From: Rafal Pietruch Date: Fri, 9 Dec 2016 14:04:03 +0000 (+0100) Subject: crash-stack: add symbol resolution for arm X-Git-Tag: submit/tizen_3.0/20161214.090816~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a356cada9c20a2af5b69b2c3e29cdc0b331cd3e0;p=platform%2Fcore%2Fsystem%2Fcrash-worker.git crash-stack: add symbol resolution for arm Change-Id: Iabb556a96907156a9b8775cdb25281dea560ce69 --- diff --git a/src/crash-stack/crash-stack-arm.c b/src/crash-stack/crash-stack-arm.c index 29cb493f..7d829119 100644 --- a/src/crash-stack/crash-stack-arm.c +++ b/src/crash-stack/crash-stack-arm.c @@ -37,6 +37,8 @@ #define REG_PC 15 #define REG_SPSR 16 +#define MAXPROCNAMELEN 512 + /** * @brief Important registers for unwinding stack on ARM */ @@ -89,31 +91,51 @@ void _crash_stack_set_ptrace_registers(void *regbuf) void _create_crash_stack(Dwfl *dwfl, Elf *core, pid_t pid, Mappings *mappings, Callstack *callstack) { // reimplemented based on libunwind tests/test-ptrace.c file - callstack->elems = 0; - unw_addr_space_t as = unw_create_addr_space(&_UPT_accessors, 0); - if (as) { - void *uptInfo = _UPT_create(pid); - if (uptInfo) { - unw_cursor_t cursor; - if (unw_init_remote(&cursor, as, uptInfo) >= 0) { - // MaxDeep as proposed in libunwind tests/test-ptrace.c file - // guard against bad unwind info in old libraries - static const int MaxDeep = 64; - int n; - for (n = 0; n < MaxDeep; ++n) { - unw_word_t ip; - if (unw_get_reg(&cursor, UNW_REG_IP, &ip) >= 0) { - callstack->tab[callstack->elems++] = ip; - } - int step = unw_step(&cursor); - if (step <= 0) - break; - } - } - _UPT_destroy(uptInfo); + unw_addr_space_t as = 0; + void *ui = 0; + do { + callstack->elems = 0; + + as = unw_create_addr_space(&_UPT_accessors, 0); + if (!as) + break; + + ui = _UPT_create(pid); + if (!ui) + break; + + unw_cursor_t cursor; + if (unw_init_remote(&cursor, as, ui) < 0) + break; + + char proc_name[MAXPROCNAMELEN]; + int n; + // MaxDeep as proposed in libunwind tests/test-ptrace.c file + // guard against bad unwind info in old libraries + static const int MaxDeep = 64; + for (n = 0; n < MaxDeep; ++n) { + + unw_word_t ip; + if (unw_get_reg(&cursor, UNW_REG_IP, &ip) < 0) + break; + callstack->tab[callstack->elems] = ip; + + proc_name[0] = '\0'; + unw_word_t off; + unw_get_proc_name(&cursor, proc_name, sizeof(proc_name), &off); + if (strlen(proc_name) > 0) + callstack->proc_name[callstack->elems] = strdup(proc_name); + + ++callstack->elems; + if (unw_step(&cursor) <= 0) + break; } + } while (0); + + if (ui) + _UPT_destroy(ui); + if (as) unw_destroy_addr_space(as); - } } void _crash_stack_print_regs(FILE* outputfile) diff --git a/src/crash-stack/crash-stack.c b/src/crash-stack/crash-stack.c index b6dcde50..5f2f3e2b 100644 --- a/src/crash-stack/crash-stack.c +++ b/src/crash-stack/crash-stack.c @@ -654,13 +654,16 @@ static void __print_callstack(Callstack *callstack, Dwfl *dwfl, Elf *core, pid_t fprintf(outputfile, "0x%016llx: ", (long long)callstack->tab[it]); else fprintf(outputfile, "0x%08x: ", (int32_t)callstack->tab[it]); + const char *symbol = callstack->proc_name[it]; + Dwfl_Module *module = dwfl_addrmodule(dwfl, callstack->tab[it]); if (module) { char *demangled_symbol = 0; - const char *symbol = dwfl_module_addrname(module, callstack->tab[it]); const char *fname = 0; const char *module_name = dwfl_module_info(module, NULL, NULL, NULL, NULL, NULL, &fname, NULL); char *symbol_from_elf = 0; + if (symbol == NULL) + symbol = dwfl_module_addrname(module, callstack->tab[it]); if (symbol == NULL) symbol = symbol_from_elf = __try_symbol_from_elfs(core, notes, callstack->tab[it], &fname); if (symbol != 0 && symbol[0] == '_' && symbol[1] == 'Z') { @@ -682,6 +685,8 @@ static void __print_callstack(Callstack *callstack, Dwfl *dwfl, Elf *core, pid_t free(symbol_from_elf); fprintf(outputfile, " from %s\n", fname != NULL ? fname : module_name); + } else if (symbol) { + fprintf(outputfile, "%s()", symbol); } else { fprintf(outputfile, "unknown function\n"); } @@ -702,7 +707,7 @@ static void __print_callstack(Callstack *callstack, Dwfl *dwfl, Elf *core, pid_t */ int main(int argc, char **argv) { - int c; + int c, i; pid_t pid = 0; const char *core_file_name; @@ -784,6 +789,8 @@ int main(int argc, char **argv) /* Unwind call stack */ Callstack callstack; + callstack.elems = 0; + memset(callstack.proc_name, 0, sizeof(callstack.proc_name)); _create_crash_stack(dwfl, core, pid, &mappings, &callstack); @@ -793,6 +800,10 @@ int main(int argc, char **argv) /* Print the results */ __print_callstack(&callstack, dwfl, core, pid, notes); + for (i = 0; i < callstack.elems; ++i) + if (callstack.proc_name[i]) + free(callstack.proc_name[i]); + /* Clean up */ dwfl_report_end(dwfl, NULL, NULL); dwfl_end(dwfl); diff --git a/src/crash-stack/crash-stack.h b/src/crash-stack/crash-stack.h index 3dfccef3..a7063732 100644 --- a/src/crash-stack/crash-stack.h +++ b/src/crash-stack/crash-stack.h @@ -33,6 +33,7 @@ */ struct Callstack { uintptr_t tab[MAX_CALLSTACK_LEN]; ///< storage for elements + char *proc_name[MAX_CALLSTACK_LEN]; ///< procedure name related to tab element with the same index size_t elems; ///< number of elements in the database }; typedef struct Callstack Callstack;