----- 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(a)marvell.com>
 > 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(a)marvell.com>
 > ---
 >  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
 >