Commit a10a5cb6 authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/home/bk/mysql-5.0-maint

into  polly.local:/home/kaa/src/maint/m50-maint--07OGt

parents e88121ea 1d47ef84
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#ifdef HAVE_STACKTRACE #ifdef HAVE_STACKTRACE
#include <unistd.h> #include <unistd.h>
#include <strings.h>
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end) #define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
...@@ -44,7 +45,29 @@ void safe_print_str(const char* name, const char* val, int max_len) ...@@ -44,7 +45,29 @@ void safe_print_str(const char* name, const char* val, int max_len)
} }
#ifdef TARGET_OS_LINUX #ifdef TARGET_OS_LINUX
#define SIGRETURN_FRAME_COUNT 2
#ifdef __i386__
#define SIGRETURN_FRAME_OFFSET 17
#endif
#ifdef __x86_64__
#define SIGRETURN_FRAME_OFFSET 23
#endif
static my_bool is_nptl;
/* Check if we are using NPTL or LinuxThreads on Linux */
void check_thread_lib(void)
{
char buf[5];
#ifdef _CS_GNU_LIBPTHREAD_VERSION
confstr(_CS_GNU_LIBPTHREAD_VERSION, buf, sizeof(buf));
is_nptl = !strncasecmp(buf, "NPTL", sizeof(buf));
#else
is_nptl = 0;
#endif
}
#if defined(__alpha__) && defined(__GNUC__) #if defined(__alpha__) && defined(__GNUC__)
/* /*
...@@ -90,7 +113,7 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp) ...@@ -90,7 +113,7 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp)
void print_stacktrace(gptr stack_bottom, ulong thread_stack) void print_stacktrace(gptr stack_bottom, ulong thread_stack)
{ {
uchar** fp; uchar** fp;
uint frame_count = 0; uint frame_count = 0, sigreturn_frame_count;
#if defined(__alpha__) && defined(__GNUC__) #if defined(__alpha__) && defined(__GNUC__)
uint32* pc; uint32* pc;
#endif #endif
...@@ -104,24 +127,23 @@ terribly wrong...\n"); ...@@ -104,24 +127,23 @@ terribly wrong...\n");
__asm __volatile__ ("movl %%ebp,%0" __asm __volatile__ ("movl %%ebp,%0"
:"=r"(fp) :"=r"(fp)
:"r"(fp)); :"r"(fp));
if (!fp) #endif
{ #ifdef __x86_64__
fprintf(stderr, "frame pointer (ebp) is NULL, did you compile with\n\ __asm __volatile__ ("movq %%rbp,%0"
-fomit-frame-pointer? Aborting backtrace!\n"); :"=r"(fp)
return; :"r"(fp));
}
#endif #endif
#if defined(__alpha__) && defined(__GNUC__) #if defined(__alpha__) && defined(__GNUC__)
__asm __volatile__ ("mov $30,%0" __asm __volatile__ ("mov $30,%0"
:"=r"(fp) :"=r"(fp)
:"r"(fp)); :"r"(fp));
#endif
if (!fp) if (!fp)
{ {
fprintf(stderr, "frame pointer (fp) is NULL, did you compile with\n\ fprintf(stderr, "frame pointer is NULL, did you compile with\n\
-fomit-frame-pointer? Aborting backtrace!\n"); -fomit-frame-pointer? Aborting backtrace!\n");
return; return;
} }
#endif /* __alpha__ */
if (!stack_bottom || (gptr) stack_bottom > (gptr) &fp) if (!stack_bottom || (gptr) stack_bottom > (gptr) &fp)
{ {
...@@ -151,13 +173,16 @@ terribly wrong...\n"); ...@@ -151,13 +173,16 @@ terribly wrong...\n");
:"r"(pc)); :"r"(pc));
#endif /* __alpha__ */ #endif /* __alpha__ */
/* We are 1 frame above signal frame with NPTL and 2 frames above with LT */
sigreturn_frame_count = is_nptl ? 1 : 2;
while (fp < (uchar**) stack_bottom) while (fp < (uchar**) stack_bottom)
{ {
#ifdef __i386__ #if defined(__i386__) || defined(__x86_64__)
uchar** new_fp = (uchar**)*fp; uchar** new_fp = (uchar**)*fp;
fprintf(stderr, "%p\n", frame_count == SIGRETURN_FRAME_COUNT ? fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ?
*(fp+17) : *(fp+1)); *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
#endif /* __386__ */ #endif /* defined(__386__) || defined(__x86_64__) */
#if defined(__alpha__) && defined(__GNUC__) #if defined(__alpha__) && defined(__GNUC__)
uchar** new_fp = find_prev_fp(pc, fp); uchar** new_fp = find_prev_fp(pc, fp);
......
...@@ -19,16 +19,20 @@ extern "C" { ...@@ -19,16 +19,20 @@ extern "C" {
#endif #endif
#ifdef TARGET_OS_LINUX #ifdef TARGET_OS_LINUX
#if defined(HAVE_STACKTRACE) || (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) #if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__)))
#undef HAVE_STACKTRACE #undef HAVE_STACKTRACE
#define HAVE_STACKTRACE #define HAVE_STACKTRACE
extern char* __bss_start; extern char* __bss_start;
extern char* heap_start; extern char* heap_start;
#define init_stacktrace() { heap_start = (char*) &__bss_start; } #define init_stacktrace() do { \
heap_start = (char*) &__bss_start; \
check_thread_lib(); \
} while(0);
void print_stacktrace(gptr stack_bottom, ulong thread_stack); void print_stacktrace(gptr stack_bottom, ulong thread_stack);
void safe_print_str(const char* name, const char* val, int max_len); void safe_print_str(const char* name, const char* val, int max_len);
void check_thread_lib(void);
#endif /* (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */ #endif /* (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */
#endif /* TARGET_OS_LINUX */ #endif /* TARGET_OS_LINUX */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment