Re: Try Finally...
From: L D Blake (not_at_any.adr)
Date: 10/26/04
- Next message: http://tinyurl.com/ii35: "Re: spam the child molester matt parker off the web"
- Previous message: Rudy Velthuis: "Re: Try Finally..."
- In reply to: Maarten Wiltink: "Re: Try Finally..."
- Next in thread: Bjørge Sæther: "Re: Try Finally..."
- Reply: Bjørge Sæther: "Re: Try Finally..."
- Reply:(deleted message) Maarten Wiltink: "Re: Try Finally..."
- Reply:(deleted message) Rudy Velthuis: "Re: Try Finally..."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Tue, 26 Oct 2004 06:51:18 -0400
On Tue, 26 Oct 2004 10:45:12 +0200, "Maarten Wiltink"
<maarten@kittensandcats.net> wrote:
>[...]
>> See that's just it... Finally doesn't handle the actual exception and
>> thus it *must not* unwind the stack.
>
>I'm not sure about this. Exceptions "climb out" through the call chain,
>executing finally and except clauses along the way, and execution
>finally continues at the point where the exception is handled. That
>suggests that unwinding the stack is the right thing to do along the
>way.
But that's not how it works...
You appear to be picturing a list, someplace, with 10 exceptions waiting to be
handled... and there is no such list. It doesn't exist. It cannot be made.
What does happen is that on the stack a series of "guard frames" are created.
They are a linked list. Each contains a pointer to the previous frame and the
address of a handler. The last one on the list is pointed to by FS:0 which is
a cpu register.
Ok... so along comes an exception... Windows (not delphi) interprets the
exception and assigns it a code. It then creates an Exception Record with a
lot of information about the exception... it's address, code, cpu registers,
etc. Once the Exception Record is created, the address of the handler is
looked up from the guard frame at FS:0. Now windows (not delphi) calls this
handler with pointers to the guard frame and exception record and a flag to
indicate if the exception is continuable or not. It is up to the exception
handler (finally in Delphi) what happens next ... it can return a 0 for
"handled", a 1 for "continue search" or 2 for "terminate process".
These handler subroutines are created by the TRY keyword. The code generated
is exactly the same for try/except as for try/finally. That's all TRY does is
create a guard frame.
The handlers themselves are linked in by Except or Finally. And consist of
pre-set bundles of code (the stuff I'm working on) that determine what happens
to the exception... Except deals with it, Finally passes it on.
If we manually unwind the stack we are trashing the guard frames that are
needed to make Except and Finally work... we run the risk of actually sending
an exception into the wrong block of code, or a different process altogether.
Lastly, since this all happens in real time, there will actually only be one
active exception at a time, most likely to be handled by the last guard frame
in the list... all the handler has to do to "unwind" itself is remove it's
guard frame from the stack.
>If I've understood correctly, the Windows mechanism takes a two-stage
>approach, with the first stage only following the stack and the second
>one unwinding it. Why it's done this way, I don't understand.
The entire process is called "Unwinding"... basically all it does is walk up
the list of guard frames asking various subroutines to deal with an exception.
Once it finds one that deals with it (i.e. either returns 0 or doesn't return
at all) the process is over.
The reason for the double pass method is that on the first pass the handler
can execute whatever corrective action is needed and on the second pass an
"unwind" flag is set. If all goes well it can remove it's guard frame from
the stack on the second pass.
Windows never removes guard frames from the stack. The handlers are
responsible for removing their own guard frames.
>Delphi
>appears to have collated these two stages into a single one, bypassing
>Windows' code. I don't consider this bad in itself; it's just different.
Try/except and try/finally were not the original intent of SEH. In fact the
original plan was to create a sort of interrupt handler where the guard frame
would send control to a subroutine that would correct the fault and then carry
on execution from the address of the exception itself. Basically the idea was
to fix problems at the CPU Register level.
Try/except and try/finally use SEH guard frames differently than Windows does.
They are using the handler address to vector execution into the Except or
Finally blocks, rather than continuing from the next CPU instruction after a
fault.
>The final effect is the same: all the right code gets executed, and
>execution finally continues after the handler that handles the exception.
Ummm... no not really. It's a less than perfect answer... sometimes the
instructions in the TRY block that don't get executed do matter...
The original windows plan would have seen the rest of those instructions
executed. The try/Except try/finally concept does not.
>More likely Borland's guys wanted something Windows couldn't offer them:
>exception _objects_.
Ask... Why exactly do they need this?
What is the point of linking in 26k of code from 3 different units when in
fact the same result can be obtained by processing the dword exception code
provided by windows?
>That you don't care for this feature doesn't mean it's irrelevant to
>other people.
And what I do to my RTL units affects anyone else, exactly how???
-----
Laura
http://www.start.ca/users/ldblake
- Next message: http://tinyurl.com/ii35: "Re: spam the child molester matt parker off the web"
- Previous message: Rudy Velthuis: "Re: Try Finally..."
- In reply to: Maarten Wiltink: "Re: Try Finally..."
- Next in thread: Bjørge Sæther: "Re: Try Finally..."
- Reply: Bjørge Sæther: "Re: Try Finally..."
- Reply:(deleted message) Maarten Wiltink: "Re: Try Finally..."
- Reply:(deleted message) Rudy Velthuis: "Re: Try Finally..."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|