~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/stacktrace.cc

  • Committer: Monty Taylor
  • Date: 2008-12-24 01:49:53 UTC
  • mto: This revision was merged to the branch mainline in revision 751.
  • Revision ID: mordred@inaugust.com-20081224014953-rc9p7a162p74y889
Fixed connect.test.

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
 
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
 */
18
19
 
19
20
#include "stacktrace.h"
20
21
 
60
61
#define SIGRETURN_FRAME_OFFSET 23
61
62
#endif
62
63
 
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__) */
102
64
 
103
65
#if BACKTRACE_DEMANGLE
104
66
static void my_demangle_symbols(char **addrs, int n)
156
118
#endif
157
119
 
158
120
 
159
 
void  print_stacktrace(uchar* stack_bottom, ulong thread_stack)
 
121
void  print_stacktrace(unsigned char* stack_bottom, size_t thread_stack)
160
122
{
161
123
#if HAVE_BACKTRACE
162
124
  backtrace_current_thread();
163
125
  return;
164
126
#endif
165
 
  uchar** fp;
166
 
  uint frame_count = 0, sigreturn_frame_count;
167
 
#if defined(__alpha__) && defined(__GNUC__)
168
 
  uint32* pc;
169
 
#endif
170
 
 
 
127
  unsigned char** fp;
 
128
  uint32_t frame_count = 0, sigreturn_frame_count;
171
129
 
172
130
#ifdef __i386__
173
131
  __asm __volatile__ ("movl %%ebp,%0"
174
 
                      :"=r"(fp)
175
 
                      :"r"(fp));
 
132
                      :"=r"(fp)
 
133
                      :"r"(fp));
176
134
#endif
177
135
#ifdef __x86_64__
178
136
  __asm __volatile__ ("movq %%rbp,%0"
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));
 
137
                      :"=r"(fp)
 
138
                      :"r"(fp));
186
139
#endif
187
140
  if (!fp)
188
141
  {
191
144
    return;
192
145
  }
193
146
 
194
 
  if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
 
147
  if (!stack_bottom || (unsigned char*) stack_bottom > (unsigned char*) &fp)
195
148
  {
196
 
    ulong tmp= min(0x10000,thread_stack);
 
149
    ulong tmp= cmin(0x10000,thread_stack);
197
150
    /* Assume that the stack starts at the previous even 65K */
198
 
    stack_bottom= (uchar*) (((ulong) &fp + tmp) &
 
151
    stack_bottom= (unsigned char*) (((ulong) &fp + tmp) &
199
152
                          ~(ulong) 0xFFFF);
200
153
    fprintf(stderr, "Cannot determine thread, fp=%p, backtrace may not be correct.\n", (void *)fp);
201
154
  }
202
 
  if (fp > (uchar**) stack_bottom ||
203
 
      fp < (uchar**) stack_bottom - thread_stack)
 
155
  if (fp > (unsigned char**) stack_bottom ||
 
156
      fp < (unsigned char**) stack_bottom - thread_stack)
204
157
  {
205
158
    fprintf(stderr, "Bogus stack limit or frame pointer,\
206
 
 fp=%p, stack_bottom=%p, thread_stack=%ld, aborting backtrace.\n",
207
 
            (void *)fp, (void *)stack_bottom, thread_stack);
 
159
 fp=%p, stack_bottom=%p, thread_stack=%"PRIu64", aborting backtrace.\n",
 
160
            (void *)fp, (void *)stack_bottom, (uint64_t)thread_stack);
208
161
    return;
209
162
  }
210
163
 
211
164
  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__ */
221
165
 
222
166
  /* We are 1 frame above signal frame with NPTL and 2 frames above with LT */
223
167
  sigreturn_frame_count = thd_lib_detected == THD_LIB_LT ? 2 : 1;
224
168
 
225
 
  while (fp < (uchar**) stack_bottom)
 
169
  while (fp < (unsigned char**) stack_bottom)
226
170
  {
227
171
#if defined(__i386__) || defined(__x86_64__)
228
 
    uchar** new_fp = (uchar**)*fp;
 
172
    unsigned char** new_fp = (unsigned char**)*fp;
229
173
    fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ?
230
 
            *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
 
174
            *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
231
175
#endif /* defined(__386__)  || defined(__x86_64__) */
232
176
 
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__) */
258
177
    if (new_fp <= fp )
259
178
    {
260
179
      fprintf(stderr, "New value of fp=%p failed sanity check,\