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]

[PATCH] Fix coff symbol table reading problem for C code compiledby g++


I found a bug/problem in the symbol reading code in symtab.c in gdb-6.2.

The problem occurs when reading symbols from a coff object file produced
from a C source file compiled by g++ (not by gcc).
The particular compiler is m68k-palmos-gcc, which is still based on gcc-2.95.3.
See http://prc-tools.sourceforge.net.
I know this gcc version is very old, but I believe the problem may also exist
for other compilers.

When compiling normal C code by g++ it produces mangled function names.
The coff symbol reader first reads the function name and inserts this in
the minimal symbol table and in a demangled name hash table in
symtab_set_names(). When reading the '.bf' symbol the function name is inserted
in the real symbol table. This time the symbol is already in the hash table
in symtab_set_names() and symbol_find_demangled_name() is not called. A side
effect of symbol_find_demangled_name() is that it changes/corrects the
gsymbol->language field. In the case of 'C compiled by g++' it changes
it from language_auto to language_cplus.
Because symbol_find_demangled_name() is not called, the gsymbol->language field
in the full symbol table stays set to language_auto.
This causes all kinds of problems when looking up symbols later, since the
stored name is the mangled name and the demangled name is empty: the symbol is
not found in the full symbol table and the code falls back on the minimal
symbol table or e.g. function names.
When trying to set a breakpoint on a function, the breakpoint is then set
on the last line of the preceding function.

I have applied the following fix to ensure that symbol_find_demangled_name()
is also called in this case. It is working for me. I do not know
if something else is needed for other languages/compilers/compiler
versions.
The patch below is against the 6.2 code.
===============================================================================
--- symtab.c.orig	2004-07-08 07:18:27.000000000 -0400
+++ symtab.c	2004-08-12 19:13:12.920308800 -0400
@@ -524,6 +524,7 @@ symbol_set_names (struct general_symbol_
   const char *lookup_name;
   /* The length of lookup_name.  */
   int lookup_len;
+  char *demangled_name = NULL;

   if (objfile->demangled_names_hash == NULL)
     create_demangled_names_hash (objfile);
@@ -569,9 +570,10 @@ symbol_set_names (struct general_symbol_
   /* If this name is not in the hash table, add it.  */
   if (*slot == NULL)
     {
-      char *demangled_name = symbol_find_demangled_name (gsymbol,
-							 linkage_name_copy);
-      int demangled_len = demangled_name ? strlen (demangled_name) : 0;
+      int demangled_len;
+
+      demangled_name = symbol_find_demangled_name (gsymbol, linkage_name_copy);
+      demangled_len = demangled_name ? strlen (demangled_name) : 0;

       /* If there is a demangled name, place it right after the mangled name.
 	 Otherwise, just place a second zero byte after the end of the mangled
@@ -582,7 +584,6 @@ symbol_set_names (struct general_symbol_
       if (demangled_name != NULL)
 	{
 	  memcpy (*slot + lookup_len + 1, demangled_name, demangled_len + 1);
-	  xfree (demangled_name);
 	}
       else
 	(*slot)[lookup_len + 1] = '\0';
@@ -590,10 +591,20 @@ symbol_set_names (struct general_symbol_

   gsymbol->name = *slot + lookup_len - len;
   if ((*slot)[lookup_len + 1] != '\0')
-    gsymbol->language_specific.cplus_specific.demangled_name
-      = &(*slot)[lookup_len + 1];
+    {
+      gsymbol->language_specific.cplus_specific.demangled_name
+        = &(*slot)[lookup_len + 1];
+      /* In case we found the demangled name in the hash table we still have
+         to call SYMBOL_FIND_DEMANGLED_NAME in order to set the
+         gsymbol->language field correctly. */
+      if (demangled_name == NULL)
+	demangled_name = symbol_find_demangled_name (gsymbol,
+						     linkage_name_copy);
+    }
   else
     gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+
+  if (demangled_name != NULL) xfree (demangled_name);
 }

 /* Initialize the demangled name of GSYMBOL if possible.  Any required space
===============================================================================

Please let me know if I should submit this as a PR and/or if there is a
better fix for this problem.

Ton van Overbeek


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