----- 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(a)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(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,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