crash-stack: add symbol resolution for arm 30/103830/2
authorRafal Pietruch <r.pietruch@samsung.com>
Fri, 9 Dec 2016 14:04:03 +0000 (15:04 +0100)
committerRafal Pietruch <r.pietruch@samsung.com>
Tue, 13 Dec 2016 13:03:25 +0000 (14:03 +0100)
Change-Id: Iabb556a96907156a9b8775cdb25281dea560ce69

src/crash-stack/crash-stack-arm.c
src/crash-stack/crash-stack.c
src/crash-stack/crash-stack.h

index 29cb493f6307d86f8f1354bb2bec26f088e1dddd..7d82911937728f9db90374935eff72d3d8f90505 100644 (file)
@@ -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)
index b6dcde508e95e0f0008c3fb25996092d1b6b5987..5f2f3e2b95ea1eccdc28f2960a2afcc31325e6f9 100644 (file)
@@ -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);
index 3dfccef31f66c2d036750c2399dc33c78d767156..a70637326852c648ae773b69f450ffe4a43d8c0d 100644 (file)
@@ -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;