From 82f910ea9cce04b0faabfcd022d9d8949567541e Mon Sep 17 00:00:00 2001 From: Philippe Waroquiers Date: Sun, 1 Dec 2019 17:24:41 +0100 Subject: [PATCH] Fix leak of symbol name in block_symbol_cache A symbol not found inserted in the cache has a xstrdup-ed name that must be freed, but only the struct block_symbol_cache is freed. Add a function destroy_block_symbol_cache that clears all slots before releasing the cache. 2019-12-03 Philippe Waroquiers * symtab.c (symbol_cache_clear_slot): Move close to cleared type. (destroy_block_symbol_cache): New function. (symbol_cache:~symbol_cache) Call destroy_block_symbol_cache. (resize_symbol_cache): Likewise. --- gdb/ChangeLog | 6 ++++++ gdb/symtab.c | 41 +++++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 59825d3268f..5ece6883523 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2019-12-03 Philippe Waroquiers + * symtab.c (symbol_cache_clear_slot): Move close to cleared type. + (destroy_block_symbol_cache): New function. + (symbol_cache:~symbol_cache) Call destroy_block_symbol_cache. + (resize_symbol_cache): Likewise. + 2019-12-02 Tom Tromey * unittests/tui-selftests.c (run_tests): Make conditional. diff --git a/gdb/symtab.c b/gdb/symtab.c index 894a3230038..5c33fbf9ab7 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -183,6 +183,16 @@ struct symbol_cache_slot } value; }; +/* Clear out SLOT. */ + +static void +symbol_cache_clear_slot (struct symbol_cache_slot *slot) +{ + if (slot->state == SYMBOL_SLOT_NOT_FOUND) + xfree (slot->value.not_found.name); + slot->state = SYMBOL_SLOT_UNUSED; +} + /* Symbols don't specify global vs static block. So keep them in separate caches. */ @@ -201,6 +211,19 @@ struct block_symbol_cache struct symbol_cache_slot symbols[1]; }; +/* Clear all slots of BSC and free BSC. */ + +static void +destroy_block_symbol_cache (struct block_symbol_cache *bsc) +{ + if (bsc != nullptr) + { + for (unsigned int i = 0; i < bsc->size; i++) + symbol_cache_clear_slot (&bsc->symbols[i]); + xfree (bsc); + } +} + /* The symbol cache. Searching for symbols in the static and global blocks over multiple objfiles @@ -217,8 +240,8 @@ struct symbol_cache ~symbol_cache () { - xfree (global_symbols); - xfree (static_symbols); + destroy_block_symbol_cache (global_symbols); + destroy_block_symbol_cache (static_symbols); } struct block_symbol_cache *global_symbols = nullptr; @@ -1234,8 +1257,8 @@ resize_symbol_cache (struct symbol_cache *cache, unsigned int new_size) && new_size == 0)) return; - xfree (cache->global_symbols); - xfree (cache->static_symbols); + destroy_block_symbol_cache (cache->global_symbols); + destroy_block_symbol_cache (cache->static_symbols); if (new_size == 0) { @@ -1373,16 +1396,6 @@ symbol_cache_lookup (struct symbol_cache *cache, return {}; } -/* Clear out SLOT. */ - -static void -symbol_cache_clear_slot (struct symbol_cache_slot *slot) -{ - if (slot->state == SYMBOL_SLOT_NOT_FOUND) - xfree (slot->value.not_found.name); - slot->state = SYMBOL_SLOT_UNUSED; -} - /* Mark SYMBOL as found in SLOT. OBJFILE_CONTEXT is the current objfile when the lookup was done, or NULL if it's not needed to distinguish lookups (STATIC_BLOCK). It is *not* -- 2.30.2