This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFA] Find the most specific symtab
- From: Michal Ludvig <mludvig at suse dot cz>
- To: GDB Patches <gdb-patches at sources dot redhat dot com>
- Date: Mon, 20 Oct 2003 16:25:28 +0200
- Subject: [RFA] Find the most specific symtab
- Organization: SuSE CR, s.r.o.
Hi,
when debugging modules in linux kernel one must load symtab from each
module using add-symbol-file command. However find_pc_sect_psymtab()
returns with the first, usually less specific entry among all psymtabs
instead of the newly added one, which leads to a situation where the
wrong source file is chosen and therefore the "next", "next", ...
stepping is unusable.
The attached patch modifies find_pc_sect_psymtab() so that it always
returns the most specific symtab. Typical debugging session with
verbosity tured on now looks like:
$ ./gdb /share/linux-2.4.21-2-mludvig/vmlinux
GNU gdb 2003-10-20-cvs
[...]
(gdb) add-symbol-file /share/lkm/lkm.o 0xffa00180c0
add symbol table from file "/share/lkm/lkm.o" at
.text_addr = 0xffa00180c0
(y or n) y
Reading symbols from /share/lkm/lkm.o...done.
(gdb) set verbose
(gdb) l lkm_exit
More symtabs for PC=0xffffffffa00181b0 found:
Ignoring vsyscall.c (vmlinux) PC=0xff802c9400...0xffff60042a
Choosing lkm.c (lkm.o) PC=0xffa00180c0...0xffa00181d9
55 void
56 lkm_exit(void)
57 {
58 printk(KERN_INFO "Exitting LKM (jiffies=%lu)...\n", jiffies);
59 lkm_func(jiffies);
60 }
61
(gdb)
OK for mainline? Or should there be a different approach?
Michal Ludvig
--
sUsE cR, s.R.o mludvig@suse.cz | I would like to change
(+420) 296.545.373 http://www.suse.cz | the world, but they wont
Personal homepage http://www.logix.cz/~mic | tell me the source code.
2003-10-23 Michal Ludvig <mludvig@suse.cz>
* symtab.c (choose_better_psymab): New function.
(find_pc_sect_psymtab): Instead of returning first
matching psymtab choose the most specific one.
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.113.4.1
diff -u -p -r1.113.4.1 symtab.c
--- symtab.c 8 Aug 2003 14:06:26 -0000 1.113.4.1
+++ symtab.c 20 Oct 2003 09:56:31 -0000
@@ -673,13 +673,63 @@ init_sal (struct symtab_and_line *sal)
}
+/* Return psymtab with more specific address range. */
+
+static inline struct partial_symtab *
+choose_better_psymab (CORE_ADDR pc, struct partial_symtab *pst1,
+ struct partial_symtab *pst2)
+{
+ if (pst1 == NULL)
+ return pst2;
+
+ if (pst2 == NULL)
+ return pst1;
+
+ if ((pst1->texthigh - pst1->textlow) > (pst2->texthigh - pst2->textlow))
+ {
+ static CORE_ADDR last_pc = 0;
+
+ if (pc != last_pc && info_verbose)
+ {
+ char *objname[2];
+ struct partial_symtab *pst[2] = { pst1, pst2 };
+ int i;
+
+ for (i = 0; i < 2; i++)
+ {
+ if (pst[i]->objfile)
+ objname[i] = strrchr (pst[i]->objfile->name, '/')
+ ? strrchr (pst[i]->objfile->name, '/') + 1
+ : pst[i]->objfile->name;
+ else
+ objname[i] = "<unknown>";
+ }
+
+ printf_unfiltered ("More symtabs for PC=0x%lx found:\n"
+ "\tIgnoring %s (%s) PC=0x%lx...0x%lx\n"
+ "\tChoosing %s (%s) PC=0x%lx...0x%lx\n",
+ (unsigned long) pc,
+ pst1->filename, objname[0],
+ (unsigned long) pst1->textlow,
+ (unsigned long) pst1->texthigh,
+ pst2->filename, objname[1],
+ (unsigned long) pst2->textlow,
+ (unsigned long) pst2->texthigh);
+
+ last_pc = pc;
+ }
+ return pst2;
+ }
+ else
+ return pst1;
+}
/* Find which partial symtab on contains PC and SECTION. Return 0 if none. */
struct partial_symtab *
find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
{
- struct partial_symtab *pst;
+ struct partial_symtab *pst, *result = NULL;
struct objfile *objfile;
struct minimal_symbol *msymbol;
@@ -707,10 +757,16 @@ find_pc_sect_psymtab (CORE_ADDR pc, asec
function containing the PC. */
if (!(objfile->flags & OBJF_REORDERED) &&
section == 0) /* can't validate section this way */
- return (pst);
+ {
+ result = choose_better_psymab (pc, result, pst);
+ continue;
+ }
if (msymbol == NULL)
- return (pst);
+ {
+ result = choose_better_psymab (pc, result, pst);
+ continue;
+ }
for (tpst = pst; tpst != NULL; tpst = tpst->next)
{
@@ -722,13 +778,17 @@ find_pc_sect_psymtab (CORE_ADDR pc, asec
if (p != NULL
&& SYMBOL_VALUE_ADDRESS (p)
== SYMBOL_VALUE_ADDRESS (msymbol))
- return (tpst);
+ {
+ result = choose_better_psymab (pc, result, tpst);
+ }
}
}
- return (pst);
+
+ result = choose_better_psymab (pc, result, pst);
}
}
- return (NULL);
+
+ return (result);
}
/* Find which partial symtab contains PC. Return 0 if none.