~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to drizzled/stacktrace.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-10-02 14:17:48 UTC
  • mfrom: (1.1.1 upstream)
  • mto: (2.1.17 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20101002141748-m6vbfbfjhrw1153e
Tags: 2010.09.1802-1
* New upstream release.
* Removed pid-file argument hack.
* Updated GPL-2 address to be new address.
* Directly copy in drizzledump.1 since debian doesn't have sphinx 1.0 yet.
* Link to jquery from libjs-jquery. Add it as a depend.
* Add drizzled.8 symlink to the install files.

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
 
 
20
 
#include "config.h"
21
 
#include "drizzled/stacktrace.h"
22
 
#include <cstddef>
23
 
 
24
 
#include <signal.h>
25
 
#include "drizzled/internal/my_pthread.h"
26
 
#include "drizzled/internal/m_string.h"
27
 
#ifdef HAVE_STACKTRACE
28
 
#include <unistd.h>
29
 
#include <strings.h>
30
 
 
31
 
#if HAVE_EXECINFO_H
32
 
#include <execinfo.h>
33
 
#endif
34
 
 
35
 
#include <cstring>
36
 
#include <cstdio>
37
 
#include <algorithm>
38
 
 
39
 
#include "drizzled/definitions.h"
40
 
 
41
 
using namespace std;
42
 
 
43
 
namespace drizzled
44
 
{
45
 
 
46
 
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
47
 
 
48
 
char *heap_start;
49
 
 
50
 
void safe_print_str(const char* name, const char* val, int max_len)
51
 
{
52
 
  char *heap_end= (char*) sbrk(0);
53
 
  fprintf(stderr, "%s at %p ", name, val);
54
 
 
55
 
  if (!PTR_SANE(val))
56
 
  {
57
 
    fprintf(stderr, " is invalid pointer\n");
58
 
    return;
59
 
  }
60
 
 
61
 
  fprintf(stderr, "= ");
62
 
  for (; max_len && PTR_SANE(val) && *val; --max_len)
63
 
    fputc(*val++, stderr);
64
 
  fputc('\n', stderr);
65
 
}
66
 
 
67
 
#ifdef TARGET_OS_LINUX
68
 
 
69
 
#ifdef __i386__
70
 
#define SIGRETURN_FRAME_OFFSET 17
71
 
#endif
72
 
 
73
 
#ifdef __x86_64__
74
 
#define SIGRETURN_FRAME_OFFSET 23
75
 
#endif
76
 
 
77
 
 
78
 
#if BACKTRACE_DEMANGLE
79
 
static void my_demangle_symbols(char **addrs, int n)
80
 
{
81
 
  int status, i;
82
 
  char *begin, *end, *demangled;
83
 
 
84
 
  for (i= 0; i < n; i++)
85
 
  {
86
 
    demangled= NULL;
87
 
    begin= strchr(addrs[i], '(');
88
 
    end= begin ? strchr(begin, '+') : NULL;
89
 
 
90
 
    if (begin && end)
91
 
    {
92
 
      *begin++= *end++= '\0';
93
 
      demangled= my_demangle(begin, &status);
94
 
      if (!demangled || status)
95
 
      {
96
 
        demangled= NULL;
97
 
        begin[-1]= '(';
98
 
        end[-1]= '+';
99
 
      }
100
 
    }
101
 
 
102
 
    if (demangled)
103
 
      fprintf(stderr, "%s(%s+%s\n", addrs[i], demangled, end);
104
 
    else
105
 
      fprintf(stderr, "%s\n", addrs[i]);
106
 
  }
107
 
}
108
 
#endif
109
 
 
110
 
 
111
 
#if HAVE_BACKTRACE
112
 
static void backtrace_current_thread(void)
113
 
{
114
 
  void *addrs[128];
115
 
  char **strings= NULL;
116
 
  int n = backtrace(addrs, array_elements(addrs));
117
 
#if BACKTRACE_DEMANGLE
118
 
  if ((strings= backtrace_symbols(addrs, n)))
119
 
  {
120
 
    my_demangle_symbols(strings, n);
121
 
    free(strings);
122
 
  }
123
 
#endif
124
 
#if HAVE_BACKTRACE_SYMBOLS_FD
125
 
  if (!strings)
126
 
  {
127
 
    backtrace_symbols_fd(addrs, n, fileno(stderr));
128
 
  }
129
 
#endif
130
 
}
131
 
#endif
132
 
 
133
 
 
134
 
void  print_stacktrace(unsigned char* stack_bottom, size_t thread_stack)
135
 
{
136
 
#if HAVE_BACKTRACE
137
 
  backtrace_current_thread();
138
 
  return;
139
 
#endif
140
 
  unsigned char** fp;
141
 
  uint32_t frame_count = 0, sigreturn_frame_count;
142
 
 
143
 
#ifdef __i386__
144
 
  __asm __volatile__ ("movl %%ebp,%0"
145
 
                      :"=r"(fp)
146
 
                      :"r"(fp));
147
 
#endif
148
 
#ifdef __x86_64__
149
 
  __asm __volatile__ ("movq %%rbp,%0"
150
 
                      :"=r"(fp)
151
 
                      :"r"(fp));
152
 
#endif
153
 
  if (!fp)
154
 
  {
155
 
    fprintf(stderr, "frame pointer is NULL, did you compile with\n\
156
 
-fomit-frame-pointer? Aborting backtrace!\n");
157
 
    return;
158
 
  }
159
 
 
160
 
  if (!stack_bottom || (unsigned char*) stack_bottom > (unsigned char*) &fp)
161
 
  {
162
 
    ulong tmp= min((size_t)0x10000,thread_stack);
163
 
    /* Assume that the stack starts at the previous even 65K */
164
 
    stack_bottom= (unsigned char*) (((ulong) &fp + tmp) &
165
 
                          ~(ulong) 0xFFFF);
166
 
    fprintf(stderr, "Cannot determine thread, fp=%p, backtrace may not be correct.\n", (void *)fp);
167
 
  }
168
 
  if (fp > (unsigned char**) stack_bottom ||
169
 
      fp < (unsigned char**) stack_bottom - thread_stack)
170
 
  {
171
 
    fprintf(stderr, "Bogus stack limit or frame pointer,\
172
 
 fp=%p, stack_bottom=%p, thread_stack=%"PRIu64", aborting backtrace.\n",
173
 
            (void *)fp, (void *)stack_bottom, (uint64_t)thread_stack);
174
 
    return;
175
 
  }
176
 
 
177
 
  fprintf(stderr, "Stack range sanity check OK, backtrace follows:\n");
178
 
 
179
 
  /* We are 1 frame above signal frame with NPTL and 2 frames above with LT */
180
 
  sigreturn_frame_count = internal::thd_lib_detected == THD_LIB_LT ? 2 : 1;
181
 
 
182
 
  while (fp < (unsigned char**) stack_bottom)
183
 
  {
184
 
#if defined(__i386__) || defined(__x86_64__)
185
 
    unsigned char** new_fp = (unsigned char**)*fp;
186
 
    fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ?
187
 
            *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
188
 
#endif /* defined(__386__)  || defined(__x86_64__) */
189
 
 
190
 
    if (new_fp <= fp )
191
 
    {
192
 
      fprintf(stderr, "New value of fp=%p failed sanity check,\
193
 
 terminating stack trace!\n", (void *)new_fp);
194
 
      goto end;
195
 
    }
196
 
    fp = new_fp;
197
 
    ++frame_count;
198
 
  }
199
 
 
200
 
  fprintf(stderr, "Stack trace seems successful - bottom reached\n");
201
 
 
202
 
end:
203
 
  fprintf(stderr,
204
 
          "Please read http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
205
 
          "and follow instructions on how to resolve the stack trace.\n"
206
 
          "Resolved stack trace is much more helpful in diagnosing the\n"
207
 
          "problem, so please do resolve it\n");
208
 
}
209
 
#endif /* TARGET_OS_LINUX */
210
 
 
211
 
} /* namespace drizzled */
212
 
 
213
 
#endif /* HAVE_STACKTRACE */
214
 
 
215
 
/* Produce a core for the thread */
216
 
 
217
 
namespace drizzled
218
 
{
219
 
 
220
 
void write_core(int sig)
221
 
{
222
 
  signal(sig, SIG_DFL);
223
 
#ifdef HAVE_gcov
224
 
  /*
225
 
    For GCOV build, crashing will prevent the writing of code coverage
226
 
    information from this process, causing gcov output to be incomplete.
227
 
    So we force the writing of coverage information here before terminating.
228
 
  */
229
 
  extern void __gcov_flush(void);
230
 
  __gcov_flush();
231
 
#endif
232
 
  pthread_kill(pthread_self(), sig);
233
 
#if defined(P_MYID) && !defined(SCO)
234
 
  /* On Solaris, the above kill is not enough */
235
 
  sigsend(P_PID,P_MYID,sig);
236
 
#endif
237
 
}
238
 
 
239
 
} /* namespace drizzled */