~danielpvolpato/mysql-server/parallel-mysqldump

« back to all changes in this revision

Viewing changes to mysys/stacktrace.c

Merge from main 5.1 to 5.1-build

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
#define DONT_DEFINE_VOID 1
18
18
 
19
19
#include <my_global.h>
20
 
#include "stacktrace.h"
 
20
#include <my_stacktrace.h>
21
21
 
22
22
#ifndef __WIN__
23
23
#include <signal.h>
33
33
 
34
34
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
35
35
 
36
 
char *heap_start;
37
 
 
38
 
void safe_print_str(const char* name, const char* val, int max_len)
 
36
static char *heap_start;
 
37
 
 
38
#ifdef HAVE_BSS_START
 
39
extern char *__bss_start;
 
40
#endif
 
41
 
 
42
void my_init_stacktrace()
 
43
{
 
44
#ifdef HAVE_BSS_START
 
45
  heap_start = (char*) &__bss_start;
 
46
#endif
 
47
}
 
48
 
 
49
void my_safe_print_str(const char* name, const char* val, int max_len)
39
50
{
40
51
  char *heap_end= (char*) sbrk(0);
41
52
  fprintf(stderr, "%s at %p ", name, val);
42
53
 
43
54
  if (!PTR_SANE(val))
44
55
  {
45
 
    fprintf(stderr, " is invalid pointer\n");
 
56
    fprintf(stderr, "is an invalid pointer\n");
46
57
    return;
47
58
  }
48
59
 
52
63
  fputc('\n', stderr);
53
64
}
54
65
 
55
 
#ifdef TARGET_OS_LINUX
56
 
 
57
 
#ifdef __i386__
58
 
#define SIGRETURN_FRAME_OFFSET 17
59
 
#endif
60
 
 
61
 
#ifdef __x86_64__
62
 
#define SIGRETURN_FRAME_OFFSET 23
63
 
#endif
64
 
 
65
 
#if defined(__alpha__) && defined(__GNUC__)
66
 
/*
67
 
  The only way to backtrace without a symbol table on alpha
68
 
  is to find stq fp,N(sp), and the first byte
69
 
  of the instruction opcode will give us the value of N. From this
70
 
  we can find where the old value of fp is stored
71
 
*/
72
 
 
73
 
#define MAX_INSTR_IN_FUNC  10000
74
 
 
75
 
inline uchar** find_prev_fp(uint32* pc, uchar** fp)
76
 
{
77
 
  int i;
78
 
  for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
79
 
  {
80
 
    uchar* p = (uchar*)pc;
81
 
    if (p[2] == 222 &&  p[3] == 35)
82
 
    {
83
 
      return (uchar**)((uchar*)fp - *(short int*)p);
84
 
    }
85
 
  }
86
 
  return 0;
87
 
}
88
 
 
89
 
inline uint32* find_prev_pc(uint32* pc, uchar** fp)
90
 
{
91
 
  int i;
92
 
  for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
93
 
  {
94
 
    char* p = (char*)pc;
95
 
    if (p[1] == 0 && p[2] == 94 &&  p[3] == -73)
96
 
    {
97
 
      uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp)));
98
 
      return prev_pc;
99
 
    }
100
 
  }
101
 
  return 0;
102
 
}
103
 
#endif /* defined(__alpha__) && defined(__GNUC__) */
 
66
#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
104
67
 
105
68
#if BACKTRACE_DEMANGLE
 
69
 
 
70
char __attribute__ ((weak)) *my_demangle(const char *mangled_name, int *status)
 
71
{
 
72
  return NULL;
 
73
}
 
74
 
106
75
static void my_demangle_symbols(char **addrs, int n)
107
76
{
108
77
  int status, i;
132
101
      fprintf(stderr, "%s\n", addrs[i]);
133
102
  }
134
103
}
135
 
#endif
136
 
 
137
 
 
138
 
#if HAVE_BACKTRACE
139
 
static void backtrace_current_thread(void)
 
104
 
 
105
#endif /* BACKTRACE_DEMANGLE */
 
106
 
 
107
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
140
108
{
141
109
  void *addrs[128];
142
110
  char **strings= NULL;
143
111
  int n = backtrace(addrs, array_elements(addrs));
 
112
  fprintf(stderr, "stack_bottom = %p thread_stack 0x%lx\n",
 
113
          stack_bottom, thread_stack);
144
114
#if BACKTRACE_DEMANGLE
145
115
  if ((strings= backtrace_symbols(addrs, n)))
146
116
  {
155
125
  }
156
126
#endif
157
127
}
158
 
#endif
159
 
 
160
 
 
161
 
void  print_stacktrace(uchar* stack_bottom, ulong thread_stack)
162
 
{
163
 
#if HAVE_BACKTRACE
164
 
  backtrace_current_thread();
165
 
  return;
166
 
#endif
 
128
 
 
129
#elif defined(TARGET_OS_LINUX)
 
130
 
 
131
#ifdef __i386__
 
132
#define SIGRETURN_FRAME_OFFSET 17
 
133
#endif
 
134
 
 
135
#ifdef __x86_64__
 
136
#define SIGRETURN_FRAME_OFFSET 23
 
137
#endif
 
138
 
 
139
#if defined(__alpha__) && defined(__GNUC__)
 
140
/*
 
141
  The only way to backtrace without a symbol table on alpha
 
142
  is to find stq fp,N(sp), and the first byte
 
143
  of the instruction opcode will give us the value of N. From this
 
144
  we can find where the old value of fp is stored
 
145
*/
 
146
 
 
147
#define MAX_INSTR_IN_FUNC  10000
 
148
 
 
149
inline uchar** find_prev_fp(uint32* pc, uchar** fp)
 
150
{
 
151
  int i;
 
152
  for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
 
153
  {
 
154
    uchar* p = (uchar*)pc;
 
155
    if (p[2] == 222 &&  p[3] == 35)
 
156
    {
 
157
      return (uchar**)((uchar*)fp - *(short int*)p);
 
158
    }
 
159
  }
 
160
  return 0;
 
161
}
 
162
 
 
163
inline uint32* find_prev_pc(uint32* pc, uchar** fp)
 
164
{
 
165
  int i;
 
166
  for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
 
167
  {
 
168
    char* p = (char*)pc;
 
169
    if (p[1] == 0 && p[2] == 94 &&  p[3] == -73)
 
170
    {
 
171
      uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp)));
 
172
      return prev_pc;
 
173
    }
 
174
  }
 
175
  return 0;
 
176
}
 
177
#endif /* defined(__alpha__) && defined(__GNUC__) */
 
178
 
 
179
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
 
180
{
167
181
  uchar** fp;
168
182
  uint frame_count = 0, sigreturn_frame_count;
169
183
#if defined(__alpha__) && defined(__GNUC__)
281
295
#endif /* HAVE_STACKTRACE */
282
296
 
283
297
/* Produce a core for the thread */
284
 
 
285
 
#ifdef NOT_USED /* HAVE_LINUXTHREADS */
286
 
void write_core(int sig)
287
 
{
288
 
  signal(sig, SIG_DFL);
289
 
  if (fork() != 0) exit(1);                     /* Abort main program */
290
 
  /* Core will be written at exit */
291
 
}
292
 
#else
293
 
void write_core(int sig)
 
298
void my_write_core(int sig)
294
299
{
295
300
  signal(sig, SIG_DFL);
296
301
#ifdef HAVE_gcov
308
313
  sigsend(P_PID,P_MYID,sig);
309
314
#endif
310
315
}
311
 
#endif
 
316
 
312
317
#else /* __WIN__*/
313
318
 
314
319
#include <dbghelp.h>
356
361
#define MODULE64_SIZE_WINXP 576
357
362
#define STACKWALK_MAX_FRAMES 64
358
363
 
 
364
void my_init_stacktrace()
 
365
{
 
366
}
 
367
 
359
368
/*
360
369
  Dynamically load dbghelp functions
361
370
*/
395
404
  return rc;
396
405
}
397
406
 
398
 
void set_exception_pointers(EXCEPTION_POINTERS *ep)
 
407
void my_set_exception_pointers(EXCEPTION_POINTERS *ep)
399
408
{
400
409
  exception_ptrs = ep;
401
410
}
405
414
#define SYMOPT_NO_PROMPTS 0
406
415
#endif
407
416
 
408
 
void print_stacktrace(uchar* unused1, ulong unused2)
 
417
void my_print_stacktrace(uchar* unused1, ulong unused2)
409
418
{
410
419
  HANDLE  hProcess= GetCurrentProcess();
411
420
  HANDLE  hThread= GetCurrentThread();
513
522
  file name is constructed from executable name plus
514
523
  ".dmp" extension
515
524
*/
516
 
void write_core(int unused)
 
525
void my_write_core(int unused)
517
526
{
518
527
  char path[MAX_PATH];
519
528
  char dump_fname[MAX_PATH]= "core.dmp";
560
569
}
561
570
 
562
571
 
563
 
void safe_print_str(const char *name, const char *val, int len)
 
572
void my_safe_print_str(const char *name, const char *val, int len)
564
573
{
565
574
  fprintf(stderr,"%s at %p", name, val);
566
575
  __try