aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2016-02-18 18:20:47 -0800
committerChristopher Ferris <cferris@google.com>2016-02-18 19:17:39 -0800
commitc5017fdb02aa2a9c87c059c9263e5dfc390da289 (patch)
tree2b2bf328da16c4e94a50c92105ebf004b8c6f142
parent2c0f916cac65c1a14e9a917452a430c490ff9620 (diff)
downloadlibunwind-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.c29
-rw-r--r--src/elfxx.h14
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)) {