~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/stacktrace.c

Put errmsg.c in sql-common since it can be built only once and used twice.
Put client.c and net_serv.c in libmysql so that we can only have one
link_sources section. 
Got rid of just about all copying and other weirdness, other than some stuff
in client and client.c/net_serv.c, which need to be reworked.

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