~drizzle-trunk/drizzle/development

1 by brian
clean slate
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
77.1.39 by Monty Taylor
More mysql->drizzle renaming.
16
/* Resolve numeric stack dump produced by drizzled 3.23.30 and later
1 by brian
clean slate
17
   versions into symbolic names. By Sasha Pachev <sasha@mysql.com>
18
 */
19
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
20
#include "config.h"
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
21
22
#include <cstdio>
23
#include <cerrno>
24
1241.9.61 by Monty Taylor
No more mystrings in drizzled/
25
#include "drizzled/charset_info.h"
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
26
#include "drizzled/internal/my_sys.h"
27
#include "drizzled/internal/m_string.h"
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
28
#include "drizzled/my_getopt.h"
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
29
30
using namespace drizzled;
1 by brian
clean slate
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"
481 by Brian Aker
Remove all of uchar.
36
#define HEX_INVALID  (unsigned char)255
1 by brian
clean slate
37
38
typedef struct sym_entry
39
{
40
  char symbol[MAX_SYM_SIZE];
481 by Brian Aker
Remove all of uchar.
41
  unsigned char* addr;
1 by brian
clean slate
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 ? */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
47
static FILE* fp_dump, *fp_sym = 0, *fp_out;
1 by brian
clean slate
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},
77.1.78 by Monty Taylor
One last bunch of warnings edits.
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},
1 by brian
clean slate
57
  {"numeric-dump-file", 'n', "Read the dump from specified file.",
77.1.78 by Monty Taylor
One last bunch of warnings edits.
58
   (char**) &dump_fname, (char**) &dump_fname, 0, GET_STR, REQUIRED_ARG,
1 by brian
clean slate
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
77.1.44 by Monty Taylor
Fixed warnings in test
64
static void verify_sort(void);
1 by brian
clean slate
65
66
static void print_version(void)
67
{
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
68
  printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname,DUMP_VERSION,
1081.1.1 by Monty Taylor
Whole boat-load of build fixes.
69
	 VERSION,HOST_VENDOR,HOST_OS,HOST_CPU);
1 by brian
clean slate
70
}
71
72
77.1.44 by Monty Taylor
Fixed warnings in test
73
static void usage(void)
1 by brian
clean slate
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",
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
80
	 internal::my_progname);
1 by brian
clean slate
81
  my_print_help(my_long_options);
82
  my_print_variables(my_long_options);
83
  printf("\n\
77.1.39 by Monty Taylor
More mysql->drizzle renaming.
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\
1 by brian
clean slate
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);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
93
  fprintf(stderr, "%s: ", internal::my_progname);
1 by brian
clean slate
94
  vfprintf(stderr, fmt, args);
95
  fprintf(stderr, "\n");
96
  va_end(args);
97
  exit(1);
98
}
99
100
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
101
static bool get_one_option(int optid, const struct my_option *, char *)
1 by brian
clean slate
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
146 by Brian Aker
my_bool cleanup.
119
  if ((ho_error= handle_options(&argc, &argv, my_long_options, get_one_option)))
1 by brian
clean slate
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
77.1.44 by Monty Taylor
Fixed warnings in test
153
static void open_files(void)
1 by brian
clean slate
154
{
155
  fp_out = stdout;
156
  fp_dump = stdin;
157
910.1.3 by Brian Aker
Remove my_fopen() and key_map.cc file (thanks to Jay's lcov)
158
  if (dump_fname && !(fp_dump= fopen(dump_fname, "r")))
1 by brian
clean slate
159
      die("Could not open %s", dump_fname);
160
  /* if name not given, assume stdin*/
161
162
  if (!sym_fname)
77.1.39 by Monty Taylor
More mysql->drizzle renaming.
163
    die("Please run nm --numeric-sort on drizzled binary that produced stack \
1 by brian
clean slate
164
trace dump and specify the path to it with -s or --symbols-file");
910.1.3 by Brian Aker
Remove my_fopen() and key_map.cc file (thanks to Jay's lcov)
165
  if (!(fp_sym= fopen(sym_fname, "r")))
1 by brian
clean slate
166
    die("Could not open %s", sym_fname);
167
168
}
169
481 by Brian Aker
Remove all of uchar.
170
static unsigned char hex_val(char c)
1 by brian
clean slate
171
{
481 by Brian Aker
Remove all of uchar.
172
  unsigned char l;
383.1.10 by Brian Aker
More cleanup/test fixup around utf8
173
  if (my_isdigit(&my_charset_utf8_general_ci,c))
1 by brian
clean slate
174
    return c - '0';
383.1.10 by Brian Aker
More cleanup/test fixup around utf8
175
  l = my_tolower(&my_charset_utf8_general_ci,c);
1 by brian
clean slate
176
  if (l < 'a' || l > 'f')
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
177
    return HEX_INVALID;
481 by Brian Aker
Remove all of uchar.
178
  return (unsigned char)10 + ((unsigned char)c - (unsigned char)'a');
1 by brian
clean slate
179
}
180
299 by brian
Reverted ulong back in resolve stack. Reverted MAX (issue for OSX, possibly
181
static unsigned long read_addr(char** buf)
1 by brian
clean slate
182
{
481 by Brian Aker
Remove all of uchar.
183
  unsigned char c;
1 by brian
clean slate
184
  char* p = *buf;
299 by brian
Reverted ulong back in resolve stack. Reverted MAX (issue for OSX, possibly
185
  unsigned long addr = 0;
1 by brian
clean slate
186
187
  while((c = hex_val(*p++)) != HEX_INVALID)
188
      addr = (addr << 4) + c;
189
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
190
  *buf = p;
1 by brian
clean slate
191
  return addr;
192
}
193
194
static int init_sym_entry(SYM_ENTRY* se, char* buf)
195
{
196
  char* p, *p_end;
481 by Brian Aker
Remove all of uchar.
197
  se->addr = (unsigned char*)read_addr(&buf);
1 by brian
clean slate
198
199
  if (!se->addr)
200
    return -1;
383.1.10 by Brian Aker
More cleanup/test fixup around utf8
201
  while (my_isspace(&my_charset_utf8_general_ci,*buf++))
1 by brian
clean slate
202
    /* empty */;
203
383.1.10 by Brian Aker
More cleanup/test fixup around utf8
204
  while (my_isspace(&my_charset_utf8_general_ci,*buf++))
1 by brian
clean slate
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
77.1.44 by Monty Taylor
Fixed warnings in test
217
static void init_sym_table(void)
1 by brian
clean slate
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;
481 by Brian Aker
Remove all of uchar.
229
    if (insert_dynamic(&sym_table, (unsigned char*)&se))
1 by brian
clean slate
230
      die("insert_dynamic() failed - looks like we are out of memory");
231
  }
232
233
  verify_sort();
234
}
235
77.1.44 by Monty Taylor
Fixed warnings in test
236
static void clean_up(void)
1 by brian
clean slate
237
{
238
  delete_dynamic(&sym_table);
239
}
240
241
static void verify_sort()
242
{
482 by Brian Aker
Remove uint.
243
  uint32_t i;
481 by Brian Aker
Remove all of uchar.
244
  unsigned char* last = 0;
1 by brian
clean slate
245
246
  for (i = 0; i < sym_table.elements; i++)
247
  {
248
    SYM_ENTRY se;
481 by Brian Aker
Remove all of uchar.
249
    get_dynamic(&sym_table, (unsigned char*)&se, i);
1 by brian
clean slate
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
481 by Brian Aker
Remove all of uchar.
258
static SYM_ENTRY* resolve_addr(unsigned char* addr, SYM_ENTRY* se)
1 by brian
clean slate
259
{
482 by Brian Aker
Remove uint.
260
  uint32_t i;
481 by Brian Aker
Remove all of uchar.
261
  get_dynamic(&sym_table, (unsigned char*)se, 0);
1 by brian
clean slate
262
  if (addr < se->addr)
263
    return 0;
264
265
  for (i = 1; i < sym_table.elements; i++)
266
  {
481 by Brian Aker
Remove all of uchar.
267
    get_dynamic(&sym_table, (unsigned char*)se, i);
1 by brian
clean slate
268
    if (addr < se->addr)
269
    {
481 by Brian Aker
Remove all of uchar.
270
      get_dynamic(&sym_table, (unsigned char*)se, i - 1);
1 by brian
clean slate
271
      return se;
272
    }
273
  }
274
275
  return se;
276
}
277
278
77.1.44 by Monty Taylor
Fixed warnings in test
279
static void do_resolve(void)
1 by brian
clean slate
280
{
281
  char buf[1024], *p;
282
  while (fgets(buf, sizeof(buf), fp_dump))
283
  {
284
    p = buf;
285
    /* skip space */
383.1.10 by Brian Aker
More cleanup/test fixup around utf8
286
    while (my_isspace(&my_charset_utf8_general_ci,*p))
1 by brian
clean slate
287
      ++p;
288
289
    if (*p++ == '0' && *p++ == 'x')
290
    {
291
      SYM_ENTRY se ;
481 by Brian Aker
Remove all of uchar.
292
      unsigned char* addr = (unsigned char*)read_addr(&p);
1 by brian
clean slate
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
}