~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/stacktrace.cc

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000 MySQL AB
2
 
 
3
 
   This program is free software; you can redistribute it and/or modify
4
 
   it under the terms of the GNU General Public License as published by
5
 
   the Free Software Foundation; version 2 of the License.
6
 
 
7
 
   This program is distributed in the hope that it will be useful,
8
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 
   GNU General Public License for more details.
11
 
 
12
 
   You should have received a copy of the GNU General Public License
13
 
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
 
 
16
 
/* Workaround for Bug#32082: VOID redefinition on Win results in compile errors*/
17
 
#define DONT_DEFINE_VOID 1
18
 
 
19
 
#include <my_global.h>
 
1
/* - mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
20
20
#include "stacktrace.h"
21
21
 
22
22
#include <signal.h>
23
 
#include <my_pthread.h>
24
 
#include <m_string.h>
 
23
#include <mysys/my_pthread.h>
 
24
#include <mystrings/m_string.h>
25
25
#ifdef HAVE_STACKTRACE
26
26
#include <unistd.h>
27
27
#include <strings.h>
61
61
#define SIGRETURN_FRAME_OFFSET 23
62
62
#endif
63
63
 
64
 
#if defined(__alpha__) && defined(__GNUC__)
65
 
/*
66
 
  The only way to backtrace without a symbol table on alpha
67
 
  is to find stq fp,N(sp), and the first byte
68
 
  of the instruction opcode will give us the value of N. From this
69
 
  we can find where the old value of fp is stored
70
 
*/
71
 
 
72
 
#define MAX_INSTR_IN_FUNC  10000
73
 
 
74
 
inline uchar** find_prev_fp(uint32* pc, uchar** fp)
75
 
{
76
 
  int i;
77
 
  for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
78
 
  {
79
 
    uchar* p = (uchar*)pc;
80
 
    if (p[2] == 222 &&  p[3] == 35)
81
 
    {
82
 
      return (uchar**)((uchar*)fp - *(short int*)p);
83
 
    }
84
 
  }
85
 
  return 0;
86
 
}
87
 
 
88
 
inline uint32* find_prev_pc(uint32* pc, uchar** fp)
89
 
{
90
 
  int i;
91
 
  for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
92
 
  {
93
 
    char* p = (char*)pc;
94
 
    if (p[1] == 0 && p[2] == 94 &&  p[3] == -73)
95
 
    {
96
 
      uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp)));
97
 
      return prev_pc;
98
 
    }
99
 
  }
100
 
  return 0;
101
 
}
102
 
#endif /* defined(__alpha__) && defined(__GNUC__) */
103
64
 
104
65
#if BACKTRACE_DEMANGLE
105
66
static void my_demangle_symbols(char **addrs, int n)
157
118
#endif
158
119
 
159
120
 
160
 
void  print_stacktrace(uchar* stack_bottom, ulong thread_stack)
 
121
void  print_stacktrace(unsigned char* stack_bottom, ulong thread_stack)
161
122
{
162
123
#if HAVE_BACKTRACE
163
124
  backtrace_current_thread();
164
125
  return;
165
126
#endif
166
 
  uchar** fp;
167
 
  uint frame_count = 0, sigreturn_frame_count;
168
 
#if defined(__alpha__) && defined(__GNUC__)
169
 
  uint32* pc;
170
 
#endif
171
 
 
 
127
  unsigned char** fp;
 
128
  uint32_t frame_count = 0, sigreturn_frame_count;
172
129
 
173
130
#ifdef __i386__
174
131
  __asm __volatile__ ("movl %%ebp,%0"
175
 
                      :"=r"(fp)
176
 
                      :"r"(fp));
 
132
                      :"=r"(fp)
 
133
                      :"r"(fp));
177
134
#endif
178
135
#ifdef __x86_64__
179
136
  __asm __volatile__ ("movq %%rbp,%0"
180
 
                      :"=r"(fp)
181
 
                      :"r"(fp));
182
 
#endif
183
 
#if defined(__alpha__) && defined(__GNUC__) 
184
 
  __asm __volatile__ ("mov $30,%0"
185
 
                      :"=r"(fp)
186
 
                      :"r"(fp));
 
137
                      :"=r"(fp)
 
138
                      :"r"(fp));
187
139
#endif
188
140
  if (!fp)
189
141
  {
192
144
    return;
193
145
  }
194
146
 
195
 
  if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
 
147
  if (!stack_bottom || (unsigned char*) stack_bottom > (unsigned char*) &fp)
196
148
  {
197
 
    ulong tmp= min(0x10000,thread_stack);
 
149
    ulong tmp= cmin(0x10000,thread_stack);
198
150
    /* Assume that the stack starts at the previous even 65K */
199
 
    stack_bottom= (uchar*) (((ulong) &fp + tmp) &
 
151
    stack_bottom= (unsigned char*) (((ulong) &fp + tmp) &
200
152
                          ~(ulong) 0xFFFF);
201
 
    fprintf(stderr, "Cannot determine thread, fp=%p, backtrace may not be correct.\n", fp);
 
153
    fprintf(stderr, "Cannot determine thread, fp=%p, backtrace may not be correct.\n", (void *)fp);
202
154
  }
203
 
  if (fp > (uchar**) stack_bottom ||
204
 
      fp < (uchar**) stack_bottom - thread_stack)
 
155
  if (fp > (unsigned char**) stack_bottom ||
 
156
      fp < (unsigned char**) stack_bottom - thread_stack)
205
157
  {
206
158
    fprintf(stderr, "Bogus stack limit or frame pointer,\
207
159
 fp=%p, stack_bottom=%p, thread_stack=%ld, aborting backtrace.\n",
208
 
            fp, stack_bottom, thread_stack);
 
160
            (void *)fp, (void *)stack_bottom, thread_stack);
209
161
    return;
210
162
  }
211
163
 
212
164
  fprintf(stderr, "Stack range sanity check OK, backtrace follows:\n");
213
 
#if defined(__alpha__) && defined(__GNUC__)
214
 
  fprintf(stderr, "Warning: Alpha stacks are difficult -\
215
 
 will be taking some wild guesses, stack trace may be incorrect or \
216
 
 terminate abruptly\n");
217
 
  /* On Alpha, we need to get pc */
218
 
  __asm __volatile__ ("bsr %0, do_next; do_next: "
219
 
                      :"=r"(pc)
220
 
                      :"r"(pc));
221
 
#endif  /* __alpha__ */
222
165
 
223
166
  /* We are 1 frame above signal frame with NPTL and 2 frames above with LT */
224
167
  sigreturn_frame_count = thd_lib_detected == THD_LIB_LT ? 2 : 1;
225
168
 
226
 
  while (fp < (uchar**) stack_bottom)
 
169
  while (fp < (unsigned char**) stack_bottom)
227
170
  {
228
171
#if defined(__i386__) || defined(__x86_64__)
229
 
    uchar** new_fp = (uchar**)*fp;
 
172
    unsigned char** new_fp = (unsigned char**)*fp;
230
173
    fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ?
231
 
            *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
 
174
            *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
232
175
#endif /* defined(__386__)  || defined(__x86_64__) */
233
176
 
234
 
#if defined(__alpha__) && defined(__GNUC__)
235
 
    uchar** new_fp = find_prev_fp(pc, fp);
236
 
    if (frame_count == sigreturn_frame_count - 1)
237
 
    {
238
 
      new_fp += 90;
239
 
    }
240
 
 
241
 
    if (fp && pc)
242
 
    {
243
 
      pc = find_prev_pc(pc, fp);
244
 
      if (pc)
245
 
        fprintf(stderr, "%p\n", pc);
246
 
      else
247
 
      {
248
 
        fprintf(stderr, "Not smart enough to deal with the rest\
249
 
 of this stack\n");
250
 
        goto end;
251
 
      }
252
 
    }
253
 
    else
254
 
    {
255
 
      fprintf(stderr, "Not smart enough to deal with the rest of this stack\n");
256
 
      goto end;
257
 
    }
258
 
#endif /* defined(__alpha__) && defined(__GNUC__) */
259
177
    if (new_fp <= fp )
260
178
    {
261
179
      fprintf(stderr, "New value of fp=%p failed sanity check,\
262
 
 terminating stack trace!\n", new_fp);
 
180
 terminating stack trace!\n", (void *)new_fp);
263
181
      goto end;
264
182
    }
265
183
    fp = new_fp;