[fpc-devel] clarification about StackBottom and StackLength in threaded programs and/or shared libraries

Seth Grover sethdgrover at gmail.com
Mon May 21 16:40:58 CEST 2012


Hi guys,

I've got a system which consists of a main program and a few shared
object libraries running under Linux. In a debugging routine I have, I
walk the stack and use BackTraceStrFunc to output the backtrace. The
code I use to do this I adopted from heaptrc.pp, which looks like
this:

===================================
  { retrieve backtrace info }
  bp:=get_caller_frame(get_frame);

  { valid bp? }
  if (bp>=StackBottom) and (bp<(StackBottom + StackLength)) then
    for i:=1 to tracesize do
     begin
       pp^.calls[i]:=get_caller_addr(bp);
       oldbp:=bp;
       bp:=get_caller_frame(bp);
       if (bp<oldbp) or (bp>(StackBottom + StackLength)) then
         break;
     end;
===================================

However, I've found that in my .so, when the backtrace function runs
in the context of a new thread I've started up, sometimes I end up
breaking out of the for loop too soon, because of the
(bp>(StackBottom + StackLength)) check. If I "pad" the comparand on
the right hand side the equation (ie., testing bp>(StackBottom +
StackLength + 12 kilobytes or so)), then I get the full backtrace (and
the loop breaks out because (bp<oldbp) rather than the second
comparision, which is how I think it should generally be.

How it appears to me is that in thread.inc's InitThread, when
StackBottom is calculated it takes esp and subtracks StackLength. The
thing is, at the time this is run, we're really not the first thing in
the backtrace, so StackBottom is not actually precisely the stack
bottom.

I read a few threads on the mailing list archives ("Stack checking in
dynamic libraries" and "Heap, Stack, HeapTrc and threads") which seem
to touch on this issue, but I wanted clarification on one thing:
Jonas, in this message
(http://lists.freepascal.org/lists/fpc-pascal/2009-November/023040.html)
you said "And keep in mind that it's only an approximation" when
referring to doing stack checking in dynamic libraries. Is the
calculation of StackBottom the approximation you're referring to? If
that is the case, is what I'm doing (checking bp>(StackBottom +
StackLength + someArbitraryPadICameUpWith)) the right thing to do, or
is there a better way to know when to stop walking the stack? Also,
doesn't this mean that since heaptrc does the same thing, it's going
to not necessarily get the entire backtrace?

Thanks,

-SG

--
This email is fiction. Any resemblance to actual events
or persons living or dead is purely coincidental.

Seth Grover



More information about the fpc-devel mailing list