From 923b5369202b0fbcd5d482fefe8de1c9fe2148a1 Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Mon, 4 Nov 2013 14:38:07 -0800 Subject: [PATCH] Add corkscrew support for finding static symbols. Change-Id: Ie557a9b0efadece75e1accaa7e214fb559eb19e1 --- libbacktrace/Corkscrew.cpp | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/libbacktrace/Corkscrew.cpp b/libbacktrace/Corkscrew.cpp index 9daa75221..2be5930f6 100644 --- a/libbacktrace/Corkscrew.cpp +++ b/libbacktrace/Corkscrew.cpp @@ -86,15 +86,33 @@ bool CorkscrewCurrent::Unwind(size_t num_ignore_frames) { std::string CorkscrewCurrent::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) { *offset = 0; - // Get information about the current thread. Dl_info info; const backtrace_map_info_t* map_info = backtrace_obj_->FindMapInfo(pc); - const char* symbol_name = NULL; - if (map_info && dladdr((const void*)pc, &info) && info.dli_sname) { - *offset = pc - map_info->start - (uintptr_t)info.dli_saddr + (uintptr_t)info.dli_fbase; - symbol_name = info.dli_sname; - - return symbol_name; + if (map_info) { + if (dladdr((const void*)pc, &info)) { + if (info.dli_sname) { + *offset = pc - map_info->start - (uintptr_t)info.dli_saddr + (uintptr_t)info.dli_fbase; + return info.dli_sname; + } + } else { + // dladdr(3) didn't find a symbol; maybe it's static? Look in the ELF file... + symbol_table_t* symbol_table = load_symbol_table(map_info->name); + if (symbol_table) { + // First check if we can find the symbol using a relative pc. + std::string name; + const symbol_t* elf_symbol = find_symbol(symbol_table, pc - map_info->start); + if (elf_symbol) { + name = elf_symbol->name; + *offset = pc - map_info->start - elf_symbol->start; + } else if ((elf_symbol = find_symbol(symbol_table, pc)) != NULL) { + // Found the symbol using the absolute pc. + name = elf_symbol->name; + *offset = pc - elf_symbol->start; + } + free_symbol_table(symbol_table); + return name; + } + } } return ""; }