I am puzzled by the way Delphi handles exceptions.
I have done this (quite) simple program :
program ExceptionAV;
uses
SysUtils;
begin
raise Exception.Create('This must be an error.');
// One might have say "Abort;" as well
end.
On my Win2K Pro SP4 workstation, as one might expect, I get the well known
message "unknown software exception (0x0eedfade)". The exception is properly
intercepted, and the message displayed. I have the same behavior on a XP SP1
computer.
*But* on my 2 Win2K Server SP4, I get another exception : in the DrWatson
log, I get the following
Application exception occurred:
App: (pid=544)
When: 11/17/2003 @ 23:22:18.093
Exception number: c0000025
And the crash location occures in the function: RtlTraceDatabaseEnumerate,
on the line :
FAULT ->77fb1db8 e9ce33feff jmp ZwDeviceIoControlFile+0xb7
(77f9518b)
That is, while processing the exception, the NT kernel "lost is marbles"
and throw another exception. (The famous "non continuable exception",
0xC0000025)
As I understand SEH, to handle proper handling of the exception, the
compiler have to cooperate (by applying a proper setup) with the kernel.
I wonder who is at fault there.
If I compile the same program with Delphi 4 and run it on my various
plateform test, every time the program properly intercept the exception and
shows the error message.
I guess that there is some troubles with exception in Delphi 6.
My concerns are not purely academic.
We have some production batch processing made in Delphi. They run on a
Windows 2000 Advanced Server (SP3) computer. Most of them (if not all) use
the BDE and an Oracle database.
Without the ability to correctly handle the exceptions, we have trouble to
predict what job really get done by our batches.
The computers used in my testing are all patched with the lasted (to
date...) Microsoft "hotfix". (The production servers are still in SP3 with
some crucial patch such as MS03-026, -039).
The test servers have little software installed. Not Delphi, nor the BDE.
The program is build without runtime package. The only thing specific to
those server is that they are Domain controllers. (But the productions
servers are not.)
Any suggestion/thought on the subject is welcomed (and eagerly awaited
for...)
--Richard.
where do you call that ExceptionAV function?
I would just guess that the c0000025 exception is a totally different
exception being raised by something else before the ExceptionAV function
is even reached. Maybe something wrong with the database setup?
--
www.madshi.net
quality low level Delphi components
extended exception handling
API hooking, DLL injection
undocumented functionality
I would say: you <g>. A program is supposed to handle its own exceptions,
so your program is not correctly written.
--
Peter Below (TeamB)
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be
I am illustrating a point : the default behavior for trapping exception is
different according the environment.
I tried running this program on NT, on my Win2K workstation or on a XP SP1
computer.
Each time, it yells at me, saying something such as :
Exception EAbort in the module Project1.exe at 00007C91.
Operation aborted.
That's what I except. The delphi runtime should be able to deal with it.
But on several Win2K Server I tried, I get a C0000025 exception instead and
a DrWatson.
In fact, what I am really investigating another problem : since 2 weeks,
some batch process written with Delphi 6 will die with a C0000025 exception
instead of returning the right error code. The error code should be returned
by the program trapping the error condition.
(There is exception handling code in the programs.)
Sometime it even looks like the exception C0000025 will be fired during the
program finalization, after the last program line. That is, the program
seems to have badly aborted whereas it has completed its job.
It is a nighmare to figure out what is really going on.
What I really want to find is why the exception handling will not properly
perform on some computers. Why the exception processing will cause another
exception to be raised thus causing the C0000025 (non continuable exception)
error.
--Richard.
This was the name for my program illustrating the point.
It really do the following
program test;
uses sysutils;
begin
Abort
end.
> I would just guess that the c0000025 exception is a totally different
> exception being raised by something else before the ExceptionAV function
> is even reached. Maybe something wrong with the database setup?
My program will simply raise a silent exception without trying to catch it
just to exhibit the default behavior of the Delphi 6 runtime under several
environment (OS version, computers...)
And I don't get the same behavior.
See my answer to Peter on my motivation for this silly test.
Thanks,
--Richard.
The VCL exception handling actually uses the OS support for unwinding the
stack etc.. So this looks like a bug in that particular Windows version to me.
Or the chain of exception handlers on the stack got corrupted somehow.
Build your test program with debug DCUs and trace through the exception
handling code. Perhaps you can figure out what the problem is. If you don't
have a Delphi installation on that server machine but can get a network
connection to it from your development machine install the remote debugger
service on the server machine and build your app with remote debug info
(project options linker page).
If so, why the exception handling is working correctly is the same program
is compiled with Delphi 4 ?
> Or the chain of exception handlers on the stack got corrupted somehow.
I just reinstalled a Win2K Server SP4 (from "Select" disk).
The first thing I did after completing the installation was the run the
dreadful program :
begin abort; end.
And I got the C0000025 exception.
(If compiled using D4, I get the message "Exception EAbort in the module
...")
> Build your test program with debug DCUs and trace through the exception
> handling code. Perhaps you can figure out what the problem is. If you
don't
> have a Delphi installation on that server machine but can get a network
> connection to it from your development machine install the remote debugger
> service on the server machine and build your app with remote debug info
> (project options linker page).
I don't have sufficient detail on how the exception handling is setup to
trace it.
I am a little lost in the stack walking...
--Richard.
I don't know how D4 did this stuff.
> > Build your test program with debug DCUs and trace through the exception
> > handling code. Perhaps you can figure out what the problem is. If you
> don't
> > have a Delphi installation on that server machine but can get a network
> > connection to it from your development machine install the remote debugger
> > service on the server machine and build your app with remote debug info
> > (project options linker page).
>
> I don't have sufficient detail on how the exception handling is setup to
> trace it.
> I am a little lost in the stack walking...
I'm afraid i cannot help you with the details here, sorry.
program Project1;
uses Windows, SysUtils;
procedure CheckAbort(ExceptObject: TObject; ExceptAddr: Pointer);
begin
if (ExceptObject <> nil) and (ExceptObject is EAbort) then
ExitProcess(0);
end;
begin
ExceptProc := @CheckAbort;
Abort;
end.
--Richard.
"madshi (Mathias Rauen)" wrote :