This is the mail archive of the gdb-patches@sourceware.org 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] dangling cleanup in find_frame_funname


[I'm cc'ing Joel on this, since I believe this is the same assertion failure that he is seeing.]

While testing insight, I ran across the following assertion:

../../gdb/gdb/cleanups.c:264: internal-error: restore_my_cleanups: Assertion `*pmy_chain == SENTINEL_CLEANUP' failed.

This is caused by a dangling cleanup in find_frame_funname, which uses a (dangling) cleanup to free memory for the returned function name in some instances.

I've corrected this by simply requiring the caller to free any memory.

Unfortunately, I don't have a test case to trigger the failure. Perhaps Joel can describe an ada test case?

This patch definitely needs a few fresh eyeballs...

Keith

ChangeLog
2013-05-16  Keith Seitz  <keiths@redhat.com>

	* ada-lang.c (is_known_support_routine): Add explicit free of
	'func_name' from find_frame_funname.
	(ada_unhandled_exception_name_addr_from_raise): Likewise.
	* python/py-frame.c (frapy_name): Likewise for 'name'.
	* stack.c (find_frame_funname): Add comment explaining that
	funcp must be freed by the caller.
	Return copy of symbol names instead of pointers.
	(print_frame): Add a cleanup for 'funname' from
	find_frame_funname.
	* stack.h (find_frame_funname): Remove "const" from
	'funname' parameter.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index fa6db0f..12e5388 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -11105,7 +11105,7 @@ static int
 is_known_support_routine (struct frame_info *frame)
 {
   struct symtab_and_line sal;
-  const char *func_name;
+  char *func_name;
   enum language func_lang;
   int i;
   const char *fullname;
@@ -11152,9 +11152,13 @@ is_known_support_routine (struct frame_info *frame)
     {
       re_comp (known_auxiliary_function_name_patterns[i]);
       if (re_exec (func_name))
-        return 1;
+	{
+	  xfree (func_name);
+	  return 1;
+	}
     }
 
+  xfree (func_name);
   return 0;
 }
 
@@ -11210,13 +11214,17 @@ ada_unhandled_exception_name_addr_from_raise (void)
 
   while (fi != NULL)
     {
-      const char *func_name;
+      char *func_name;
       enum language func_lang;
 
       find_frame_funname (fi, &func_name, &func_lang, NULL);
       if (func_name != NULL
           && strcmp (func_name, data->exception_info->catch_exception_sym) == 0)
-        break; /* We found the frame we were looking for...  */
+	{
+	  xfree (func_name);
+	  break; /* We found the frame we were looking for...  */
+	}
+      xfree (func_name);
       fi = get_prev_frame (fi);
     }
 
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index e2eb9c5..312d26a 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -122,7 +122,7 @@ static PyObject *
 frapy_name (PyObject *self, PyObject *args)
 {
   struct frame_info *frame;
-  const char *name;
+  char *name = NULL;
   enum language lang;
   PyObject *result;
   volatile struct gdb_exception except;
@@ -133,10 +133,17 @@ frapy_name (PyObject *self, PyObject *args)
 
       find_frame_funname (frame, &name, &lang, NULL);
     }
+
+  if (except.reason < 0)
+    xfree (name);
+
   GDB_PY_HANDLE_EXCEPTION (except);
 
   if (name)
-    result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL);
+    {
+      result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL);
+      xfree (name);
+    }
   else
     {
       result = Py_None;
diff --git a/gdb/stack.c b/gdb/stack.c
index d10e9b4..a4b392e 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1004,10 +1004,10 @@ get_last_displayed_sal (struct symtab_and_line *sal)
 
 
 /* Attempt to obtain the FUNNAME, FUNLANG and optionally FUNCP of the function
-   corresponding to FRAME.  */
+   corresponding to FRAME.  FUNNAME needs to be freed by the caller.  */
 
 void
-find_frame_funname (struct frame_info *frame, const char **funname,
+find_frame_funname (struct frame_info *frame, char **funname,
 		    enum language *funlang, struct symbol **funcp)
 {
   struct symbol *func;
@@ -1055,12 +1055,12 @@ find_frame_funname (struct frame_info *frame, const char **funname,
 	  /* We also don't know anything about the function besides
 	     its address and name.  */
 	  func = 0;
-	  *funname = SYMBOL_PRINT_NAME (msymbol.minsym);
+	  *funname = xstrdup (SYMBOL_PRINT_NAME (msymbol.minsym));
 	  *funlang = SYMBOL_LANGUAGE (msymbol.minsym);
 	}
       else
 	{
-	  *funname = SYMBOL_PRINT_NAME (func);
+	  *funname = xstrdup (SYMBOL_PRINT_NAME (func));
 	  *funlang = SYMBOL_LANGUAGE (func);
 	  if (funcp)
 	    *funcp = func;
@@ -1075,8 +1075,8 @@ find_frame_funname (struct frame_info *frame, const char **funname,
 
 	      if (func_only)
 		{
+		  xfree (*funname);
 		  *funname = func_only;
-		  make_cleanup (xfree, func_only);
 		}
 	    }
 	}
@@ -1092,7 +1092,7 @@ find_frame_funname (struct frame_info *frame, const char **funname,
       msymbol = lookup_minimal_symbol_by_pc (pc);
       if (msymbol.minsym != NULL)
 	{
-	  *funname = SYMBOL_PRINT_NAME (msymbol.minsym);
+	  *funname = xstrdup (SYMBOL_PRINT_NAME (msymbol.minsym));
 	  *funlang = SYMBOL_LANGUAGE (msymbol.minsym);
 	}
     }
@@ -1105,7 +1105,7 @@ print_frame (struct frame_info *frame, int print_level,
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct ui_out *uiout = current_uiout;
-  const char *funname = NULL;
+  char *funname = NULL;
   enum language funlang = language_unknown;
   struct ui_file *stb;
   struct cleanup *old_chain, *list_chain;
@@ -1120,6 +1120,7 @@ print_frame (struct frame_info *frame, int print_level,
   old_chain = make_cleanup_ui_file_delete (stb);
 
   find_frame_funname (frame, &funname, &funlang, &func);
+  make_cleanup (xfree, funname);
 
   annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
 			gdbarch, pc);
diff --git a/gdb/stack.h b/gdb/stack.h
index 841ad43..4badf19 100644
--- a/gdb/stack.h
+++ b/gdb/stack.h
@@ -22,7 +22,7 @@
 
 void select_frame_command (char *level_exp, int from_tty);
 
-void find_frame_funname (struct frame_info *frame, const char **funname,
+void find_frame_funname (struct frame_info *frame, char **funname,
 			 enum language *funlang, struct symbol **funcp);
 
 typedef void (*iterate_over_block_arg_local_vars_cb) (const char *print_name,

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