Sunday, July 22, 2007

print_stacktrace in mysql source code

Mysql AB provides print_stacktrace function inside stacktrace.c.
void print_stacktrace(gptr stack_bottom, ulong thread_stack)

mysqld.cc calls it when segfault happens:
print_stacktrace(thd ? (gptr) thd->thread_stack : (gptr) 0,
thread_stack);

Its basic idea of print_stacktrace is

1. first get current frame pointer fp

take __i386__ for example, fp is
Extended Base Pointer (ebp)

#ifdef __i386__
__asm __volatile__ ("movl %%ebp,%0"
:"=r"(fp)
:"r"(fp));
#endif


+---------+------------------+
| EBP - 4 | local variables |
| EBP | callees EBP |
| EBP + 4 | ret-addr |
| EBP + 8 | parameters |
+---------+------------------+

2. transverse the stack to print the call stack info
/* We are 1 frame above signal frame with NPTL and 2 frames above with LT */
sigreturn_frame_count = thd_lib_detected == THD_LIB_LT ? 2 : 1;

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;
}

I don't quite understand how to get sigreturn_frame_count in the 2nd step.


The 2nd parameter seems the stack size, and the first one seems the stack bottom.
I am trying to call this function inside my program. But I passed wrong parameters.
I will further investigate how to pass correct parameters.

No comments: