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 PR gdb/592, memory leaks in calls


This was interesting.  Things I learned while doing this:
  - our logic for making these symbol overload lists is very bad, and in
   fact could not work properly.  Fixed.
  - Doing so is very slow - not fixed.
  - Doing so is _ridiculously_ slow - because we kept demangling things. 
   Fixed.
  - We leaked memory - fixed.
  - libiberty's cplus_dem leaks memory - not fixed, but avoided and
   reported.
  - Our testsuite doesn't cover this function properly - not fixed, but
   I'll try to get to this.
  - It hasn't worked with GCC in quite some time, because DMGL_ARM has no
   business being specified for either v2 (I think) or v3 (definitely)
   mangled names; so we weren't actually demangling much.

I've committed this.  There's still a small memory leak but it's on the
order of 32 bytes instead of 128 MB.

Stephane, mind verifying that this works correctly for you?

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

2002-07-04  Daniel Jacobowitz  <drow@mvista.com>

	* symtab.c (remove_params): New function.
	(make_symbol_overload_list): Use it instead of cplus_demangle.
	(overload_list_add_symbol): Likewise.  Reorder.  Fix memory leak.

Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.63
diff -u -p -r1.63 symtab.c
--- symtab.c	12 May 2002 04:20:06 -0000	1.63
+++ symtab.c	4 Jul 2002 15:20:34 -0000
@@ -3719,6 +3719,49 @@ in_prologue (CORE_ADDR pc, CORE_ADDR fun
 
 
 /* Begin overload resolution functions */
+
+static char *
+remove_params (const char *demangled_name)
+{
+  const char *argp;
+  char *new_name;
+  int depth;
+
+  if (demangled_name == NULL)
+    return NULL;
+
+  /* First find the end of the arg list.  */
+  argp = strrchr (demangled_name, ')');
+  if (argp == NULL)
+    return NULL;
+
+  /* Back up to the beginning.  */
+  depth = 1;
+
+  while (argp-- > demangled_name)
+    {
+      if (*argp == ')')
+	depth ++;
+      else if (*argp == '(')
+	{
+	  depth --;
+
+	  if (depth == 0)
+	    break;
+	}
+    }
+  if (depth != 0)
+    internal_error (__FILE__, __LINE__,
+		    "bad demangled name %s\n", demangled_name);
+  while (argp[-1] == ' ' && argp > demangled_name)
+    argp --;
+
+  new_name = xmalloc (argp - demangled_name + 1);
+  memcpy (new_name, demangled_name, argp - demangled_name);
+  new_name[argp - demangled_name] = '\0';
+  return new_name;
+}
+
 /* Helper routine for make_symbol_completion_list.  */
 
 static int sym_return_val_size;
@@ -3734,14 +3777,21 @@ overload_list_add_symbol (struct symbol 
 {
   int newsize;
   int i;
+  char *sym_name;
+
+  /* If there is no type information, we can't do anything, so skip */
+  if (SYMBOL_TYPE (sym) == NULL)
+    return;
+
+  /* skip any symbols that we've already considered. */
+  for (i = 0; i < sym_return_val_index; ++i)
+    if (!strcmp (SYMBOL_NAME (sym), SYMBOL_NAME (sym_return_val[i])))
+      return;
 
   /* Get the demangled name without parameters */
-  char *sym_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ARM | DMGL_ANSI);
+  sym_name = remove_params (SYMBOL_DEMANGLED_NAME (sym));
   if (!sym_name)
-    {
-      sym_name = (char *) xmalloc (strlen (SYMBOL_NAME (sym)) + 1);
-      strcpy (sym_name, SYMBOL_NAME (sym));
-    }
+    return;
 
   /* skip symbols that cannot match */
   if (strcmp (sym_name, oload_name) != 0)
@@ -3750,14 +3800,7 @@ overload_list_add_symbol (struct symbol 
       return;
     }
 
-  /* If there is no type information, we can't do anything, so skip */
-  if (SYMBOL_TYPE (sym) == NULL)
-    return;
-
-  /* skip any symbols that we've already considered. */
-  for (i = 0; i < sym_return_val_index; ++i)
-    if (!strcmp (SYMBOL_NAME (sym), SYMBOL_NAME (sym_return_val[i])))
-      return;
+  xfree (sym_name);
 
   /* We have a match for an overload instance, so add SYM to the current list
    * of overload instances */
@@ -3768,8 +3811,6 @@ overload_list_add_symbol (struct symbol 
     }
   sym_return_val[sym_return_val_index++] = sym;
   sym_return_val[sym_return_val_index] = NULL;
-
-  xfree (sym_name);
 }
 
 /* Return a null-terminated list of pointers to function symbols that
@@ -3792,14 +3833,17 @@ make_symbol_overload_list (struct symbol
   /* Length of name.  */
   int oload_name_len = 0;
 
-  /* Look for the symbol we are supposed to complete on.
-   * FIXME: This should be language-specific.  */
+  /* Look for the symbol we are supposed to complete on.  */
 
-  oload_name = cplus_demangle (SYMBOL_NAME (fsym), DMGL_ARM | DMGL_ANSI);
+  oload_name = remove_params (SYMBOL_DEMANGLED_NAME (fsym));
   if (!oload_name)
     {
-      oload_name = (char *) xmalloc (strlen (SYMBOL_NAME (fsym)) + 1);
-      strcpy (oload_name, SYMBOL_NAME (fsym));
+      sym_return_val_size = 1;
+      sym_return_val = (struct symbol **) xmalloc (2 * sizeof (struct symbol *));
+      sym_return_val[0] = fsym;
+      sym_return_val[1] = NULL;
+
+      return sym_return_val;
     }
   oload_name_len = strlen (oload_name);
 


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