----- Original Message ----- > But unfortunately, it's not necessarily reproducible, even with the same set > of commands! > > The backtrace above was from a live session, and now I can't seem to reproduce it. > But I'm guessing that block_for_pc_sect() returned a NULL "b" pointer. > > Dave I was able to reproduce once by running this set of commands from an input file: $ cat /tmp/input whatis crash_read mod -s crash whatis crash_read whatis call_transmit mod -s sunrpc whatis call_transmit whatis nfs_alloc_server mod -s nfs whatis nfs_alloc_server $ which resulted in: crash> < /tmp/input crash> whatis crash_read crash> mod -s crash MODULE NAME SIZE OBJECT FILE ffffffffa07c5140 crash 12577 /lib/modules/3.7.9-104.fc17.x86_64/kernel/drivers/char/crash.ko crash> whatis crash_read ssize_t crash_read(struct file * file, char * buf, size_t count, loff_t * poff); crash> whatis call_transmit <segmentation violation in gdb> crash> mod -s sunrpc MODULE NAME SIZE OBJECT FILE ffffffffa0153ea0 sunrpc 255581 /lib/modules/3.7.9-104.fc17.x86_64/kernel/net/sunrpc/sunrpc.ko crash> whatis call_transmit <segmentation violation in gdb> crash> whatis nfs_alloc_server <segmentation violation in gdb> crash> mod -s nfs MODULE NAME SIZE OBJECT FILE ffffffffa07ad920 nfs 169253 /lib/modules/3.7.9-104.fc17.x86_64/kernel/fs/nfs/nfs.ko crash> whatis nfs_alloc_server <segmentation violation in gdb> crash> But again, it's not reproducible all of the time? Anyway, it was getting a NULL back from the first call to to block_for_pc_sect(): b = block_for_pc_sect(req->pc, find_pc_mapped_section(req->pc)); /* Get the lexical block, which is not a inline function */ while ((BLOCK_FUNCTION(b) == NULL || block_inlined_p(b)) && BLOCK_SUPERBLOCK(b) != NULL) b = BLOCK_SUPERBLOCK(b); And I note that other gdb usage of block_for_pc_sect() or the block_for_pc() wrapper function do seem to ensure a non-NULL return value. Dave > > > > > > From 8ea80a2ddbd0ea524a715a5e188118c39a0ce311 Mon Sep 17 00:00:00 > > 2001 > > From: Lei Wen <leiwen@xxxxxxxxxxx> > > Date: Mon, 11 Mar 2013 10:34:15 +0800 > > Subject: [PATCH] whatis: display full parameter name when symbol is > > function > > > > Signed-off-by: Lei Wen <leiwen@xxxxxxxxxxx> > > --- > > defs.h | 1 + > > gdb-7.3.1.patch | 77 > > +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > gdb_interface.c | 3 ++ > > symbols.c | 50 +++++++++++++++++++++++++++++++++++- > > 4 files changed, 130 insertions(+), 1 deletions(-) > > > > diff --git a/defs.h b/defs.h > > index 1f693c3..1b31d1f 100755 > > --- a/defs.h > > +++ b/defs.h > > @@ -3685,6 +3685,7 @@ struct gnu_request { > > #define GNU_GET_SYMBOL_TYPE (15) > > #define GNU_USER_PRINT_OPTION (16) > > #define GNU_SET_CRASH_BLOCK (17) > > +#define GNU_FUNCTION_NAMEARGS (18) > > #define GNU_DEBUG_COMMAND (100) > > /* > > * GNU flags > > diff --git a/gdb-7.3.1.patch b/gdb-7.3.1.patch > > index a12d3d4..3b0f0d1 100644 > > --- a/gdb-7.3.1.patch > > +++ b/gdb-7.3.1.patch > > @@ -1821,3 +1821,80 @@ diff -up gdb-7.3.1/gdb/psymtab.c.orig > > gdb-7.3.1/gdb/psymtab.c > > break; > > > > if (cur_sec == NULL) > > +--- gdb-7.3.1/gdb/symtab.c.orig > > ++++ gdb-7.3.1/gdb/symtab.c > > +@@ -4848,6 +4848,7 @@ static void gdb_get_symbol_type(struct > > gnu_request *); > > + static void gdb_command_exists(struct gnu_request *); > > + static void gdb_debug_command(struct gnu_request *); > > + static void gdb_function_numargs(struct gnu_request *); > > ++static void gdb_function_nameargs(struct gnu_request *); > > + static void gdb_add_symbol_file(struct gnu_request *); > > + static void gdb_delete_symbol_file(struct gnu_request *); > > + static void gdb_patch_symbol_values(struct gnu_request *); > > +@@ -4952,6 +4953,10 @@ gdb_command_funnel(struct gnu_request *req) > > + gdb_set_crash_block(req); > > + break; > > + > > ++ case GNU_FUNCTION_NAMEARGS: > > ++ gdb_function_nameargs(req); > > ++ break; > > ++ > > + default: > > + req->flags |= GNU_COMMAND_FAILED; > > + break; > > +@@ -5054,8 +5059,9 @@ gdb_get_datatype(struct gnu_request *req) > > + if (gdb_CRASHDEBUG(2)) > > + console("expr->elts[0].opcode: OP_VAR_VALUE\n"); > > + type = expr->elts[2].symbol->type; > > ++ req->typecode = TYPE_CODE(type); > > ++ req->length = TYPE_LENGTH(type); > > + if (TYPE_CODE(type) == TYPE_CODE_ENUM) { > > +- req->typecode = TYPE_CODE(type); > > + req->value = SYMBOL_VALUE(expr->elts[2].symbol); > > + req->tagname = TYPE_TAG_NAME(type); > > + if (!req->tagname) { > > +@@ -5243,6 +5249,44 @@ gdb_function_numargs(struct gnu_request > > *req) > > + req->value = (ulong)TYPE_NFIELDS(sym->type); > > + } > > + > > ++static void > > ++gdb_function_nameargs(struct gnu_request *req) > > ++{ > > ++ struct block *b; > > ++ struct dict_iterator iter; > > ++ struct symbol *sym = NULL; > > ++ int len; > > ++ char *buf = req->buf; > > ++ > > ++ b = block_for_pc_sect(req->pc, find_pc_mapped_section(req->pc)); > > ++ /* Get the lexical block, which is not a inline function */ > > ++ while ((BLOCK_FUNCTION(b) == NULL || block_inlined_p(b)) > > ++ && BLOCK_SUPERBLOCK(b) != NULL) > > ++ b = BLOCK_SUPERBLOCK(b); > > ++ > > ++ ALL_BLOCK_SYMBOLS (b, iter, sym) > > ++ { > > ++ if (!SYMBOL_IS_ARGUMENT (sym)) > > ++ continue; > > ++ > > ++ if (*SYMBOL_LINKAGE_NAME (sym)) > > ++ { > > ++ struct symbol *nsym; > > ++ > > ++ nsym = lookup_symbol (SYMBOL_LINKAGE_NAME (sym), > > ++ b, VAR_DOMAIN, NULL); > > ++ gdb_assert (nsym != NULL); > > ++ if (SYMBOL_CLASS (nsym) != LOC_REGISTER > > ++ || SYMBOL_IS_ARGUMENT (nsym)) > > ++ sym = nsym; > > ++ } > > ++ > > ++ len = strlen(SYMBOL_PRINT_NAME(sym)); > > ++ sprintf(buf, "%s,", SYMBOL_PRINT_NAME(sym)); > > ++ buf += len + 1; > > ++ } > > ++} > > ++ > > + struct load_module *gdb_current_load_module = NULL; > > + > > + static void > > diff --git a/gdb_interface.c b/gdb_interface.c > > index afc197c..a460ea8 100755 > > --- a/gdb_interface.c > > +++ b/gdb_interface.c > > @@ -590,6 +590,9 @@ gdb_command_string(int cmd, char *buf, int > > live) > > case GNU_SET_CRASH_BLOCK: > > sprintf(buf, "GNU_SET_CRASH_BLOCK"); > > break; > > + case GNU_FUNCTION_NAMEARGS: > > + sprintf(buf, "GNU_FUNCTION_NAMEARGS"); > > + break; > > case 0: > > buf[0] = NULLCHAR; > > break; > > diff --git a/symbols.c b/symbols.c > > index 4fb397c..b38a2a3 100755 > > --- a/symbols.c > > +++ b/symbols.c > > @@ -6660,18 +6660,62 @@ whatis_datatype(char *st, ulong flags, FILE > > *ofp) > > } > > > > /* > > + * add the function argument to the function type showing > > + * The arg name input is seperated by comma > > + */ > > +static void > > +add_function_name(char *argnames, char *func) > > +{ > > + char *arg, *seperator, *tmp; > > + > > + tmp = func; > > + for (arg = strtok(argnames, ","); arg; ) { > > + seperator = strstr(tmp, ","); > > + if (!seperator) > > + seperator= strrchr(func, ')'); > > + > > + shift_string_right(seperator, strlen(arg) + 1); > > + BCOPY(arg, seperator + 1, strlen(arg)); > > + tmp = seperator + 2 + strlen(arg); > > + arg = strtok(NULL, ","); > > + } > > +} > > + > > +/* > > * Scan the symbol file for a variable declaration. > > */ > > static void > > whatis_variable(struct syment *sp) > > { > > + struct datatype_member datatype_member, *dm; > > + struct gnu_request *req; > > + int ret; > > char *p1; > > char buf[BUFSIZE]; > > > > + dm = &datatype_member; > > + strcpy(buf, sp->name); > > + if (!arg_to_datatype(buf, dm, RETURN_ON_ERROR|DATATYPE_QUERY)) > > + return FALSE; > > + > > open_tmpfile(); > > sprintf(buf, "whatis %s", sp->name); > > - if (!gdb_pass_through(buf, fp, GNU_RETURN_ON_ERROR)) { > > + > > + req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request)); > > + req->buf = GETBUF(BUFSIZE); > > + > > + ret = gdb_pass_through(buf, fp, GNU_RETURN_ON_ERROR); > > + if (ret && dm->type == FUNCTION) { > > + req->command = GNU_FUNCTION_NAMEARGS; > > + req->flags |= GNU_RETURN_ON_ERROR; > > + req->pc = symbol_value(sp->name); > > + > > + gdb_interface(req); > > + } > > + if (!ret || req->flags & GNU_COMMAND_FAILED) { > > close_tmpfile(); > > + FREEBUF(req->buf); > > + FREEBUF(req); > > error(FATAL, "gdb request failed: whatis %s\n", > > sp->name); > > } > > > > @@ -6693,6 +6737,7 @@ whatis_variable(struct syment *sp) > > if (index(buf, '(') == rindex(buf, '(')) { > > shift_string_right(p1, strlen(sp->name)); > > BCOPY(sp->name, p1, strlen(sp->name)); > > + add_function_name(req->buf, p1 + strlen(sp->name)); > > } else { > > p1 = strstr(buf, ")"); > > shift_string_right(p1, strlen(sp->name)); > > @@ -6705,6 +6750,9 @@ whatis_variable(struct syment *sp) > > fprintf(fp, "%s%s%s;\n", p1, LASTCHAR(p1) == '*' ? > > "":" ", > > sp->name); > > } > > + > > + FREEBUF(req->buf); > > + FREEBUF(req); > > } > > > > /* > > -- > > 1.7.5.4 > > > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility