The world's most popular open source database
#include <my_global.h>#include <m_ctype.h>#include <my_sys.h>#include <m_string.h>#include <mysql_version.h>#include <errno.h>#include <my_getopt.h>#include <help_start.h>#include <help_end.h>Include dependency graph for resolve_stack_dump.c:

Go to the source code of this file.
Classes | |
| struct | sym_entry |
Defines | |
| #define | DONT_USE_RAID |
| #define | INIT_SYM_TABLE 4096 |
| #define | INC_SYM_TABLE 4096 |
| #define | MAX_SYM_SIZE 128 |
| #define | DUMP_VERSION "1.4" |
| #define | HEX_INVALID (uchar)255 |
Typedefs | |
| typedef ulong | my_long_addr_t |
| typedef sym_entry | SYM_ENTRY |
Functions | |
| static void | verify_sort () |
| static void | print_version (void) |
| static void | usage () |
| static void | die (const char *fmt,...) |
| static my_bool | get_one_option (int optid, const struct my_option *opt __attribute__((unused)), char *argument __attribute__((unused))) |
| static int | parse_args (int argc, char **argv) |
| static void | open_files () |
| static uchar | hex_val (char c) |
| static my_long_addr_t | read_addr (char **buf) |
| static int | init_sym_entry (SYM_ENTRY *se, char *buf) |
| static void | init_sym_table () |
| static void | clean_up () |
| static SYM_ENTRY * | resolve_addr (uchar *addr, SYM_ENTRY *se) |
| static void | do_resolve () |
| int | main (int argc, char **argv) |
Variables | |
| static char * | dump_fname = 0 |
| static char * | sym_fname = 0 |
| static DYNAMIC_ARRAY | sym_table |
| static FILE * | fp_dump |
| static FILE * | fp_sym = 0 |
| static FILE * | fp_out |
| static struct my_option | my_long_options [] |
| #define DONT_USE_RAID |
Definition at line 21 of file resolve_stack_dump.c.
| #define DUMP_VERSION "1.4" |
Definition at line 33 of file resolve_stack_dump.c.
| #define HEX_INVALID (uchar)255 |
| #define INC_SYM_TABLE 4096 |
| #define INIT_SYM_TABLE 4096 |
| #define MAX_SYM_SIZE 128 |
Definition at line 32 of file resolve_stack_dump.c.
| typedef ulong my_long_addr_t |
Definition at line 36 of file resolve_stack_dump.c.
| static void clean_up | ( | ) | [static] |
Definition at line 246 of file resolve_stack_dump.c.
References delete_dynamic(), and sym_table.
00247 { 00248 delete_dynamic(&sym_table); 00249 }
Here is the call graph for this function:

| static void die | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 97 of file resolve_stack_dump.c.
References args, exit, and my_progname.
00098 { 00099 va_list args; 00100 va_start(args, fmt); 00101 fprintf(stderr, "%s: ", my_progname); 00102 vfprintf(stderr, fmt, args); 00103 fprintf(stderr, "\n"); 00104 va_end(args); 00105 exit(1); 00106 }
| static void do_resolve | ( | ) | [static] |
Definition at line 289 of file resolve_stack_dump.c.
References sym_entry::addr, buf, fp_dump, fp_out, my_charset_latin1, my_isspace, p, read_addr(), resolve_addr(), and sym_entry::symbol.
Referenced by main().
00290 { 00291 char buf[1024], *p; 00292 while (fgets(buf, sizeof(buf), fp_dump)) 00293 { 00294 p = buf; 00295 /* skip space */ 00296 while (my_isspace(&my_charset_latin1,*p)) 00297 ++p; 00298 00299 if (*p++ == '0' && *p++ == 'x') 00300 { 00301 SYM_ENTRY se ; 00302 uchar* addr = (uchar*)read_addr(&p); 00303 if (resolve_addr(addr, &se)) 00304 fprintf(fp_out, "%p %s + %d\n", addr, se.symbol, 00305 (int) (addr - se.addr)); 00306 else 00307 fprintf(fp_out, "%p (?)\n", addr); 00308 00309 } 00310 else 00311 { 00312 fputs(buf, fp_out); 00313 continue; 00314 } 00315 } 00316 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static my_bool get_one_option | ( | int | optid, | |
| const struct my_option *opt | __attribute__((unused)), | |||
| char *argument | __attribute__((unused)) | |||
| ) | [static] |
Definition at line 110 of file resolve_stack_dump.c.
References exit, print_version(), and usage().
00112 { 00113 switch(optid) { 00114 case 'V': 00115 print_version(); 00116 exit(0); 00117 case '?': 00118 usage(); 00119 exit(0); 00120 } 00121 return 0; 00122 }
Here is the call graph for this function:

| static uchar hex_val | ( | char | c | ) | [static] |
Definition at line 180 of file resolve_stack_dump.c.
References HEX_INVALID, my_charset_latin1, my_isdigit, and my_tolower.
Referenced by read_addr().
00181 { 00182 uchar l; 00183 if (my_isdigit(&my_charset_latin1,c)) 00184 return c - '0'; 00185 l = my_tolower(&my_charset_latin1,c); 00186 if (l < 'a' || l > 'f') 00187 return HEX_INVALID; 00188 return (uchar)10 + ((uchar)c - (uchar)'a'); 00189 }
Here is the caller graph for this function:

| static int init_sym_entry | ( | SYM_ENTRY * | se, | |
| char * | buf | |||
| ) | [static] |
Definition at line 204 of file resolve_stack_dump.c.
References sym_entry::addr, my_charset_latin1, my_isspace, p, read_addr(), strcmp(), and sym_entry::symbol.
Referenced by init_sym_table().
00205 { 00206 char* p, *p_end; 00207 se->addr = (uchar*)read_addr(&buf); 00208 00209 if (!se->addr) 00210 return -1; 00211 while (my_isspace(&my_charset_latin1,*buf++)) 00212 /* empty */; 00213 00214 while (my_isspace(&my_charset_latin1,*buf++)) 00215 /* empty - skip more space */; 00216 --buf; 00217 /* now we are on the symbol */ 00218 for (p = se->symbol, p_end = se->symbol + sizeof(se->symbol) - 1; 00219 *buf != '\n' && *buf && p < p_end; ++buf,++p) 00220 *p = *buf; 00221 *p = 0; 00222 if (!strcmp(se->symbol, "gcc2_compiled.")) 00223 return -1; 00224 return 0; 00225 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void init_sym_table | ( | ) | [static] |
Definition at line 227 of file resolve_stack_dump.c.
References buf, die(), fp_sym, INC_SYM_TABLE, init_sym_entry(), INIT_SYM_TABLE, insert_dynamic(), my_init_dynamic_array, sym_table, and verify_sort().
Referenced by main().
00228 { 00229 char buf[512]; 00230 if (my_init_dynamic_array(&sym_table, sizeof(SYM_ENTRY), INIT_SYM_TABLE, 00231 INC_SYM_TABLE)) 00232 die("Failed in my_init_dynamic_array() -- looks like out of memory problem"); 00233 00234 while (fgets(buf, sizeof(buf), fp_sym)) 00235 { 00236 SYM_ENTRY se; 00237 if (init_sym_entry(&se, buf)) 00238 continue; 00239 if (insert_dynamic(&sym_table, (gptr)&se)) 00240 die("insert_dynamic() failed - looks like we are out of memory"); 00241 } 00242 00243 verify_sort(); 00244 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int main | ( | int | argc, | |
| char ** | argv | |||
| ) |
Definition at line 319 of file resolve_stack_dump.c.
References clean_up(), do_resolve(), init_sym_table(), MY_INIT, open_files(), and parse_args().
00320 { 00321 MY_INIT(argv[0]); 00322 parse_args(argc, argv); 00323 open_files(); 00324 init_sym_table(); 00325 do_resolve(); 00326 clean_up(); 00327 return 0; 00328 }
Here is the call graph for this function:

| static void open_files | ( | ) | [static] |
Definition at line 163 of file resolve_stack_dump.c.
References die(), dump_fname, fp_dump, fp_out, fp_sym, my_fopen(), MY_WME, MYF, and sym_fname.
Referenced by main().
00164 { 00165 fp_out = stdout; 00166 fp_dump = stdin; 00167 00168 if (dump_fname && !(fp_dump = my_fopen(dump_fname, O_RDONLY, MYF(MY_WME)))) 00169 die("Could not open %s", dump_fname); 00170 /* if name not given, assume stdin*/ 00171 00172 if (!sym_fname) 00173 die("Please run nm --numeric-sort on mysqld binary that produced stack \ 00174 trace dump and specify the path to it with -s or --symbols-file"); 00175 if (!(fp_sym = my_fopen(sym_fname, O_RDONLY, MYF(MY_WME)))) 00176 die("Could not open %s", sym_fname); 00177 00178 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int parse_args | ( | int | argc, | |
| char ** | argv | |||
| ) | [static] |
Definition at line 125 of file resolve_stack_dump.c.
References dump_fname, exit, get_one_option(), handle_options(), my_long_options, sym_fname, and usage().
00126 { 00127 int ho_error; 00128 00129 if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) 00130 exit(ho_error); 00131 00132 /* 00133 The following code is to make the command compatible with the old 00134 version that required one to use the -n and -s options 00135 */ 00136 00137 if (argc == 2) 00138 { 00139 sym_fname= argv[0]; 00140 dump_fname= argv[1]; 00141 } 00142 else if (argc == 1) 00143 { 00144 if (!sym_fname) 00145 sym_fname = argv[0]; 00146 else if (!dump_fname) 00147 dump_fname = argv[0]; 00148 else 00149 { 00150 usage(); 00151 exit(1); 00152 } 00153 } 00154 else if (argc != 0 || !sym_fname) 00155 { 00156 usage(); 00157 exit(1); 00158 } 00159 return 0; 00160 }
Here is the call graph for this function:

| static void print_version | ( | void | ) | [static] |
Definition at line 71 of file resolve_stack_dump.c.
References DUMP_VERSION, MACHINE_TYPE, my_progname, MYSQL_SERVER_VERSION, and SYSTEM_TYPE.
00072 { 00073 printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,DUMP_VERSION, 00074 MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); 00075 }
| static my_long_addr_t read_addr | ( | char ** | buf | ) | [static] |
Definition at line 191 of file resolve_stack_dump.c.
References HEX_INVALID, hex_val(), and p.
Referenced by do_resolve(), and init_sym_entry().
00192 { 00193 uchar c; 00194 char* p = *buf; 00195 my_long_addr_t addr = 0; 00196 00197 while((c = hex_val(*p++)) != HEX_INVALID) 00198 addr = (addr << 4) + c; 00199 00200 *buf = p; 00201 return addr; 00202 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 268 of file resolve_stack_dump.c.
References st_dynamic_array::elements, get_dynamic(), and sym_table.
Referenced by do_resolve().
00269 { 00270 uint i; 00271 get_dynamic(&sym_table, (gptr)se, 0); 00272 if (addr < se->addr) 00273 return 0; 00274 00275 for (i = 1; i < sym_table.elements; i++) 00276 { 00277 get_dynamic(&sym_table, (gptr)se, i); 00278 if (addr < se->addr) 00279 { 00280 get_dynamic(&sym_table, (gptr)se, i - 1); 00281 return se; 00282 } 00283 } 00284 00285 return se; 00286 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void usage | ( | void | ) | [static] |
Definition at line 78 of file resolve_stack_dump.c.
References my_long_options, my_print_help(), my_print_variables(), my_progname, and print_version().
00079 { 00080 print_version(); 00081 printf("MySQL AB, by Sasha Pachev\n"); 00082 printf("This software comes with ABSOLUTELY NO WARRANTY\n\n"); 00083 printf("Resolve numeric stack strace dump into symbols.\n\n"); 00084 printf("Usage: %s [OPTIONS] symbols-file [numeric-dump-file]\n", 00085 my_progname); 00086 my_print_help(my_long_options); 00087 my_print_variables(my_long_options); 00088 printf("\n\ 00089 The symbols-file should include the output from: 'nm --numeric-sort mysqld'.\n\ 00090 The numeric-dump-file should contain a numeric stack trace from mysqld.\n\ 00091 If the numeric-dump-file is not given, the stack trace is read from stdin.\n"); 00092 }
Here is the call graph for this function:

| static void verify_sort | ( | ) | [static] |
Definition at line 251 of file resolve_stack_dump.c.
References die(), st_dynamic_array::elements, get_dynamic(), and sym_table.
Referenced by init_sym_table().
00252 { 00253 uint i; 00254 uchar* last = 0; 00255 00256 for (i = 0; i < sym_table.elements; i++) 00257 { 00258 SYM_ENTRY se; 00259 get_dynamic(&sym_table, (gptr)&se, i); 00260 if (se.addr < last) 00261 die("sym table does not appear to be sorted, did you forget \ 00262 --numeric-sort arg to nm? trouble addr = %p, last = %p", se.addr, last); 00263 last = se.addr; 00264 } 00265 }
Here is the call graph for this function:

Here is the caller graph for this function:

char* dump_fname = 0 [static] |
FILE* fp_dump [static] |
FILE * fp_out [static] |
FILE * fp_sym = 0 [static] |
Definition at line 49 of file resolve_stack_dump.c.
Referenced by init_sym_table(), and open_files().
struct my_option my_long_options[] [static] |
Initial value:
{
{"help", 'h', "Display this help and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"symbols-file", 's', "Use specified symbols file.", (gptr*) &sym_fname,
(gptr*) &sym_fname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"numeric-dump-file", 'n', "Read the dump from specified file.",
(gptr*) &dump_fname, (gptr*) &dump_fname, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
}
Definition at line 51 of file resolve_stack_dump.c.
char * sym_fname = 0 [static] |
DYNAMIC_ARRAY sym_table [static] |
Definition at line 48 of file resolve_stack_dump.c.
Referenced by clean_up(), init_sym_table(), resolve_addr(), and verify_sort().
1.4.7

