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.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment