bfd_get_full_section_contents memory leak, plus
Tom Tromey
tromey@redhat.com
Wed Oct 17 03:12:00 GMT 2012
I noticed that bfd_get_full_section_contents has a memory leak. If you
set BFD_DECOMPRESS on the BFD, then use bfd_get_full_section_contents to
read a compressed section, the uncompressed section data will be
malloc'd and stored as section->contents -- but nothing ever frees this.
My fix for this (appended) is to allocate the uncompressed data on the
BFD's objalloc.
While looking into this I thought that it would be good to also set
SEC_IN_MEMORY in this case. I'm less sure of this change.
However, what I'd really like here is a way for gdb to better control
the caching. Right now, if gdb uses bfd_get_full_section_contents, then
in the compressed case we will have two copies of the section data in
memory -- needlessly wasteful.
Any suggestions for how you would like this to be done? I could either
add a new function, to be used in lieu of bfd_get_full_section_contents;
or remove the caching entirely; or make a new sentinel initialization
value for the 'ptr' argument to indicate that the function should always
cache the data and never make a copy.
There is a gdb patch series that is blocked on this, so I'd appreciate a
timely answer.
thanks,
Tom
* compress.c (bfd_get_full_section_contents): Use bfd_alloc
and bfd_release for allocate uncompressed data. Set
SEC_IN_MEMORY.
diff --git a/bfd/compress.c b/bfd/compress.c
index 52c884c..ca71261 100644
--- a/bfd/compress.c
+++ b/bfd/compress.c
@@ -220,7 +220,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
if (!ret)
goto fail_compressed;
- uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
+ uncompressed_buffer = (bfd_byte *) bfd_alloc (abfd, uncompressed_size);
if (uncompressed_buffer == NULL)
goto fail_compressed;
@@ -228,13 +228,14 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
uncompressed_buffer, uncompressed_size))
{
bfd_set_error (bfd_error_bad_value);
- free (uncompressed_buffer);
+ bfd_release (abfd, uncompressed_buffer);
fail_compressed:
free (compressed_buffer);
return FALSE;
}
free (compressed_buffer);
+ sec->flags |= SEC_IN_MEMORY;
sec->contents = uncompressed_buffer;
sec->compress_status = COMPRESS_SECTION_DONE;
/* Fall thru */
More information about the Binutils
mailing list