I faced very strange behavior: after some point in the code exceptions stop to work. This is my test function:
procedure vmDbg_TestExceptionsHandling(AMarker: string);
var
i: integer;
begin
i := UVmDll.DebugPoint(9002, PChar(AMarker)); // #define dbgpnt_HeapCheck 9002
if i <> 1 then
ToAppLogger(ll_ERROR, format(' %s->UVmDll.DebugPoint(9002)->heap integrity failure!', [AMarker]));
//DBG:
try
// when Borland RTL space is somehow broken, it will crash here!
raise Exception.Create('test exceptions#1 /' + AMarker);
except
on e: Exception do begin
ToAppLogger(ll_ERROR, format(' %s->UVmDll.DebugPoint(99)->%s', [AMarker, ExcErrMsg(e)]));
end;
end;
//DBG:
try
// inside ScriptVN.dll there is a special handling for point# 99 - it will throw a C++ exception
UVmDll.DebugPoint(99, PChar(AMarker));
except
on e: Exception do begin
ToAppLogger(ll_ERROR, format(' %s->UVmDll.DebugPoint(99)->%s', [AMarker, ExcErrMsg(e)]));
end;
end;
//DBG:
try
// sometimes it may crash here...
raise Exception.Create('test exceptions#2 /' + AMarker);
except
on e: Exception do begin
ToAppLogger(ll_ERROR, format(' %s->UVmDll.DebugPoint(99)->%s', [AMarker, ExcErrMsg(e)]));
end;
end;
end;
And then use it in my code like this:
procedure vmDll_Jira790TestCase;
var
n: integer;
ixf: cpp_IInterface;
rw, rwx, rwd: TRow;
begin
isJira790Catch := true;
vmDbg_TestExceptionsHandling('Jira790TestCase.0'); //<-- here it works fine
rwd := TRow.CreateDummy;
vmDbg_TestExceptionsHandling('Jira790TestCase.1'); //<-- here it works fine
rw := TRow.Create(true);
vmDbg_TestExceptionsHandling('Jira790TestCase.2'); //<-- here it works fine
ixf := UVmDll.DataTree__GetContainerInterface(rw.Engine);
rwx := TRow.CreateForIxf(ixf); // <-- it crashes on leaving this constructor
vmDbg_TestExceptionsHandling('Jira790TestCase.3'); // <-- sometimes it crashes here
end;
The idea of this test function: just to raise exceptions as usual and confirm if try ... except
works as expected.
So, the problem is: try ... except
statements suddenly stop to work as expected. Instead of catching exceptions the application crashes with a message like this (when running in debugger):
--------------------------- Debugger Fault Notification --------------------------- Project D:\testApp\testApp.exe faulted with message: 'application-defined exception (code 0x0eedfade) at 0x756456e8'. Process Stopped. Use Step or Run to continue. --------------------------- OK ---------------------------
When running normally (without debugger) it writes to Windows Events log messages like these:
Faulting application name: testApp.exe, version: 0.0.0.0, time stamp: 0x2a425e19 Faulting module name: KERNELBASE.dll, version: 6.3.9600.19724, time stamp: 0x5ec50c3e Exception code: 0x0eedfade Fault offset: 0x000156e8 Faulting process id: 0xb98 Faulting application start time: 0x01d89d1805403f55 Faulting application path: D:\testApp\testApp.exe Faulting module path: C:\Windows\SYSTEM32\KERNELBASE.dll Report Id: 43b9a57a-090b-11ed-8140-000c299851c5 Faulting package full name: Faulting package-relative application ID:
- I stepped through ASM code, validated a lot of stuff, confirmed that VMT of created objects are valid. But now I'm a bit stuck, because I'm not sure how exception handling is implemented in Borland Delphi 5 (or 7). Tried to use Google but it seems that nothing interesting on particular low-level details on how exceptions are implemented in Borland Delphi exists.
Could you please advise documentation materials on this topic? How can I manually track and check correctness of exception handling structures for Borland Delphi? What structures are created for exception handling, where exactly, and so on. I guess it should be somewhere on the stack, but I need a bit more details on it.
This is a single threaded simple UI application. Just one form with a button. No additional threads in the background. Also I have not found any problems with heap memory integrity, so that is not broken RAM.
Important: crashing only happens on Windows Server. So,
- it works fine on Windows 7 and 10 (but pls note - on some editions of Windows 10 it also begin to crash, ex: on Win 10 2004 but on next edition - it no crash anymore)
- but it crashes on Windows Server 2012, 2016, 2019.
I tried to configure this app to run in different "compatibility modes" but that does not have any effect - it still crashes.