This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] Find the most specific symtab


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. 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]