~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/stacktrace.c

  • Committer: Monty Taylor
  • Date: 2008-08-04 19:37:18 UTC
  • mto: (261.2.2 codestyle)
  • mto: This revision was merged to the branch mainline in revision 262.
  • Revision ID: monty@inaugust.com-20080804193718-f0rz13uli4429ozb
Changed gettext_noop() to N_()

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 */
 
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
19
18
 
20
19
#include "stacktrace.h"
21
20
 
61
60
#define SIGRETURN_FRAME_OFFSET 23
62
61
#endif
63
62
 
 
63
#if defined(__alpha__) && defined(__GNUC__)
 
64
/*
 
65
  The only way to backtrace without a symbol table on alpha
 
66
  is to find stq fp,N(sp), and the first byte
 
67
  of the instruction opcode will give us the value of N. From this
 
68
  we can find where the old value of fp is stored
 
69
*/
 
70
 
 
71
#define MAX_INSTR_IN_FUNC  10000
 
72
 
 
73
inline uchar** find_prev_fp(uint32* pc, uchar** fp)
 
74
{
 
75
  int i;
 
76
  for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
 
77
  {
 
78
    uchar* p = (uchar*)pc;
 
79
    if (p[2] == 222 &&  p[3] == 35)
 
80
    {
 
81
      return (uchar**)((uchar*)fp - *(short int*)p);
 
82
    }
 
83
  }
 
84
  return 0;
 
85
}
 
86
 
 
87
inline uint32* find_prev_pc(uint32* pc, uchar** fp)
 
88
{
 
89
  int i;
 
90
  for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
 
91
  {
 
92
    char* p = (char*)pc;
 
93
    if (p[1] == 0 && p[2] == 94 &&  p[3] == -73)
 
94
    {
 
95
      uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp)));
 
96
      return prev_pc;
 
97
    }
 
98
  }
 
99
  return 0;
 
100
}
 
101
#endif /* defined(__alpha__) && defined(__GNUC__) */
64
102
 
65
103
#if BACKTRACE_DEMANGLE
66
104
static void my_demangle_symbols(char **addrs, int n)
118
156
#endif
119
157
 
120
158
 
121
 
void  print_stacktrace(unsigned char* stack_bottom, ulong thread_stack)
 
159
void  print_stacktrace(uchar* stack_bottom, ulong thread_stack)
122
160
{
123
161
#if HAVE_BACKTRACE
124
162
  backtrace_current_thread();
125
163
  return;
126
164
#endif
127
 
  unsigned char** fp;
128
 
  uint32_t frame_count = 0, sigreturn_frame_count;
 
165
  uchar** fp;
 
166
  uint frame_count = 0, sigreturn_frame_count;
 
167
#if defined(__alpha__) && defined(__GNUC__)
 
168
  uint32* pc;
 
169
#endif
 
170
 
129
171
 
130
172
#ifdef __i386__
131
173
  __asm __volatile__ ("movl %%ebp,%0"
132
 
                      :"=r"(fp)
133
 
                      :"r"(fp));
 
174
                      :"=r"(fp)
 
175
                      :"r"(fp));
134
176
#endif
135
177
#ifdef __x86_64__
136
178
  __asm __volatile__ ("movq %%rbp,%0"
137
 
                      :"=r"(fp)
138
 
                      :"r"(fp));
 
179
                      :"=r"(fp)
 
180
                      :"r"(fp));
 
181
#endif
 
182
#if defined(__alpha__) && defined(__GNUC__) 
 
183
  __asm __volatile__ ("mov $30,%0"
 
184
                      :"=r"(fp)
 
185
                      :"r"(fp));
139
186
#endif
140
187
  if (!fp)
141
188
  {
144
191
    return;
145
192
  }
146
193
 
147
 
  if (!stack_bottom || (unsigned char*) stack_bottom > (unsigned char*) &fp)
 
194
  if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
148
195
  {
149
 
    ulong tmp= cmin(0x10000,thread_stack);
 
196
    ulong tmp= min(0x10000,thread_stack);
150
197
    /* Assume that the stack starts at the previous even 65K */
151
 
    stack_bottom= (unsigned char*) (((ulong) &fp + tmp) &
 
198
    stack_bottom= (uchar*) (((ulong) &fp + tmp) &
152
199
                          ~(ulong) 0xFFFF);
153
200
    fprintf(stderr, "Cannot determine thread, fp=%p, backtrace may not be correct.\n", (void *)fp);
154
201
  }
155
 
  if (fp > (unsigned char**) stack_bottom ||
156
 
      fp < (unsigned char**) stack_bottom - thread_stack)
 
202
  if (fp > (uchar**) stack_bottom ||
 
203
      fp < (uchar**) stack_bottom - thread_stack)
157
204
  {
158
205
    fprintf(stderr, "Bogus stack limit or frame pointer,\
159
206
 fp=%p, stack_bottom=%p, thread_stack=%ld, aborting backtrace.\n",
162
209
  }
163
210
 
164
211
  fprintf(stderr, "Stack range sanity check OK, backtrace follows:\n");
 
212
#if defined(__alpha__) && defined(__GNUC__)
 
213
  fprintf(stderr, "Warning: Alpha stacks are difficult -\
 
214
 will be taking some wild guesses, stack trace may be incorrect or \
 
215
 terminate abruptly\n");
 
216
  /* On Alpha, we need to get pc */
 
217
  __asm __volatile__ ("bsr %0, do_next; do_next: "
 
218
                      :"=r"(pc)
 
219
                      :"r"(pc));
 
220
#endif  /* __alpha__ */
165
221
 
166
222
  /* We are 1 frame above signal frame with NPTL and 2 frames above with LT */
167
223
  sigreturn_frame_count = thd_lib_detected == THD_LIB_LT ? 2 : 1;
168
224
 
169
 
  while (fp < (unsigned char**) stack_bottom)
 
225
  while (fp < (uchar**) stack_bottom)
170
226
  {
171
227
#if defined(__i386__) || defined(__x86_64__)
172
 
    unsigned char** new_fp = (unsigned char**)*fp;
 
228
    uchar** new_fp = (uchar**)*fp;
173
229
    fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ?
174
 
            *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
 
230
            *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
175
231
#endif /* defined(__386__)  || defined(__x86_64__) */
176
232
 
 
233
#if defined(__alpha__) && defined(__GNUC__)
 
234
    uchar** new_fp = find_prev_fp(pc, fp);
 
235
    if (frame_count == sigreturn_frame_count - 1)
 
236
    {
 
237
      new_fp += 90;
 
238
    }
 
239
 
 
240
    if (fp && pc)
 
241
    {
 
242
      pc = find_prev_pc(pc, fp);
 
243
      if (pc)
 
244
        fprintf(stderr, "%p\n", pc);
 
245
      else
 
246
      {
 
247
        fprintf(stderr, "Not smart enough to deal with the rest\
 
248
 of this stack\n");
 
249
        goto end;
 
250
      }
 
251
    }
 
252
    else
 
253
    {
 
254
      fprintf(stderr, "Not smart enough to deal with the rest of this stack\n");
 
255
      goto end;
 
256
    }
 
257
#endif /* defined(__alpha__) && defined(__GNUC__) */
177
258
    if (new_fp <= fp )
178
259
    {
179
260
      fprintf(stderr, "New value of fp=%p failed sanity check,\