Sunday, August 12, 2007

more explanation on print_stacktrace

For code segement:

while (fp < (uchar**) stack_bottom)
{
#if defined(__i386__) || defined(__x86_64__)
uchar** new_fp = (uchar**)*fp;
fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ?
*(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
#endif /* defined(__386__) || defined(__x86_64__) */

fp = new_fp;
++frame_count;
}

As suggested by Paul,
if it is a signal frame, its frame OFFSET is different.
It is defined by SIGRETURN_FRAME_OFFSET.

Since we are going to print stacktrace inside a normal function, we don't need consider this.
Here, fp (frame pointer) is EBP (Extend Base Pointer) of this caller. Its content *fp is the EBP of its caller.
That's why we can trace to the stack frame of callers by using
new_fp = *fp;

The return address of the callee is next to EBP. In this code segment,
we print *(fp + 1) to get it.

I did test on this. The printed address makes sense.

Next, the problem is how to resolve those symbols.
http://dev.mysql.com/doc/refman/5.0/en/using-stack-trace.html

In mysql, the resolving part is done by
resolve_stack_dump.c.

But I have problem to resolve my test stack with symbol info.

No comments: