~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to extra/resolve_stack_dump.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:
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 */
15
15
 
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>
18
18
 */
19
19
 
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>
 
21
#include <m_ctype.h>
 
22
#include <my_sys.h>
 
23
#include <m_string.h>
 
24
#include <mysql_version.h>
25
25
#include <errno.h>
26
 
#include <mysys/my_getopt.h>
 
26
#include <my_getopt.h>
27
27
 
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
33
33
 
 
34
typedef ulong my_long_addr_t ; /* at some point, we need to fix configure
 
35
                                * to define this for us  
 
36
                                */
34
37
 
35
38
typedef struct sym_entry
36
39
{
37
40
  char symbol[MAX_SYM_SIZE];
38
 
  unsigned char* addr;
 
41
  uchar* addr;
39
42
} SYM_ENTRY;
40
43
 
41
44
 
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,
56
59
   0, 0, 0, 0, 0, 0},
57
60
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
58
61
};
59
62
 
60
63
 
61
 
static void verify_sort(void);
 
64
static void verify_sort();
 
65
 
 
66
 
 
67
#include <help_start.h>
62
68
 
63
69
static void print_version(void)
64
70
{
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);
67
73
}
68
74
 
69
75
 
70
 
static void usage(void)
 
76
static void usage()
71
77
{
72
78
  print_version();
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);
80
86
  printf("\n\
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");
84
90
}
85
91
 
 
92
#include <help_end.h>
 
93
 
 
94
 
86
95
static void die(const char* fmt, ...)
87
96
{
88
97
  va_list args;
95
104
}
96
105
 
97
106
 
98
 
static bool
 
107
static my_bool
99
108
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
100
109
               char *argument __attribute__((unused)))
101
110
{
115
124
{
116
125
  int ho_error;
117
126
 
118
 
  if ((ho_error= handle_options(&argc, &argv, my_long_options, get_one_option)))
 
127
  if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
119
128
    exit(ho_error);
120
129
 
121
130
  /*
149
158
}
150
159
 
151
160
 
152
 
static void open_files(void)
 
161
static void open_files()
153
162
{
154
163
  fp_out = stdout;
155
164
  fp_dump = stdin;
159
168
  /* if name not given, assume stdin*/
160
169
 
161
170
  if (!sym_fname)
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);
166
175
 
167
176
}
168
177
 
169
 
static unsigned char hex_val(char c)
 
178
static uchar hex_val(char c)
170
179
{
171
 
  unsigned char l;
172
 
  if (my_isdigit(&my_charset_utf8_general_ci,c))
 
180
  uchar l;
 
181
  if (my_isdigit(&my_charset_latin1,c))
173
182
    return c - '0';
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');
178
187
}
179
188
 
180
 
static unsigned long read_addr(char** buf)
 
189
static my_long_addr_t read_addr(char** buf)
181
190
{
182
 
  unsigned char c;
 
191
  uchar c;
183
192
  char* p = *buf;
184
 
  unsigned long addr = 0;
 
193
  my_long_addr_t addr = 0;
185
194
 
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)
194
203
{
195
204
  char* p, *p_end;
196
 
  se->addr = (unsigned char*)read_addr(&buf);
 
205
  se->addr = (uchar*)read_addr(&buf);
197
206
 
198
207
  if (!se->addr)
199
208
    return -1;
200
 
  while (my_isspace(&my_charset_utf8_general_ci,*buf++))
 
209
  while (my_isspace(&my_charset_latin1,*buf++))
201
210
    /* empty */;
202
211
 
203
 
  while (my_isspace(&my_charset_utf8_general_ci,*buf++))
 
212
  while (my_isspace(&my_charset_latin1,*buf++))
204
213
    /* empty - skip more space */;
205
214
  --buf;
206
215
  /* now we are on the symbol */
213
222
  return 0;
214
223
}
215
224
 
216
 
static void init_sym_table(void)
 
225
static void init_sym_table()
217
226
{
218
227
  char buf[512];
219
228
  if (my_init_dynamic_array(&sym_table, sizeof(SYM_ENTRY), INIT_SYM_TABLE,
225
234
    SYM_ENTRY se;
226
235
    if (init_sym_entry(&se, buf))
227
236
      continue;
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");
230
239
  }
231
240
 
232
241
  verify_sort();
233
242
}
234
243
 
235
 
static void clean_up(void)
 
244
static void clean_up()
236
245
{
237
246
  delete_dynamic(&sym_table);
238
247
}
239
248
 
240
249
static void verify_sort()
241
250
{
242
 
  uint32_t i;
243
 
  unsigned char* last = 0;
 
251
  uint i;
 
252
  uchar* last = 0;
244
253
 
245
254
  for (i = 0; i < sym_table.elements; i++)
246
255
  {
247
256
    SYM_ENTRY se;
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);
254
263
}
255
264
 
256
265
 
257
 
static SYM_ENTRY* resolve_addr(unsigned char* addr, SYM_ENTRY* se)
 
266
static SYM_ENTRY* resolve_addr(uchar* addr, SYM_ENTRY* se)
258
267
{
259
 
  uint32_t i;
260
 
  get_dynamic(&sym_table, (unsigned char*)se, 0);
 
268
  uint i;
 
269
  get_dynamic(&sym_table, (uchar*)se, 0);
261
270
  if (addr < se->addr)
262
271
    return 0;
263
272
 
264
273
  for (i = 1; i < sym_table.elements; i++)
265
274
  {
266
 
    get_dynamic(&sym_table, (unsigned char*)se, i);
 
275
    get_dynamic(&sym_table, (uchar*)se, i);
267
276
    if (addr < se->addr)
268
277
    {
269
 
      get_dynamic(&sym_table, (unsigned char*)se, i - 1);
 
278
      get_dynamic(&sym_table, (uchar*)se, i - 1);
270
279
      return se;
271
280
    }
272
281
  }
275
284
}
276
285
 
277
286
 
278
 
static void do_resolve(void)
 
287
static void do_resolve()
279
288
{
280
289
  char buf[1024], *p;
281
290
  while (fgets(buf, sizeof(buf), fp_dump))
282
291
  {
283
292
    p = buf;
284
293
    /* skip space */
285
 
    while (my_isspace(&my_charset_utf8_general_ci,*p))
 
294
    while (my_isspace(&my_charset_latin1,*p))
286
295
      ++p;
287
296
 
288
297
    if (*p++ == '0' && *p++ == 'x')
289
298
    {
290
299
      SYM_ENTRY se ;
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));