Sign in Join

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

Mailing lists / lazarus / 2009-04

function StabBackTraceStr(addr:Pointer):shortstring; - problem with subsequent back traces

3 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

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

Bogusław Brandys

There is a problem with this function. To avoid recursion there is a hack there to point BackTraceStrFunc to system implementation (which only shows addresses in hex).Long back trace which mostly ends with incorrect frame address as I suppose (OpenStabs is returning false for nil address) - thus function pointer is not returned back to lineinfo stabs processing method and next back trace contains only addresses .

This problem is minor if program crashes with exception and stack trace but in other cases , like in bigger program (any Lazarus ones) , ONLY first back trace has useful information (source,line number) attached to it. That eliminates any useful logging like multilog for example. And nobody really is able to know correct stack frames length before calling any of such functions to obtain back trace (that would resolve problem).

How we could fix it ? Is this recursion still a subject here ?

I have one idea, probably not perfect.

How about  a function to initialize
  BackTraceStrFunc  : TBackTraceStrFunc;

The only way now is to set :

BackTraceStrFunc := @SysBackTraceStr; (displays only hex of addresses)

Something generic is needed, able to set to StabBackTraceStr if lineinfo unit (option -gl) is used and only to SysBackTraceStr in other case. It might be used also to set to user defined function.

That way in any such functions in lcl
(DumpExceptionBackTrace,GetStackTrace) or external package (like multilog), we could initialize BackTraceStrFunc to point again to correct function before obtaining stack trace.

Boguslaw Brandys

Reply by email

Sergei Gorelkin
to Bogusław Brandys

Bogus?aw Brandys ?????:

Show quoted text 7 lines
There is a problem with this function. To avoid recursion there is a hack there to point BackTraceStrFunc to system implementation (which only shows addresses in hex).Long back trace which mostly ends with incorrect frame address as I suppose (OpenStabs is returning false for nil address) - thus function pointer is not returned back to lineinfo stabs processing method and next back trace contains only addresses .

Right you are. However, many backtraces *start* with an invalid frame: e.g. when you call a virtual method of an object that is already destroyed, you'll likely end up at a random address.

Show quoted text 11 lines
This problem is minor if program crashes with exception and stack trace but in other cases , like in bigger program (any Lazarus ones) , ONLY first back trace has useful information (source,line number) attached to it. That eliminates any useful logging like multilog for example. And nobody really is able to know correct stack frames length before calling any of such functions to obtain back trace (that would resolve problem). How we could fix it ? Is this recursion still a subject here ?

I fixed one of the causes recently (see exeinfo.pp, rev.12802), but that wasn't enough. In general, code of lineinfo, lnfodwrf and exeinfo has to be checked very carefully to make sure it would not crash at any circumstances. Including possibly unknown/corrupted state of the RTL in case when backtrace is called due to a crash.

Show quoted text 20 lines
I have one idea, probably not perfect. How about a function to initialize BackTraceStrFunc : TBackTraceStrFunc; The only way now is to set : BackTraceStrFunc := @SysBackTraceStr; (displays only hex of addresses) Something generic is needed, able to set to StabBackTraceStr if lineinfo unit (option -gl) is used and only to SysBackTraceStr in other case. It might be used also to set to user defined function. That way in any such functions in lcl (DumpExceptionBackTrace,GetStackTrace) or external package (like multilog), we could initialize BackTraceStrFunc to point again to correct function before obtaining stack trace.

For me, it looks simpler and better to restore BackTraceStrFunc unconditionally at the end of StabsBackTraceFunc/DwarfBackTraceFunc. Or even better, have it set to stub only for calling GetLineInfo.

Regards,
Sergei

Reply by email

Bogusław Brandys
to Sergei Gorelkin

Sergei Gorelkin pisze:

Show quoted text 11 lines
Bogus?aw Brandys ?????: > There is a problem with this function. To avoid recursion there is a > hack there to point BackTraceStrFunc to system implementation (which > only shows addresses in hex).Long back trace which mostly ends with > incorrect frame address as I suppose (OpenStabs is returning false for > nil address) - thus function pointer is not returned back to lineinfo > stabs processing method and next back trace contains only addresses . > Right you are. However, many backtraces *start* with an invalid frame: e.g. when you call a virtual method of an object that is already destroyed, you'll likely end up at a random address.

I attached my proposition of patch here :
http://bugs.freepascal.org/view.php?id=13518

and here (only windows) for external debug files (.dbg) :

http://bugs.freepascal.org/view.php?id=13499

Do you have testcases for testing such invalid frames like in example above and for testing recursion ?

Would be great if someone looked at proposed solution and checked under unix,win64 and other supported systems.

Show quoted text 43 lines
> This problem is minor if program crashes with exception and stack trace > but in other cases , like in bigger program (any Lazarus ones) , ONLY > first back trace has useful information (source,line number) attached to it. > That eliminates any useful logging like multilog for example. > And nobody really is able to know correct stack frames length before > calling any of such functions to obtain back trace (that would resolve > problem). > > How we could fix it ? Is this recursion still a subject here ? > I fixed one of the causes recently (see exeinfo.pp, rev.12802), but that wasn't enough. In general, code of lineinfo, lnfodwrf and exeinfo has to be checked very carefully to make sure it would not crash at any circumstances. Including possibly unknown/corrupted state of the RTL in case when backtrace is called due to a crash. > I have one idea, probably not perfect. > > > How about a function to initialize > BackTraceStrFunc : TBackTraceStrFunc; > > > The only way now is to set : > > BackTraceStrFunc := @SysBackTraceStr; (displays only hex of addresses) > > Something generic is needed, able to set to StabBackTraceStr if lineinfo > unit (option -gl) is used and only to SysBackTraceStr in other case. > It might be used also to set to user defined function. > > That way in any such functions in lcl > (DumpExceptionBackTrace,GetStackTrace) or external package (like > multilog), we could initialize BackTraceStrFunc to point again to > correct function before obtaining stack trace. > For me, it looks simpler and better to restore BackTraceStrFunc unconditionally at the end of StabsBackTraceFunc/DwarfBackTraceFunc. Or even better, have it set to stub only for calling GetLineInfo. Regards, Sergei

That's what I did among other changes.

Regards
Bogus?aw

Reply by email