[Crash-utility] [PATCH 2/2] dis: Report duplicate symbols

Aaron Tomlin atomlin at redhat.com
Mon Jul 6 08:20:28 UTC 2015


Notify the user if there is more than one symbol of the given target.

For example, after this patch:

- The 'dis' command now reports that more than one symbol of "watchdog"
  exists, to allow the user to be more specific

  crash> dis watchdog
  duplicate symbols found: watchdog
  ffffffff810e6100 (t) watchdog /usr/src/debug/kernel-2.6.32-431.1.2.el6/linux-2.6.32-431.1.2.el6.x86_64/kernel/hung_task.c: 199
  ffffffff810e6990 (t) watchdog /usr/src/debug/kernel-2.6.32-431.1.2.el6/linux-2.6.32-431.1.2.el6.x86_64/kernel/watchdog.c: 332
  ffffffff81eb3fc8 (b) watchdog

- Choose to disassemble the watchdog() function defined in
  kernel/watchdog.c by using the address of the first function

  crash> dis ffffffff810e6990
  0xffffffff810e6990 <watchdog>:	push   %rbp
  0xffffffff810e6991 <watchdog+1>:	mov    %rsp,%rbp
  0xffffffff810e6994 <watchdog+4>:	push   %r13
  0xffffffff810e699d <watchdog+13>:	nopl   0x0(%rax,%rax,1)
  ...

Signed-off-by: Aaron Tomlin <atomlin at redhat.com>
---
 defs.h    |  1 +
 kernel.c  | 28 ++++++++++++++++++++++++----
 symbols.c |  3 +--
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/defs.h b/defs.h
index f21137d..26aa963 100644
--- a/defs.h
+++ b/defs.h
@@ -4585,6 +4585,7 @@ void show_symbol(struct syment *, ulong, ulong);
 #define SHOW_DEC_OFFS (0x8)
 #define SHOW_RADIX() (*gdb_output_radix == 16 ? SHOW_HEX_OFFS : SHOW_DEC_OFFS)
 #define SHOW_MODULE  (0x10)
+int symbol_name_count(char *);
 int symbol_query(char *, char *, struct syment **);
 struct syment *next_symbol(char *, struct syment *);
 struct syment *prev_symbol(char *, struct syment *);
diff --git a/kernel.c b/kernel.c
index 628779c..b87d9ec 100644
--- a/kernel.c
+++ b/kernel.c
@@ -1339,6 +1339,7 @@ cmd_dis(void)
 	ulong revtarget;
 	ulong count;
 	ulong offset;
+	ulong show_flags;
 	struct syment *sp;
 	struct gnu_request *req;
 	char *savename; 
@@ -1362,6 +1363,7 @@ cmd_dis(void)
 	sp = NULL;
 	unfiltered = user_mode = do_machdep_filter = do_load_module_filter = 0;
 	radix = 0;
+	show_flags = SHOW_LINENUM | SHOW_RADIX();
 
 	req = (struct gnu_request *)getbuf(sizeof(struct gnu_request));
 	req->buf = GETBUF(BUFSIZE);
@@ -1425,7 +1427,28 @@ cmd_dis(void)
 		radix = pc->output_radix;
 
         if (args[optind]) {
-                if (can_eval(args[optind])) 
+		if ((sp = symbol_search(args[optind])) &&
+		    ((symbol_name_count(sp->name)) > 1)) {
+                        fprintf(fp, "duplicate symbols found: %s\n",
+			    args[optind]);
+
+			do {
+				if (module_symbol(sp->value, NULL, NULL,
+				    NULL, 0))
+					show_symbol(sp, 0, show_flags|SHOW_MODULE);
+				else
+					show_symbol(sp, 0, show_flags);
+
+			} while ((sp = symbol_search_next(sp->name, sp)));
+
+			FREEBUF(req->buf);
+			FREEBUF(req);
+			return;
+		}
+		if (sp) {
+			req->addr = sp->value;
+			req->flags |= GNU_FUNCTION_ONLY;
+		} else if (can_eval(args[optind]))
                         req->addr = eval(args[optind], FAULT_ON_ERROR, NULL);
                 else if (hexadecimal(args[optind], 0)) {
                         req->addr = htol(args[optind], FAULT_ON_ERROR, NULL);
@@ -1438,9 +1461,6 @@ cmd_dis(void)
 			}
 			if (!offset)
 				req->flags |= GNU_FUNCTION_ONLY;
-                } else if ((sp = symbol_search(args[optind]))) {
-                        req->addr = sp->value;
-			req->flags |= GNU_FUNCTION_ONLY;
 		} else {
                         fprintf(fp, "symbol not found: %s\n", args[optind]);
                         fprintf(fp, "possible alternatives:\n");
diff --git a/symbols.c b/symbols.c
index 48d9f58..958181a 100644
--- a/symbols.c
+++ b/symbols.c
@@ -37,7 +37,6 @@ static asection *get_kernel_section(char *);
 static char * get_section(ulong vaddr, char *buf);
 static void symbol_dump(ulong, char *);
 static void check_for_dups(struct load_module *);
-static int symbol_name_count(char *);
 static struct syment *kallsyms_module_symbol(struct load_module *, symbol_info *);
 static void store_load_module_symbols \
 	(bfd *, int, void *, long, uint, ulong, char *);
@@ -4156,7 +4155,7 @@ symbol_search(char *s)
 /*
  *  Count the number of instances of a symbol name.
  */
-static int
+int
 symbol_name_count(char *s)
 {
         int i;
-- 
2.4.3




More information about the Crash-utility mailing list