This question already has answers here:
Debugging Access Violation errors?
(4 answers)
Closed 5 years ago.
I face the following error when I try to debug. I am just newbie with Delphi, please guide how to correct this error.
First chance exception at $73B1A9F2. Exception class EAccessViolation with message 'Access violation at address 005D3653 in module 'Project1.exe'. Read of address 000003AC'. Process Project1.exe (34780)
When break this source code is shown:
if fsCreating in FFormState then
if Value then
Include(FFormState, fsVisible) else
Exclude(FFormState, fsVisible)
You are calling a method on an invalid reference. For instance something like
Obj.DoSomething;
where Obj is not valid. Because the attempted read address is 000003AC, close to zero, almost certainly the reference is nil.
Track back up your call stack until you find the call with the nil reference.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I try to handle exception but a warning occurs. "No calls to throwing functions occur within 'try' expression"
do{
var folderID = getFolder()?
}catch{
}
The warning clearly states that getFolder() does not throw. To get rid of the warning remove the do - catch block
let folderID = getFolder()
Note:
In Swift you cannot catch arbitrary exceptions like in Objective-C.
A do - catch block catches only Errors thrown by methods marked with the throws keyword.
A customer has reported a Range check error on a machine embedded in a factory running an older Delphi 7 application. We have not (yet) been able to reproduce the error. They sent us a photo:
The software can operate correctly for days on end, and we currently only have vague clues as to how this might be generated or reliably reproduced. My understanding is that this error occurs in two general scenarios:
(1) An array or string has been accessed outside its bounds
(2) The variable is assigned a value out-of-range for its type
An example of (1) is accessing array[50] if there are only 40 elements. An example of (2) is assigning the value "300" to an an unsigned BYTE.
This comes from SO question 1 and SO question 2. I've got lots of careful checking to do to try and identify the offending lines!
My question is how this error is generated in the first place. Both the above-mentioned questions refer to the {$R+} compiler directive. In Project Options > Compiler > Runtime errors, Range checking is off, and nowhere in the code is {$R+} (nor {$R-}) used. How does this error occur? Shouldn't the application crash or generate a different exception?
I'll answer the question:
Can a Range check error be generated without being specifically enabled?
However, the problem you're experiencing at your client's site will need further investigation for you to resolve it. Typically this kind of thing requires a combination of:
Exception logging: tools that produce a stack trace when exceptions occur to determine exactly what code was being called.
Tracing: logging messages that provide clues to the state of the application to assist in your investigation.
Yes, range check error can be generated without being specifically enabled.
Range check errors can be raised at any time with raise ERangeError.Create(...);. If called, this will raise the error regardless of the state of the range-check setting.
Note code can if so written, also honour the setting as follows:
{$IFOPT R+}
raise ERangeError.Create(...);
{$ENDIF}
But the point is that as soon as raise <SomeClass>.Create(...) is called, an exception will be raised. If you search the Delphi source code, you'll find a few places where ERangeError is raised. Loki's answer provides an example.
The second important thing to note is that the {$R} setting is not global. If you compile a project with this setting turn off, but link in DCUs which were compiled with the option turned on: then the setting will still be on for those DCUs.
Furthermore, the setting can be locally changed for specific sections of code. E.g.
{$IFOPT R-} {$R+} {$DEFINE TOGGLE_ROFF} {$ENDIF}
{ Ensure range-checking is on, but turn off again if it was already off.}
procedure MustUseRangeChecking(...);
begin
...
end;
{$IFDEF TOGGLE_ROFF} {$R-} {$ENDIF}
NOTE: You can use {$IFOPT} in your own code to check the state of the range-checking directive.
yes it's can be raise without having Range check error specifically enabled
exemple just look the TStream.SetSize function :
procedure TStream.SetSize(const NewSize: Int64);
begin
if (NewSize < Low(Integer)) or (NewSize > High(Integer)) then
raise ERangeError.CreateRes(#SRangeError);
SetSize(LongInt(NewSize));
end;
so it's will raise the exception with or without Range check error enabled. you have in delphi several function like this.
I wrote my routines for using CDO.Message. It's working long time ago.
But now, in some site they installed a certificate and then the priorly working version is making errors with all calls.
I used simple variants to hold the CDO.Message COM object.
When I used Send method(?) it returns a HResult.
But it's interesting, because the HResult is unusable for get the error code, because the Send is seems to be a real method which makes Exception on problems.
So the result code is -1 if I set to this value before.
I tried to get the last error code with GetLastError. But this is 0.
I can catch the Exception, but it contains only the error message what is:
"The transport failed to connect to the server"
The VB codes can get the error code which could provide extra information about the problem (or not).
Do you know about a technic to get the error code value from Delphi XE3?
It would be better if we had some source code at hand. Specifically the Delphi declaration of the COM interface.
My guess is that the method is declared as safecall. What this means is that the compiler understands that the method is actually stdcall returning HRESULT, and re-writes the parameters to match. If the true COM method returns an HRESULT other than S_OK then the compiler writes code to check for that and convert the error into an exception.
The exception that is raised will be EOleSysError and that has the property ErrorCode which contains the HRESULT that you are looking for.
So, you need to:
Add an exception handler to catch EOleSysError.
Read the ErrorCode property of the EOleSysError exception instance that you catch.
This is all a little bit round the houses. If you'd prefer to avoid exception handling, then you can always re-write the COM interface declaration to be a true stdcall method returning an HRESULT.
I have a piece of code written below and I'm stuck with it. I've done it before with a different compiler and right now I'm moving into the Visual C++. Every time this function tries to get called this error pops out:
Unhandled exception at 0x0076e124 in SeaQuest.exe: 0xC0000005:
Access violation writing location 0xccccccd0.
Besides, I've written the D3DXGetImageInfoFromFileA's syntax correctly.
class Texture
{
private:
D3DXIMAGE_INFO m_ImageInfo;
public:
bool GetImageInfo(char* filename);
};
bool Texture::GetImageInfo(char* filename)
{
if((D3DXGetImageInfoFromFileA(filename, &m_ImageInfo)) != D3D_OK)
return false;
}
I've also tracked the DirectX debug output but it doesn't show anything.
UPDATE
Now I've defined a D3DXIMAGE_INFO local variable in the implementation of GetImageInfo and have it addressed instead of m_ImageInfo. It works!. I don't know what is the problem with my private member that the Access violation writing rises for that. Hope someone guide me.
ANSWER
I was using Texture class as a pointer variable in another class and the reason was to not instantiating the pointer to a new Texture class or I could use a non pointer variable then copy class into it but losing the benefits of referencing. 0xC0000005 is near to 0 so it means there is a NULL pointer that it's trying to get addressed. I'll keep it in mind hope you will too!
Background
We have a problem that sometimes the grid in Devexpress raise exception
"Raised EConvertError: Cannot assign a nil to a TFont".
But to trace the real cause of this we have changed Font in cxEdit to be a public property instead with a get and set method. Here I want to log the callstack.
My question
Normally JCL is used to log callstacks when exceptions appear. But how can I log the callstack without using raise exception and show a dialog for the user about this ?
I have found the lines:
var
GlobalStackList: TJclGlobalStackList;
in JclDebug but I fail to use it. If someone have a example how to get the callstack I would be happy.
Regards Roland Bengtsson
This answer shows how to do it with JCL by calling JclCreateStackList.