Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Andreas Schwab <schwab@suse.de>
To: gdb-patches@sourceware.org
Subject: Fix some memory leaks in libunwind unwinder
Date: Wed, 06 Jun 2007 18:55:00 -0000	[thread overview]
Message-ID: <jer6oo9alq.fsf@sykes.suse.de> (raw)

This is a partial patch to fix the memory leaks in the libunwind
unwinder.  Fixing it completely requires some framework changes, but
this is already a big step forward.

Andreas.

2007-06-06  Andreas Schwab  <schwab@suse.de>

	* libunwind-frame.c (unw_destroy_addr_space_p): Define.
	(destroy_addr_space_name): Define.
	(libunwind_load): Get address of destroy_addr_space function.
	(libunwind_frame_cache): Destroy unw_addr_space_t object before
	returning unsuccessfully.
	(libunwind_frame_sniffer): Destroy unw_addr_space_t object before
	returning.
	(libunwind_sigtramp_frame_sniffer): Likewise.
	(libunwind_get_reg_special): Likewise.

--- libunwind-frame.c	01 Jun 2007 10:50:56 +0200	1.14
+++ libunwind-frame.c	06 Jun 2007 13:59:40 +0200	
@@ -53,6 +53,7 @@ static int (*unw_is_signal_frame_p) (unw
 static int (*unw_step_p) (unw_cursor_t *);
 static int (*unw_init_remote_p) (unw_cursor_t *, unw_addr_space_t, void *);
 static unw_addr_space_t (*unw_create_addr_space_p) (unw_accessors_t *, int);
+static void (*unw_destroy_addr_space_p) (unw_addr_space_t);
 static int (*unw_search_unwind_table_p) (unw_addr_space_t, unw_word_t, unw_dyn_info_t *,
 					 unw_proc_info_t *, int, void *);
 static unw_word_t (*unw_find_dyn_list_p) (unw_addr_space_t, unw_dyn_info_t *,
@@ -85,6 +86,7 @@ static char *is_signal_frame_name = STRI
 static char *step_name = STRINGIFY(UNW_OBJ(step));
 static char *init_remote_name = STRINGIFY(UNW_OBJ(init_remote));
 static char *create_addr_space_name = STRINGIFY(UNW_OBJ(create_addr_space));
+static char *destroy_addr_space_name = STRINGIFY(UNW_OBJ(destroy_addr_space));
 static char *search_unwind_table_name = STRINGIFY(UNW_OBJ(search_unwind_table));
 static char *find_dyn_list_name = STRINGIFY(UNW_OBJ(find_dyn_list));
 
@@ -170,13 +172,19 @@ libunwind_frame_cache (struct frame_info
 
   unw_init_remote_p (&cache->cursor, as, next_frame);
   if (unw_step_p (&cache->cursor) < 0)
-    return NULL;
+    {
+      unw_destroy_addr_space_p (as);
+      return NULL;
+    }
 
   /* To get base address, get sp from previous frame.  */
   uw_sp_regnum = descr->gdb2uw (SP_REGNUM);
   ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp);
   if (ret < 0)
-    error (_("Can't get libunwind sp register."));
+    {
+      unw_destroy_addr_space_p (as);
+      error (_("Can't get libunwind sp register."));
+    }
 
   cache->base = (CORE_ADDR)fp;
 
@@ -224,13 +232,17 @@ libunwind_frame_sniffer (struct frame_in
   ret = unw_init_remote_p (&cursor, as, next_frame);
 
   if (ret < 0)
-    return NULL;
+    {
+      unw_destroy_addr_space_p (as);
+      return NULL;
+    }
 
  
   /* Check to see if we have libunwind info by checking if we are in a 
      signal frame.  If it doesn't return an error, we have libunwind info
      and can use libunwind.  */
   ret = unw_is_signal_frame_p (&cursor);
+  unw_destroy_addr_space_p (as);
 
   if (ret < 0)
     return NULL;
@@ -382,10 +394,14 @@ libunwind_sigtramp_frame_sniffer (struct
   ret = unw_init_remote_p (&cursor, as, next_frame);
 
   if (ret < 0)
-    return NULL;
+    {
+      unw_destroy_addr_space_p (as);
+      return NULL;
+    }
 
   /* Check to see if we are in a signal frame.  */
   ret = unw_is_signal_frame_p (&cursor);
+  unw_destroy_addr_space_p (as);
   if (ret > 0)
     return &libunwind_frame_unwind;
 
@@ -422,7 +438,10 @@ libunwind_get_reg_special (struct gdbarc
 
   ret = unw_init_remote_p (&cursor, as, regcache);
   if (ret < 0)
-    return -1;
+    {
+      unw_destroy_addr_space_p (as);
+      return -1;
+    }
 
   uw_regnum = descr->gdb2uw (regnum);
 
@@ -437,6 +456,8 @@ libunwind_get_reg_special (struct gdbarc
       ptr = &intval;
     }
 
+  unw_destroy_addr_space_p (as);
+
   if (ret < 0)
     return -1;
 
@@ -485,6 +506,10 @@ libunwind_load (void)
   if (unw_create_addr_space_p == NULL)
     return 0;
 
+  unw_destroy_addr_space_p = dlsym (handle, destroy_addr_space_name);
+  if (unw_destroy_addr_space_p == NULL)
+    return 0;
+
   unw_search_unwind_table_p = dlsym (handle, search_unwind_table_name);
   if (unw_search_unwind_table_p == NULL)
     return 0;

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."


             reply	other threads:[~2007-06-06 18:55 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-06 18:55 Andreas Schwab [this message]
2007-06-06 19:07 ` Daniel Jacobowitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=jer6oo9alq.fsf@sykes.suse.de \
    --to=schwab@suse.de \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox