[Crash-utility] whatis: display full parameter name when symbol is function

Dave Anderson anderson at redhat.com
Wed Mar 13 15:26:28 UTC 2013



----- Original Message -----

> I see...
> How about below patch, I add the checking for return value of
> block_for_pc_sect, is it better now?

Sorry, I can't even apply this patch: 

 # patch -p1 < textname.patch
 patching file defs.h
 Hunk #1 succeeded at 3721 with fuzz 2 (offset 36 lines).
 patching file gdb-7.3.1.patch
 patch: **** malformed patch at line 17: gdb-7.3.1/gdb/psymtab.c

 #

And if I remove the gdb-7.3.1.patch section, it still fails:

 # patch -p1 < textname.patch2
 patching file defs.h
 Hunk #1 succeeded at 3721 with fuzz 2 (offset 36 lines).
 patching file gdb_interface.c
 Hunk #1 FAILED at 590.
 1 out of 1 hunk FAILED -- saving rejects to file gdb_interface.c.rej
 patching file symbols.c
 Hunk #1 FAILED at 6660.
 Hunk #2 FAILED at 6693.
 Hunk #3 FAILED at 6705.
 3 out of 3 hunks FAILED -- saving rejects to file symbols.c.rej
 $

The patch seems to be missing tabs or something?

Anyway, when posting patches, can you please make them as attachments
to your email instead of inline? 

Also, my original complaint was that it changes the behavior of the 
"whatis" command if you enter a module text symbol without loading the
module's debuginfo data, because it quietly fails without displaying 
anything.  And that is because you've added the arg_to_datatype() call
here:

 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;
+

If you just return FALSE above, then nothing get printed at all, and
you don't reach the "error(FATAL, ..." message.

Dave



> From 8ea80a2ddbd0ea524a715a5e188118c39a0ce311 Mon Sep 17 00:00:00
> 2001
> From: Lei Wen <leiwen at marvell.com>
> Date: Mon, 11 Mar 2013 10:34:15 +0800
> Subject: [PATCH] whatis: display full parameter name when symbol is
> function
> 
> Change-Id: I4f8067f89ec67b7799be26912d76092bb844f7d2
> Signed-off-by: Lei Wen <leiwen at 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,82 @@ 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,46 @@ 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 */
> ++ if (b) {
> ++ 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
> 




More information about the Crash-utility mailing list