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

« back to all changes in this revision

Viewing changes to tests/resolve_stack_dump.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
 
/* 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
 
/* Resolve numeric stack dump produced by drizzled 3.23.30 and later
17
 
   versions into symbolic names. By Sasha Pachev <sasha@mysql.com>
18
 
 */
19
 
 
20
 
#include "config.h"
21
 
 
22
 
#include <cstdio>
23
 
#include <cerrno>
24
 
 
25
 
#include "drizzled/charset_info.h"
26
 
#include "drizzled/internal/my_sys.h"
27
 
#include "drizzled/internal/m_string.h"
28
 
#include "drizzled/my_getopt.h"
29
 
 
30
 
using namespace drizzled;
31
 
 
32
 
#define INIT_SYM_TABLE  4096
33
 
#define INC_SYM_TABLE  4096
34
 
#define MAX_SYM_SIZE   128
35
 
#define DUMP_VERSION "1.4"
36
 
#define HEX_INVALID  (unsigned char)255
37
 
 
38
 
typedef struct sym_entry
39
 
{
40
 
  char symbol[MAX_SYM_SIZE];
41
 
  unsigned char* addr;
42
 
} SYM_ENTRY;
43
 
 
44
 
 
45
 
static char* dump_fname = 0, *sym_fname = 0;
46
 
static DYNAMIC_ARRAY sym_table; /* how do you like this , static DYNAMIC ? */
47
 
static FILE* fp_dump, *fp_sym = 0, *fp_out;
48
 
 
49
 
static struct my_option my_long_options[] =
50
 
{
51
 
  {"help", 'h', "Display this help and exit.",
52
 
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
53
 
  {"version", 'V', "Output version information and exit.",
54
 
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
55
 
  {"symbols-file", 's', "Use specified symbols file.", (char**) &sym_fname,
56
 
   (char**) &sym_fname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
57
 
  {"numeric-dump-file", 'n', "Read the dump from specified file.",
58
 
   (char**) &dump_fname, (char**) &dump_fname, 0, GET_STR, REQUIRED_ARG,
59
 
   0, 0, 0, 0, 0, 0},
60
 
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
61
 
};
62
 
 
63
 
 
64
 
static void verify_sort(void);
65
 
 
66
 
static void print_version(void)
67
 
{
68
 
  printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname,DUMP_VERSION,
69
 
         VERSION,HOST_VENDOR,HOST_OS,HOST_CPU);
70
 
}
71
 
 
72
 
 
73
 
static void usage(void)
74
 
{
75
 
  print_version();
76
 
  printf("MySQL AB, by Sasha Pachev\n");
77
 
  printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
78
 
  printf("Resolve numeric stack strace dump into symbols.\n\n");
79
 
  printf("Usage: %s [OPTIONS] symbols-file [numeric-dump-file]\n",
80
 
         internal::my_progname);
81
 
  my_print_help(my_long_options);
82
 
  my_print_variables(my_long_options);
83
 
  printf("\n\
84
 
The symbols-file should include the output from:  'nm --numeric-sort drizzled'.\n\
85
 
The numeric-dump-file should contain a numeric stack trace from drizzled.\n\
86
 
If the numeric-dump-file is not given, the stack trace is read from stdin.\n");
87
 
}
88
 
 
89
 
static void die(const char* fmt, ...)
90
 
{
91
 
  va_list args;
92
 
  va_start(args, fmt);
93
 
  fprintf(stderr, "%s: ", internal::my_progname);
94
 
  vfprintf(stderr, fmt, args);
95
 
  fprintf(stderr, "\n");
96
 
  va_end(args);
97
 
  exit(1);
98
 
}
99
 
 
100
 
 
101
 
static bool get_one_option(int optid, const struct my_option *, char *)
102
 
{
103
 
  switch(optid) {
104
 
  case 'V':
105
 
    print_version();
106
 
    exit(0);
107
 
  case '?':
108
 
    usage();
109
 
    exit(0);
110
 
  }
111
 
  return 0;
112
 
}
113
 
 
114
 
 
115
 
static int parse_args(int argc, char **argv)
116
 
{
117
 
  int ho_error;
118
 
 
119
 
  if ((ho_error= handle_options(&argc, &argv, my_long_options, get_one_option)))
120
 
    exit(ho_error);
121
 
 
122
 
  /*
123
 
    The following code is to make the command compatible with the old
124
 
    version that required one to use the -n and -s options
125
 
  */
126
 
 
127
 
  if (argc == 2)
128
 
  {
129
 
    sym_fname= argv[0];
130
 
    dump_fname= argv[1];
131
 
  }
132
 
  else if (argc == 1)
133
 
  {
134
 
    if (!sym_fname)
135
 
      sym_fname = argv[0];
136
 
    else if (!dump_fname)
137
 
      dump_fname = argv[0];
138
 
    else
139
 
    {
140
 
      usage();
141
 
      exit(1);
142
 
    }
143
 
  }
144
 
  else if (argc != 0 || !sym_fname)
145
 
  {
146
 
    usage();
147
 
    exit(1);
148
 
  }
149
 
  return 0;
150
 
}
151
 
 
152
 
 
153
 
static void open_files(void)
154
 
{
155
 
  fp_out = stdout;
156
 
  fp_dump = stdin;
157
 
 
158
 
  if (dump_fname && !(fp_dump= fopen(dump_fname, "r")))
159
 
      die("Could not open %s", dump_fname);
160
 
  /* if name not given, assume stdin*/
161
 
 
162
 
  if (!sym_fname)
163
 
    die("Please run nm --numeric-sort on drizzled binary that produced stack \
164
 
trace dump and specify the path to it with -s or --symbols-file");
165
 
  if (!(fp_sym= fopen(sym_fname, "r")))
166
 
    die("Could not open %s", sym_fname);
167
 
 
168
 
}
169
 
 
170
 
static unsigned char hex_val(char c)
171
 
{
172
 
  unsigned char l;
173
 
  if (my_isdigit(&my_charset_utf8_general_ci,c))
174
 
    return c - '0';
175
 
  l = my_tolower(&my_charset_utf8_general_ci,c);
176
 
  if (l < 'a' || l > 'f')
177
 
    return HEX_INVALID;
178
 
  return (unsigned char)10 + ((unsigned char)c - (unsigned char)'a');
179
 
}
180
 
 
181
 
static unsigned long read_addr(char** buf)
182
 
{
183
 
  unsigned char c;
184
 
  char* p = *buf;
185
 
  unsigned long addr = 0;
186
 
 
187
 
  while((c = hex_val(*p++)) != HEX_INVALID)
188
 
      addr = (addr << 4) + c;
189
 
 
190
 
  *buf = p;
191
 
  return addr;
192
 
}
193
 
 
194
 
static int init_sym_entry(SYM_ENTRY* se, char* buf)
195
 
{
196
 
  char* p, *p_end;
197
 
  se->addr = (unsigned char*)read_addr(&buf);
198
 
 
199
 
  if (!se->addr)
200
 
    return -1;
201
 
  while (my_isspace(&my_charset_utf8_general_ci,*buf++))
202
 
    /* empty */;
203
 
 
204
 
  while (my_isspace(&my_charset_utf8_general_ci,*buf++))
205
 
    /* empty - skip more space */;
206
 
  --buf;
207
 
  /* now we are on the symbol */
208
 
  for (p = se->symbol, p_end = se->symbol + sizeof(se->symbol) - 1;
209
 
       *buf != '\n' && *buf && p < p_end; ++buf,++p)
210
 
    *p = *buf;
211
 
  *p = 0;
212
 
  if (!strcmp(se->symbol, "gcc2_compiled."))
213
 
    return -1;
214
 
  return 0;
215
 
}
216
 
 
217
 
static void init_sym_table(void)
218
 
{
219
 
  char buf[512];
220
 
  if (my_init_dynamic_array(&sym_table, sizeof(SYM_ENTRY), INIT_SYM_TABLE,
221
 
                            INC_SYM_TABLE))
222
 
    die("Failed in my_init_dynamic_array() -- looks like out of memory problem");
223
 
 
224
 
  while (fgets(buf, sizeof(buf), fp_sym))
225
 
  {
226
 
    SYM_ENTRY se;
227
 
    if (init_sym_entry(&se, buf))
228
 
      continue;
229
 
    if (insert_dynamic(&sym_table, (unsigned char*)&se))
230
 
      die("insert_dynamic() failed - looks like we are out of memory");
231
 
  }
232
 
 
233
 
  verify_sort();
234
 
}
235
 
 
236
 
static void clean_up(void)
237
 
{
238
 
  delete_dynamic(&sym_table);
239
 
}
240
 
 
241
 
static void verify_sort()
242
 
{
243
 
  uint32_t i;
244
 
  unsigned char* last = 0;
245
 
 
246
 
  for (i = 0; i < sym_table.elements; i++)
247
 
  {
248
 
    SYM_ENTRY se;
249
 
    get_dynamic(&sym_table, (unsigned char*)&se, i);
250
 
    if (se.addr < last)
251
 
      die("sym table does not appear to be sorted, did you forget \
252
 
--numeric-sort arg to nm? trouble addr = %p, last = %p", se.addr, last);
253
 
    last = se.addr;
254
 
  }
255
 
}
256
 
 
257
 
 
258
 
static SYM_ENTRY* resolve_addr(unsigned char* addr, SYM_ENTRY* se)
259
 
{
260
 
  uint32_t i;
261
 
  get_dynamic(&sym_table, (unsigned char*)se, 0);
262
 
  if (addr < se->addr)
263
 
    return 0;
264
 
 
265
 
  for (i = 1; i < sym_table.elements; i++)
266
 
  {
267
 
    get_dynamic(&sym_table, (unsigned char*)se, i);
268
 
    if (addr < se->addr)
269
 
    {
270
 
      get_dynamic(&sym_table, (unsigned char*)se, i - 1);
271
 
      return se;
272
 
    }
273
 
  }
274
 
 
275
 
  return se;
276
 
}
277
 
 
278
 
 
279
 
static void do_resolve(void)
280
 
{
281
 
  char buf[1024], *p;
282
 
  while (fgets(buf, sizeof(buf), fp_dump))
283
 
  {
284
 
    p = buf;
285
 
    /* skip space */
286
 
    while (my_isspace(&my_charset_utf8_general_ci,*p))
287
 
      ++p;
288
 
 
289
 
    if (*p++ == '0' && *p++ == 'x')
290
 
    {
291
 
      SYM_ENTRY se ;
292
 
      unsigned char* addr = (unsigned char*)read_addr(&p);
293
 
      if (resolve_addr(addr, &se))
294
 
        fprintf(fp_out, "%p %s + %d\n", addr, se.symbol,
295
 
                (int) (addr - se.addr));
296
 
      else
297
 
        fprintf(fp_out, "%p (?)\n", addr);
298
 
 
299
 
    }
300
 
    else
301
 
    {
302
 
      fputs(buf, fp_out);
303
 
      continue;
304
 
    }
305
 
  }
306
 
}
307
 
 
308
 
 
309
 
int main(int argc, char** argv)
310
 
{
311
 
  MY_INIT(argv[0]);
312
 
  parse_args(argc, argv);
313
 
  open_files();
314
 
  init_sym_table();
315
 
  do_resolve();
316
 
  clean_up();
317
 
  return 0;
318
 
}