From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9627 invoked by alias); 6 Jun 2007 18:55:22 -0000 Received: (qmail 9615 invoked by uid 22791); 6 Jun 2007 18:55:21 -0000 X-Spam-Check-By: sourceware.org Received: from ns.suse.de (HELO mx1.suse.de) (195.135.220.2) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 06 Jun 2007 18:55:16 +0000 Received: from Relay2.suse.de (mail2.suse.de [195.135.221.8]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id EC65E120D1 for ; Wed, 6 Jun 2007 20:55:13 +0200 (CEST) From: Andreas Schwab To: gdb-patches@sourceware.org Subject: Fix some memory leaks in libunwind unwinder X-Yow: I'd like some JUNK FOOD... and then I want to be ALONE -- Date: Wed, 06 Jun 2007 18:55:00 -0000 Message-ID: User-Agent: Gnus/5.110006 (No Gnus v0.6) Emacs/22.0.97 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-06/txt/msg00071.txt.bz2 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 * 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."