From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 422 invoked by alias); 23 Apr 2005 21:00:54 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 29398 invoked from network); 23 Apr 2005 20:59:54 -0000 Received: from unknown (HELO probity.mcc.ac.uk) (130.88.200.94) by sourceware.org with SMTP; 23 Apr 2005 20:59:54 -0000 Received: from compsoc.umu.man.ac.uk ([130.88.22.5] helo=mrtall.compsoc.man.ac.uk) by probity.mcc.ac.uk with esmtp (Exim 4.20) id 1DPRjD-000NRS-E4; Sat, 23 Apr 2005 21:59:51 +0100 Received: from moz by mrtall.compsoc.man.ac.uk with local (Exim 3.36 #1) id 1DPRjD-0000pg-00; Sat, 23 Apr 2005 21:59:51 +0100 Date: Sat, 23 Apr 2005 21:00:00 -0000 From: John Levon To: binutils@sources.redhat.com Cc: Philippe Elie Subject: [PATCH] Re: Multiple apparent leaks in dwarf2.c Message-ID: <20050423205950.GA3035@compsoc.man.ac.uk> References: <20050421060339.GA86259@compsoc.man.ac.uk> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20050421060339.GA86259@compsoc.man.ac.uk> User-Agent: Mutt/1.3.25i X-Url: http://www.movementarian.org/ X-Record: Graham Coxon - Happiness in Magazines X-Scanner: exiscan for exim4 (http://duncanthrax.net/exiscan/) *1DPRjD-000NRS-E4*qX3cAxYz.8U* X-SW-Source: 2005-04/txt/msg00644.txt.bz2 On Thu, Apr 21, 2005 at 07:03:40AM +0100, John Levon wrote: > These appear to indeed be valid leaks: the code is using the > non-objalloc'd bfd_realloc/bfd_malloc routines, but there's nothing to > clear up the debug info stash that I can see (binutils 2.15). Here's a patch that fixes up the issues I found in dwarf2.c. With this patch applied to CVS, our application is valgrind-clean. thanks, john Index: binutils-cvs/bfd/dwarf2.c =================================================================== RCS file: /cvs/src/src/bfd/dwarf2.c,v retrieving revision 1.65 diff -u -a -p -r1.65 dwarf2.c --- binutils-cvs/bfd/dwarf2.c 3 Apr 2005 20:36:37 -0000 1.65 +++ binutils-cvs/bfd/dwarf2.c 23 Apr 2005 20:45:22 -0000 @@ -447,11 +447,26 @@ read_abbrevs (bfd *abfd, bfd_uint64_t of { if ((cur_abbrev->num_attrs % ATTR_ALLOC_CHUNK) == 0) { + struct attr_abbrev *tmp; amt = cur_abbrev->num_attrs + ATTR_ALLOC_CHUNK; amt *= sizeof (struct attr_abbrev); - cur_abbrev->attrs = bfd_realloc (cur_abbrev->attrs, amt); - if (! cur_abbrev->attrs) - return 0; + tmp = bfd_realloc (cur_abbrev->attrs, amt); + if (! tmp) + { + size_t i; + + for (i = 0; i < ABBREV_HASH_SIZE; i++) + { + struct abbrev_info *abbrev = abbrevs[i]; + while (abbrev) + { + free (abbrev->attrs); + abbrev = abbrev->next; + } + } + return 0; + } + cur_abbrev->attrs = tmp; } cur_abbrev->attrs[cur_abbrev->num_attrs].name @@ -963,11 +978,16 @@ decode_line_info (struct comp_unit *unit if ((table->num_dirs % DIR_ALLOC_CHUNK) == 0) { + char **tmp; amt = table->num_dirs + DIR_ALLOC_CHUNK; amt *= sizeof (char *); - table->dirs = bfd_realloc (table->dirs, amt); - if (! table->dirs) - return 0; + tmp = bfd_realloc (table->dirs, amt); + if (! tmp) + { + free (table->dirs); + return 0; + } + table->dirs = tmp; } table->dirs[table->num_dirs++] = cur_dir; @@ -982,11 +1002,17 @@ decode_line_info (struct comp_unit *unit if ((table->num_files % FILE_ALLOC_CHUNK) == 0) { + struct fileinfo *tmp; amt = table->num_files + FILE_ALLOC_CHUNK; amt *= sizeof (struct fileinfo); - table->files = bfd_realloc (table->files, amt); - if (! table->files) - return 0; + tmp = bfd_realloc (table->files, amt); + if (! tmp) + { + free (table->files); + free (table->dirs); + return 0; + } + table->files = tmp; } table->files[table->num_files].name = cur_file; @@ -1073,11 +1099,18 @@ decode_line_info (struct comp_unit *unit line_ptr += bytes_read; if ((table->num_files % FILE_ALLOC_CHUNK) == 0) { + struct fileinfo *tmp; amt = table->num_files + FILE_ALLOC_CHUNK; amt *= sizeof (struct fileinfo); - table->files = bfd_realloc (table->files, amt); - if (! table->files) - return 0; + tmp = bfd_realloc (table->files, amt); + if (! tmp) + { + free (table->files); + free (table->dirs); + free (filename); + return 0; + } + table->files = tmp; } table->files[table->num_files].name = cur_file; table->files[table->num_files].dir = @@ -1094,6 +1127,9 @@ decode_line_info (struct comp_unit *unit default: (*_bfd_error_handler) (_("Dwarf Error: mangled line number section.")); bfd_set_error (bfd_error_bad_value); + free (filename); + free (table->files); + free (table->dirs); return 0; } break; @@ -2003,3 +2039,39 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd return FALSE; } + +void +_bfd_dwarf2_cleanup_debug_info(bfd *abfd) +{ + struct comp_unit *each; + struct dwarf2_debug *stash = elf_tdata (abfd)->dwarf2_find_line_info; + + if (! stash) + return; + + for (each = stash->all_comp_units; each; each = each->next_unit) + { + struct abbrev_info **abbrevs = each->abbrevs; + size_t i; + + for (i = 0; i < ABBREV_HASH_SIZE; i++) + { + struct abbrev_info *abbrev = abbrevs[i]; + while (abbrev) + { + free (abbrev->attrs); + abbrev = abbrev->next; + } + } + + if (each->line_table) + { + free (each->line_table->dirs); + free (each->line_table->files); + } + } + + free (stash->dwarf_abbrev_buffer); + free (stash->dwarf_line_buffer); + free (stash->dwarf_ranges_buffer); +} Index: binutils-cvs/bfd/elf-bfd.h =================================================================== RCS file: /cvs/src/src/bfd/elf-bfd.h,v retrieving revision 1.179 diff -u -a -p -r1.179 elf-bfd.h --- binutils-cvs/bfd/elf-bfd.h 4 Apr 2005 16:11:02 -0000 1.179 +++ binutils-cvs/bfd/elf-bfd.h 23 Apr 2005 20:45:25 -0000 @@ -1728,6 +1728,8 @@ extern int bfd_elf_link_record_local_dyn extern bfd_boolean _bfd_elf_close_and_cleanup (bfd *); +extern void _bfd_dwarf2_cleanup_debug_info + (bfd *); extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn (bfd *, arelent *, struct bfd_symbol *, void *, asection *, bfd *, char **); Index: binutils-cvs/bfd/elf.c =================================================================== RCS file: /cvs/src/src/bfd/elf.c,v retrieving revision 1.280 diff -u -a -p -r1.280 elf.c --- binutils-cvs/bfd/elf.c 21 Apr 2005 12:13:37 -0000 1.280 +++ binutils-cvs/bfd/elf.c 23 Apr 2005 20:45:36 -0000 @@ -6676,6 +6676,8 @@ _bfd_elf_close_and_cleanup (bfd *abfd) _bfd_elf_strtab_free (elf_shstrtab (abfd)); } + _bfd_dwarf2_cleanup_debug_info (abfd); + return _bfd_generic_close_and_cleanup (abfd); }