This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: why no stacktrace?


> I am not a compiler specialist, but isn't the return address on the stack
> anyway?

Typically, yes. The problem is that you don't know where it is. Consider

void foo(){get_backtrace();}

void bar(int i)
{
  char c[i]; // C99 VLA
  i = i*2;
  foo();
}

In this case, location of bar's return address depends on the value of
the parameter i, which even gets changed. Inside bar, the code
generated for bar knows how to remove the array from the stack. Nobody
else does.

Even in the "normal" case, location of the return address on the stack
depends on the number of local variables.

Of course, the DWARF debugging specification describes all that, so
that unwinding is possible. It is just not portable - you need DWARF
information.

> I don't see how you would have access to the line number where foo()
> was called, unless you add TraceCall() before each call which would
> be nearly impossible in case of overloaded operators.

That's true - you couldn't get the caller location.

> well, this is how I do it (with limited portability):
> 
> class stack { // simplified layout of call stack
>   long           fudge[PREV_OFF]; // PREV_OFF is platform specific
>   stack*         prev;       // pointer to stack frame of caller
>   unsigned long  ret;        // return address


That apparently requires that there is a frame pointer on a fixed
position relative to the return address. That is not universally true,
eg. with -fomit-frame-pointer on i386.

> This works for Solaris gcc and CC and for Linux gcc; overhead is zero.

It requires that frames are linked in some way. If that is already the
case, there is no overhead. However, if it is not the case, you'd have
to add that, adding overhead. Also, it terribly crashes if you get
inside a stack frame which does not follow the convention. gdb usually
gets confused if it sees such a frame.

You can look at glibc's backtrace.c implementations:

sysdeps/generic/backtrace.c
sysdeps/i386/backtrace.c
sysdeps/powerpc/backtrace.c

I don't know for which architectures the generic implementation works.
It uses the same layout that you assume, and find the first frame with
__builtin_frame_address. It even considers that the stack grows in
different directions, but it probably couldn't handle the case that
the order of the return address and the frame pointer might get
switched, too.

For example, on alpha, gcc's __builtin_return_address won't return
anything if the argument is >0. It just seems not be possible to
implement that function reliably.

Regards,
Martin

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]