diff options
author | Christopher Ferris <cferris@google.com> | 2016-02-18 18:20:47 -0800 |
---|---|---|
committer | Christopher Ferris <cferris@google.com> | 2016-02-18 19:17:39 -0800 |
commit | c5017fdb02aa2a9c87c059c9263e5dfc390da289 (patch) | |
tree | 2b2bf328da16c4e94a50c92105ebf004b8c6f142 | |
parent | 2c0f916cac65c1a14e9a917452a430c490ff9620 (diff) | |
download | libunwind-brillo-m10-release.tar.gz |
Fix the caching of the compressed section.brillo-m10-releasebrillo-m10-dev
A previous change fixed a race condtion, but caused a big memory
leak of the compressed section data. In order to fix this, move
the caching of the compressed section at the point that we cache
the elf image data itself.
Bug: 27152097
Change-Id: I934916c527225274b29638a6afef7a5fba48a5af
-rw-r--r-- | src/elfxx.c | 29 | ||||
-rw-r--r-- | src/elfxx.h | 14 |
2 files changed, 17 insertions, 26 deletions
diff --git a/src/elfxx.c b/src/elfxx.c index 52f122ec..7fda0b72 100644 --- a/src/elfxx.c +++ b/src/elfxx.c @@ -557,27 +557,6 @@ elf_w (find_section_mapped) (struct elf_image *ei, const char* name, } return false; } - -static bool elf_w (extract_minidebuginfo_mapped) (struct elf_image *ei, uint8_t** data, size_t* size) { - if (ei->mini_debug_info_data != NULL) { - // Return cached result. - *data = ei->mini_debug_info_data; - *size = ei->mini_debug_info_size; - return true; - } - uint8_t *compressed = NULL; - size_t compressed_len; - if (elf_w (find_section_mapped) (ei, ".gnu_debugdata", &compressed, &compressed_len, NULL)) { - if (elf_w (xz_decompress) (compressed, compressed_len, data, size)) { - // Also cache the result for next time. - ei->mini_debug_info_data = *data; - ei->mini_debug_info_size = *size; - Debug (1, "Decompressed and cached .gnu_debugdata"); - return true; - } - } - return false; -} /* ANDROID support update. */ // Find the ELF image that contains IP and return the procedure name from @@ -598,13 +577,11 @@ HIDDEN bool elf_w (get_proc_name_in_image) ( // If the ELF image doesn't contain a match, look up the symbol in // the MiniDebugInfo. - uint8_t* mdi_data; - size_t mdi_size; - if (ei->mapped && elf_w (extract_minidebuginfo_mapped) (ei, &mdi_data, &mdi_size)) { + if (ei->mapped && ei->mini_debug_info_data) { struct elf_image mdi; mdi.mapped = true; - mdi.u.mapped.image = mdi_data; - mdi.u.mapped.size = mdi_size; + mdi.u.mapped.image = ei->mini_debug_info_data; + mdi.u.mapped.size = ei->mini_debug_info_size; mdi.valid = elf_w (valid_object_mapped) (&mdi); // The ELF file might have been relocated after the debug // information has been compresses and embedded. diff --git a/src/elfxx.h b/src/elfxx.h index 7af4d289..ff73ec51 100644 --- a/src/elfxx.h +++ b/src/elfxx.h @@ -183,6 +183,20 @@ static inline bool elf_map_cached_image ( map->ei.u.memory.as_arg = as_arg; map->ei.valid = elf_w (valid_object_memory) (&map->ei); } + } else { + // Try to cache the minidebuginfo data. + uint8_t *compressed = NULL; + size_t compressed_len; + if (elf_w (find_section_mapped) (&map->ei, ".gnu_debugdata", &compressed, + &compressed_len, NULL)) { + if (elf_w (xz_decompress) (compressed, compressed_len, + (uint8_t**) &map->ei.mini_debug_info_data, &map->ei.mini_debug_info_size)) { + Debug (1, "Decompressed and cached .gnu_debugdata"); + } else { + map->ei.mini_debug_info_data = NULL; + map->ei.mini_debug_info_size = 0; + } + } } unw_word_t load_base; if (map->ei.valid && elf_w (get_load_base) (&map->ei, map->offset, &load_base)) { |