~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/stacktrace.cc

  • Committer: Brian Aker
  • Date: 2009-10-01 22:56:26 UTC
  • mto: (1154.1.1 staging)
  • mto: This revision was merged to the branch mainline in revision 1155.
  • Revision ID: brian@gaz-20091001225626-sb1pdykpxlnkheaj
Remove Factory/make scheduler work like everything else.

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
 
 
 
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
#include "drizzled/global.h"
19
21
#include "stacktrace.h"
20
22
 
21
23
#include <signal.h>
29
31
#include <execinfo.h>
30
32
#endif
31
33
 
 
34
#include <algorithm>
 
35
 
 
36
using namespace std;
 
37
 
32
38
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
33
39
 
34
40
char *heap_start;
60
66
#define SIGRETURN_FRAME_OFFSET 23
61
67
#endif
62
68
 
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
69
 
103
70
#if BACKTRACE_DEMANGLE
104
71
static void my_demangle_symbols(char **addrs, int n)
156
123
#endif
157
124
 
158
125
 
159
 
void  print_stacktrace(uchar* stack_bottom, ulong thread_stack)
 
126
void  print_stacktrace(unsigned char* stack_bottom, size_t thread_stack)
160
127
{
161
128
#if HAVE_BACKTRACE
162
129
  backtrace_current_thread();
163
130
  return;
164
131
#endif
165
 
  uchar** fp;
166
 
  uint frame_count = 0, sigreturn_frame_count;
167
 
#if defined(__alpha__) && defined(__GNUC__)
168
 
  uint32* pc;
169
 
#endif
170
 
 
 
132
  unsigned char** fp;
 
133
  uint32_t frame_count = 0, sigreturn_frame_count;
171
134
 
172
135
#ifdef __i386__
173
136
  __asm __volatile__ ("movl %%ebp,%0"
174
 
                      :"=r"(fp)
175
 
                      :"r"(fp));
 
137
                      :"=r"(fp)
 
138
                      :"r"(fp));
176
139
#endif
177
140
#ifdef __x86_64__
178
141
  __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));
 
142
                      :"=r"(fp)
 
143
                      :"r"(fp));
186
144
#endif
187
145
  if (!fp)
188
146
  {
191
149
    return;
192
150
  }
193
151
 
194
 
  if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
 
152
  if (!stack_bottom || (unsigned char*) stack_bottom > (unsigned char*) &fp)
195
153
  {
196
 
    ulong tmp= min(0x10000,thread_stack);
 
154
    ulong tmp= min((size_t)0x10000,thread_stack);
197
155
    /* Assume that the stack starts at the previous even 65K */
198
 
    stack_bottom= (uchar*) (((ulong) &fp + tmp) &
 
156
    stack_bottom= (unsigned char*) (((ulong) &fp + tmp) &
199
157
                          ~(ulong) 0xFFFF);
200
158
    fprintf(stderr, "Cannot determine thread, fp=%p, backtrace may not be correct.\n", (void *)fp);
201
159
  }
202
 
  if (fp > (uchar**) stack_bottom ||
203
 
      fp < (uchar**) stack_bottom - thread_stack)
 
160
  if (fp > (unsigned char**) stack_bottom ||
 
161
      fp < (unsigned char**) stack_bottom - thread_stack)
204
162
  {
205
163
    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);
 
164
 fp=%p, stack_bottom=%p, thread_stack=%"PRIu64", aborting backtrace.\n",
 
165
            (void *)fp, (void *)stack_bottom, (uint64_t)thread_stack);
208
166
    return;
209
167
  }
210
168
 
211
169
  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
170
 
222
171
  /* We are 1 frame above signal frame with NPTL and 2 frames above with LT */
223
172
  sigreturn_frame_count = thd_lib_detected == THD_LIB_LT ? 2 : 1;
224
173
 
225
 
  while (fp < (uchar**) stack_bottom)
 
174
  while (fp < (unsigned char**) stack_bottom)
226
175
  {
227
176
#if defined(__i386__) || defined(__x86_64__)
228
 
    uchar** new_fp = (uchar**)*fp;
 
177
    unsigned char** new_fp = (unsigned char**)*fp;
229
178
    fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ?
230
 
            *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
 
179
            *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
231
180
#endif /* defined(__386__)  || defined(__x86_64__) */
232
181
 
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
182
    if (new_fp <= fp )
259
183
    {
260
184
      fprintf(stderr, "New value of fp=%p failed sanity check,\