Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2014-04

-dTEST_WIN32_SEH

8 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Martin Frb

Just been looking at this, and trying to thing of how to catch in the debugger.

From a very brief look at the sources (please correct me, if I got it wrong, or missed anything)

An error handler is installed to the OS, the handler is
function syswin32_i386_exception_handler(excep : PExceptionPointers) :
Longint;stdcall;

This handler returns instructions (ignore, or alternative instruction pointer) to the OS ?
If this exception is handled it goes to JumpToHandleErrorFrame ?

Then in there the "longjmp" is triggered, and presumingly goes to the "except" block ?

If so, how can the debugger get notified (before the longjmp), in a way, that it can get the address where the problem occurred?

with raise exception the debugger can set a breakpoint, because raise exception is defined [public alias ...] so the debugger can read the address by knowing the name.
But the new code does not have that....

Reply by email

Sergei Gorelkin
to Martin Frb

13.04.2014 18:20, Martin Frb пишет:

Show quoted text 12 lines
Just been looking at this, and trying to thing of how to catch in the debugger. From a very brief look at the sources (please correct me, if I got it wrong, or missed anything) An error handler is installed to the OS, the handler is function syswin32_i386_exception_handler(excep : PExceptionPointers) : Longint;stdcall; This handler returns instructions (ignore, or alternative instruction pointer) to the OS ? If this exception is handled it goes to JumpToHandleErrorFrame ? Then in there the "longjmp" is triggered, and presumingly goes to the "except" block ?

With TEST_WIN32_SEH defined, syswin32_i386_exception_hander, longjmp, JumpToHandleErrorFrame and all other stuff from system.pp is no longer used. Instead, code from seh32.inc is used. For every try..except or try..finally block, an individual handler is installed on stack, consisiting of pointer to one of __FPC_finally_handler, __FPC_except_handler, __FPC_on_handler or __FPC_except_safecall routines, and an "argument", which points to "except" block, "finally" code or an array of TFilterRec records preceded by 4-byte count, depending on the handler kind.

Show quoted text 6 lines
If so, how can the debugger get notified (before the longjmp), in a way, that it can get the address where the problem occurred? with raise exception the debugger can set a breakpoint, because raise exception is defined [public alias ...] so the debugger can read the address by knowing the name. But the new code does not have that....

The new fpc_raiseexception procedure has the same public alias as before. Each of the handler routines mentioned above also has a public alias.

Regards,
Sergei

Reply by email

Martin Frb
to Sergei Gorelkin
Sergei Gorelkin wrote 13 lines
> If so, how can the debugger get notified (before the longjmp), in a > way, that it can get the address > where the problem occurred? > > with raise exception the debugger can set a breakpoint, because raise > exception is defined [public > alias ...] so the debugger can read the address by knowing the name. > But the new code does not have that.... The new fpc_raiseexception procedure has the same public alias as before. Each of the handler routines mentioned above also has a public alias.

I am looking at http://bugs.freepascal.org/view.php?id=26013#bugnotes I still await feedback.

But it does look like it might be:

- An external dll has risen an exception
- The fpc_raiseexception was not called (as there is no mention that the IDE showed the debug dialog that is triggered by exceptions in the debugger)
- An except handle was reached (in the LCL / the application except handler, that does show the dialog for otherwise unhandled exceptions

Yes the debugger could propably gen "fpc_catches" or similar). But at that point. the instruction pointer and stack would be at the except. The position (in the dll) where the error occurred, would be lost.

Reply by email

Martin Frb
to Martin Frb

Sorry.

But the below on hold.

I just found the log at the issue. And it seems fpc_raise was called.

My fault

Martin Frb wrote 30 lines
On 13/04/2014 15:49, Sergei Gorelkin wrote: > >> If so, how can the debugger get notified (before the longjmp), in a >> way, that it can get the address >> where the problem occurred? >> >> with raise exception the debugger can set a breakpoint, because >> raise exception is defined [public >> alias ...] so the debugger can read the address by knowing the name. >> But the new code does not have that.... > > The new fpc_raiseexception procedure has the same public alias as > before. Each of the handler routines mentioned above also has a > public alias. I am looking at http://bugs.freepascal.org/view.php?id=26013#bugnotes I still await feedback. But it does look like it might be: - An external dll has risen an exception - The fpc_raiseexception was not called (as there is no mention that the IDE showed the debug dialog that is triggered by exceptions in the debugger) - An except handle was reached (in the LCL / the application except handler, that does show the dialog for otherwise unhandled exceptions Yes the debugger could propably gen "fpc_catches" or similar). But at that point. the instruction pointer and stack would be at the except. The position (in the dll) where the error occurred, would be lost.

Reply by email

Martin Frb
to Martin Frb
Martin Frb wrote 7 lines
Sorry. But the below on hold. I just found the log at the issue. And it seems fpc_raise was called. My fault

OK, I excuse it by being Sunday afternoon. reread. Definitely not called.

Show quoted text 36 lines
On 13/04/2014 15:58, Martin Frb wrote: > On 13/04/2014 15:49, Sergei Gorelkin wrote: >> >>> If so, how can the debugger get notified (before the longjmp), in a >>> way, that it can get the address >>> where the problem occurred? >>> >>> with raise exception the debugger can set a breakpoint, because >>> raise exception is defined [public >>> alias ...] so the debugger can read the address by knowing the name. >>> But the new code does not have that.... >> >> The new fpc_raiseexception procedure has the same public alias as >> before. Each of the handler routines mentioned above also has a >> public alias. > > I am looking at http://bugs.freepascal.org/view.php?id=26013#bugnotes > I still await feedback. > > But it does look like it might be: > > - An external dll has risen an exception > - The fpc_raiseexception was not called (as there is no mention that > the IDE showed the debug dialog that is triggered by exceptions in > the debugger) > - An except handle was reached (in the LCL / the application except > handler, that does show the dialog for otherwise unhandled exceptions > > Yes the debugger could propably gen "fpc_catches" or similar). But at > that point. the instruction pointer and stack would be at the except. > The position (in the dll) where the error occurred, would be lost. _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Sergei Gorelkin
to Martin Frb

13.04.2014 19:06, Martin Frb пишет:

Show quoted text 11 lines
On 13/04/2014 16:02, Martin Frb wrote: > Sorry. > > But the below on hold. > > I just found the log at the issue. And it seems fpc_raise was called. > > My fault OK, I excuse it by being Sunday afternoon. reread. Definitely not called.

Since the new exception handling is compilant with "official way to do it", I'd expect the debugger to be notified about exception by Windows directly. But I have no idea about how gdb is compatible with that. Maybe it must be configured in certain way.

Anyway, the exception information including its original address is still available when control is passed to __FPC_except_handler. This handler is called twice, first time it initiates unwinding and the second time restores the stack and jumps to code of "except" block.

Regards,
Sergei

Reply by email

Martin Frb
to Sergei Gorelkin
Sergei Gorelkin wrote 9 lines
Since the new exception handling is compilant with "official way to do it", I'd expect the debugger to be notified about exception by Windows directly. But I have no idea about how gdb is compatible with that. Maybe it must be configured in certain way. Anyway, the exception information including its original address is still available when control is passed to __FPC_except_handler. This handler is called twice, first time it initiates unwinding and the second time restores the stack and jumps to code of "except" block.

Ok, thanks for the info.

Will see what I can find.

Reply by email

Sven Barth
to Martin Frb
Martin Frb wrote 14 lines
On 13/04/2014 16:54, Sergei Gorelkin wrote: > Since the new exception handling is compilant with "official way to do > it", I'd expect the debugger to be notified about exception by Windows > directly. But I have no idea about how gdb is compatible with that. > Maybe it must be configured in certain way. > > Anyway, the exception information including its original address is > still available when control is passed to __FPC_except_handler. This > handler is called twice, first time it initiates unwinding and the > second time restores the stack and jumps to code of "except" block. Ok, thanks for the info. Will see what I can find.

On Windows a debugger will use the debugging API which (most importantly) involves WaitForDebugEvent() (see
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681423%28v=vs.85%29.aspx ) of which the returned DEBUG_EVENT structure (see http://msdn.microsoft.com/en-us/library/windows/desktop/ms679308%28v=vs.85%29.aspx ) contains among others information of the exception. The debugger is informed of such an exception twice: once before the exception handler is called and once afterwards if no handler decided to handle the exception (called first change and second/last change exception handling). GDB should handle this already as it is able to present SIGSEGVs etc. which rely on the information provided by Windows...

Regards,
Sven

Reply by email