Ich bin jetzt ein bisschen baff
Wenn ich möchte dass eine
Exception über ihren
try..except
-Block hinaus lebt gibt es zwei Routinen
AcquireExceptionObject() und
ReleaseExceptionObject().
Schaut man in den interface-Teil von System.pas:
Zitat:
{
When an
exception is thrown, the
exception object that is thrown is destroyed
automatically when the except clause which handles the
exception is exited.
There are some cases in which an application may wish to acquire the thrown
object and keep it alive after the except clause is exited. For this purpose,
we have added the AcquireExceptionObject and ReleaseExceptionObject functions.
These functions maintain a reference count on the most current
exception object,
allowing applications to legitimately obtain references. If the reference count
for an
exception that is being thrown is positive when the except clause is exited,
then the thrown object is not destroyed by the
RTL, but assumed to be in control
of the application. It is then the application's responsibility to destroy the
thrown object. If the reference count is zero, then the
RTL will destroy the
thrown object when the except clause is exited.
}
function AcquireExceptionObject: Pointer;
procedure ReleaseExceptionObject;
Schaut man in den implementation-Teil dann gibt es
ReleaseExceptionObject()
zwei mal:
Delphi-Quellcode:
procedure ReleaseExceptionObject;
begin
end;
und
Delphi-Quellcode:
procedure ReleaseExceptionObject;
asm
{$IFDEF ALIGN_STACK}
SUB ESP, 12
{$ENDIF ALIGN_STACK}
CALL CurrentException
{$IFDEF ALIGN_STACK}
ADD ESP, 12
{$ENDIF ALIGN_STACK}
OR EAX, EAX
JE @@Error
CMP [EAX].TRaisedException.RefCount, 0
JE @@Error
DEC [EAX].TRaisedException.RefCount
RET
@@Error:
{ This happens if there is no exception pending, or
if the reference count on a pending exception is
zero. }
JMP _Run0Error
end;
Aufgerufen wird natürlich ersteres. Heißt: Nichts passiert, die
Exception verbleibt auf ewig im Speicher.
Kann mir jemand den Sinn dahinter erklären? wtf...