13
13
along with this program; if not, write to the Free Software
14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
/* Resolve numeric stack dump produced by drizzled 3.23.30 and later
16
/* Resolve numeric stack dump produced by mysqld 3.23.30 and later
17
17
versions into symbolic names. By Sasha Pachev <sasha@mysql.com>
20
#include <drizzled/global.h>
21
#include <mystrings/m_ctype.h>
22
#include <mysys/my_sys.h>
23
#include <mystrings/m_string.h>
24
#include <drizzled/version.h>
20
#include <my_global.h>
24
#include <mysql_version.h>
26
#include <mysys/my_getopt.h>
26
#include <my_getopt.h>
28
28
#define INIT_SYM_TABLE 4096
29
29
#define INC_SYM_TABLE 4096
30
30
#define MAX_SYM_SIZE 128
31
31
#define DUMP_VERSION "1.4"
32
#define HEX_INVALID (unsigned char)255
32
#define HEX_INVALID (uchar)255
34
typedef ulong my_long_addr_t ; /* at some point, we need to fix configure
35
* to define this for us
35
38
typedef struct sym_entry
37
40
char symbol[MAX_SYM_SIZE];
49
52
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
50
53
{"version", 'V', "Output version information and exit.",
51
54
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
52
{"symbols-file", 's', "Use specified symbols file.", (char**) &sym_fname,
53
(char**) &sym_fname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
55
{"symbols-file", 's', "Use specified symbols file.", (uchar**) &sym_fname,
56
(uchar**) &sym_fname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
54
57
{"numeric-dump-file", 'n', "Read the dump from specified file.",
55
(char**) &dump_fname, (char**) &dump_fname, 0, GET_STR, REQUIRED_ARG,
58
(uchar**) &dump_fname, (uchar**) &dump_fname, 0, GET_STR, REQUIRED_ARG,
57
60
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
61
static void verify_sort(void);
64
static void verify_sort();
67
#include <help_start.h>
63
69
static void print_version(void)
65
71
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,DUMP_VERSION,
66
DRIZZLE_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
72
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
70
static void usage(void)
73
79
printf("MySQL AB, by Sasha Pachev\n");
78
84
my_print_help(my_long_options);
79
85
my_print_variables(my_long_options);
81
The symbols-file should include the output from: 'nm --numeric-sort drizzled'.\n\
82
The numeric-dump-file should contain a numeric stack trace from drizzled.\n\
87
The symbols-file should include the output from: 'nm --numeric-sort mysqld'.\n\
88
The numeric-dump-file should contain a numeric stack trace from mysqld.\n\
83
89
If the numeric-dump-file is not given, the stack trace is read from stdin.\n");
86
95
static void die(const char* fmt, ...)
159
168
/* if name not given, assume stdin*/
162
die("Please run nm --numeric-sort on drizzled binary that produced stack \
171
die("Please run nm --numeric-sort on mysqld binary that produced stack \
163
172
trace dump and specify the path to it with -s or --symbols-file");
164
173
if (!(fp_sym = my_fopen(sym_fname, O_RDONLY, MYF(MY_WME))))
165
174
die("Could not open %s", sym_fname);
169
static unsigned char hex_val(char c)
178
static uchar hex_val(char c)
172
if (my_isdigit(&my_charset_utf8_general_ci,c))
181
if (my_isdigit(&my_charset_latin1,c))
174
l = my_tolower(&my_charset_utf8_general_ci,c);
183
l = my_tolower(&my_charset_latin1,c);
175
184
if (l < 'a' || l > 'f')
176
185
return HEX_INVALID;
177
return (unsigned char)10 + ((unsigned char)c - (unsigned char)'a');
186
return (uchar)10 + ((uchar)c - (uchar)'a');
180
static unsigned long read_addr(char** buf)
189
static my_long_addr_t read_addr(char** buf)
184
unsigned long addr = 0;
193
my_long_addr_t addr = 0;
186
195
while((c = hex_val(*p++)) != HEX_INVALID)
187
196
addr = (addr << 4) + c;
193
202
static int init_sym_entry(SYM_ENTRY* se, char* buf)
196
se->addr = (unsigned char*)read_addr(&buf);
205
se->addr = (uchar*)read_addr(&buf);
200
while (my_isspace(&my_charset_utf8_general_ci,*buf++))
209
while (my_isspace(&my_charset_latin1,*buf++))
203
while (my_isspace(&my_charset_utf8_general_ci,*buf++))
212
while (my_isspace(&my_charset_latin1,*buf++))
204
213
/* empty - skip more space */;
206
215
/* now we are on the symbol */
226
235
if (init_sym_entry(&se, buf))
228
if (insert_dynamic(&sym_table, (unsigned char*)&se))
237
if (insert_dynamic(&sym_table, (uchar*)&se))
229
238
die("insert_dynamic() failed - looks like we are out of memory");
235
static void clean_up(void)
244
static void clean_up()
237
246
delete_dynamic(&sym_table);
240
249
static void verify_sort()
243
unsigned char* last = 0;
245
254
for (i = 0; i < sym_table.elements; i++)
248
get_dynamic(&sym_table, (unsigned char*)&se, i);
257
get_dynamic(&sym_table, (uchar*)&se, i);
249
258
if (se.addr < last)
250
259
die("sym table does not appear to be sorted, did you forget \
251
260
--numeric-sort arg to nm? trouble addr = %p, last = %p", se.addr, last);
257
static SYM_ENTRY* resolve_addr(unsigned char* addr, SYM_ENTRY* se)
266
static SYM_ENTRY* resolve_addr(uchar* addr, SYM_ENTRY* se)
260
get_dynamic(&sym_table, (unsigned char*)se, 0);
269
get_dynamic(&sym_table, (uchar*)se, 0);
261
270
if (addr < se->addr)
264
273
for (i = 1; i < sym_table.elements; i++)
266
get_dynamic(&sym_table, (unsigned char*)se, i);
275
get_dynamic(&sym_table, (uchar*)se, i);
267
276
if (addr < se->addr)
269
get_dynamic(&sym_table, (unsigned char*)se, i - 1);
278
get_dynamic(&sym_table, (uchar*)se, i - 1);
278
static void do_resolve(void)
287
static void do_resolve()
280
289
char buf[1024], *p;
281
290
while (fgets(buf, sizeof(buf), fp_dump))
285
while (my_isspace(&my_charset_utf8_general_ci,*p))
294
while (my_isspace(&my_charset_latin1,*p))
288
297
if (*p++ == '0' && *p++ == 'x')
291
unsigned char* addr = (unsigned char*)read_addr(&p);
300
uchar* addr = (uchar*)read_addr(&p);
292
301
if (resolve_addr(addr, &se))
293
302
fprintf(fp_out, "%p %s + %d\n", addr, se.symbol,
294
303
(int) (addr - se.addr));