[SATYR PATCH 3/5] unwind: factor out build_id+offset resolution

Martin Milata mmilata at redhat.com
Wed Jul 24 13:55:06 UTC 2013


Signed-off-by: Martin Milata <mmilata at redhat.com>
---
 lib/core_unwind.c           | 41 +++++++++++++++++++++++++++++++++++++++++
 lib/core_unwind_elfutils.c  | 35 ++---------------------------------
 lib/core_unwind_libunwind.c | 33 +--------------------------------
 lib/internal_unwind.h       |  4 ++++
 4 files changed, 48 insertions(+), 65 deletions(-)

diff --git a/lib/core_unwind.c b/lib/core_unwind.c
index 4b491d3..02fe0e0 100644
--- a/lib/core_unwind.c
+++ b/lib/core_unwind.c
@@ -252,4 +252,45 @@ fail_free:
     return NULL;
 }
 
+struct sr_core_frame *
+resolve_frame(Dwfl *dwfl, Dwarf_Addr ip, bool minus_one)
+{
+    struct sr_core_frame *frame = sr_core_frame_new();
+    frame->address = frame->build_id_offset = (uint64_t)ip;
+
+    /* see dwfl_frame_state_pc for meaning of this parameter */
+    Dwarf_Addr ip_adjusted = ip - (minus_one ? 1 : 0);
+
+    Dwfl_Module *mod = dwfl_addrmodule(dwfl, ip_adjusted);
+    if (mod)
+    {
+        int ret;
+        const unsigned char *build_id_bits;
+        const char *filename, *funcname;
+        GElf_Addr bid_addr;
+        Dwarf_Addr start;
+
+        ret = dwfl_module_build_id(mod, &build_id_bits, &bid_addr);
+        if (ret > 0)
+        {
+            frame->build_id = sr_mallocz(2*ret + 1);
+            sr_bin2hex(frame->build_id, (const char *)build_id_bits, ret);
+        }
+
+        if (dwfl_module_info(mod, NULL, &start, NULL, NULL, NULL,
+                             &filename, NULL) != NULL)
+        {
+            frame->build_id_offset = ip - start;
+            if (filename)
+                frame->file_name = sr_strdup(filename);
+        }
+
+        funcname = dwfl_module_addrname(mod, (GElf_Addr)ip_adjusted);
+        if (funcname)
+            frame->function_name = sr_strdup(funcname);
+    }
+
+    return frame;
+}
+
 #endif /* !defined WITH_LIBDWFL && !defined WITH_LIBUNWIND */
diff --git a/lib/core_unwind_elfutils.c b/lib/core_unwind_elfutils.c
index 1c94ec1..2cd48c5 100644
--- a/lib/core_unwind_elfutils.c
+++ b/lib/core_unwind_elfutils.c
@@ -33,7 +33,6 @@
 static struct sr_core_thread *
 unwind_thread(Dwfl *dwfl, Dwfl_Frame_State *state, char **error_msg)
 {
-    int ret;
     struct sr_core_frame *head = NULL, *tail = NULL;
     pid_t tid = 0;
 
@@ -44,47 +43,17 @@ unwind_thread(Dwfl *dwfl, Dwfl_Frame_State *state, char **error_msg)
 
     while (state)
     {
-        Dwarf_Addr pc, pc_adjusted;
+        Dwarf_Addr pc;
         bool minus_one;
         if (!dwfl_frame_state_pc(state, &pc, &minus_one))
         {
             warn("Failed to obtain PC: %s", dwfl_errmsg(-1));
             break;
         }
-        pc_adjusted = pc - (minus_one ? 1 : 0);
 
-        struct sr_core_frame *frame = sr_core_frame_new();
-        frame->address = frame->build_id_offset = (uint64_t)pc;
+        struct sr_core_frame *frame = resolve_frame(dwfl, pc, minus_one);
         list_append(head, tail, frame);
 
-        Dwfl_Module *mod = dwfl_addrmodule(dwfl, (Dwarf_Addr)pc_adjusted);
-        if (mod)
-        {
-            const unsigned char *build_id_bits;
-            const char *filename, *funcname;
-            GElf_Addr bid_addr;
-            Dwarf_Addr start;
-
-            ret = dwfl_module_build_id(mod, &build_id_bits, &bid_addr);
-            if (ret > 0)
-            {
-                frame->build_id = sr_mallocz(2*ret + 1);
-                sr_bin2hex(frame->build_id, (const char *)build_id_bits, ret);
-            }
-
-            if (dwfl_module_info(mod, NULL, &start, NULL, NULL, NULL,
-                                 &filename, NULL) != NULL)
-            {
-                frame->build_id_offset = (Dwarf_Addr)pc - start;
-                if (filename)
-                    frame->file_name = sr_strdup(filename);
-            }
-
-            funcname = dwfl_module_addrname(mod, (GElf_Addr)pc_adjusted);
-            if (funcname)
-                frame->function_name = sr_strdup(funcname);
-        }
-
         /* Do not unwind below __libc_start_main. */
         if (0 == sr_strcmp0(frame->function_name, "__libc_start_main"))
             break;
diff --git a/lib/core_unwind_libunwind.c b/lib/core_unwind_libunwind.c
index 0f38a10..8f2de7c 100644
--- a/lib/core_unwind_libunwind.c
+++ b/lib/core_unwind_libunwind.c
@@ -61,38 +61,7 @@ unwind_thread(struct UCD_info *ui,
         if (ip == 0)
             break;
 
-        struct sr_core_frame *entry = sr_core_frame_new();
-        entry->address = entry->build_id_offset = ip;
-        entry->build_id = entry->file_name = NULL;
-        entry->function_name = NULL;
-
-        Dwfl_Module *mod = dwfl_addrmodule(dwfl, (Dwarf_Addr)ip);
-        if (mod)
-        {
-            const unsigned char *build_id_bits;
-            const char *filename, *funcname;
-            GElf_Addr bid_addr;
-            Dwarf_Addr start;
-
-            ret = dwfl_module_build_id(mod, &build_id_bits, &bid_addr);
-            if (ret > 0)
-            {
-                entry->build_id = sr_mallocz(2 * ret + 1);
-                sr_bin2hex(entry->build_id, (const char *)build_id_bits, ret);
-            }
-
-            if (dwfl_module_info(mod, NULL, &start, NULL, NULL, NULL,
-                                 &filename, NULL) != NULL)
-            {
-                entry->build_id_offset = (Dwarf_Addr)ip - start;
-                if (filename)
-                    entry->file_name = sr_strdup(filename);
-            }
-
-            funcname = dwfl_module_addrname(mod, (GElf_Addr)ip);
-            if (funcname)
-                entry->function_name = sr_strdup(funcname);
-        }
+        struct sr_core_frame *entry = resolve_frame(dwfl, ip, false);
 
         if (!entry->function_name)
         {
diff --git a/lib/internal_unwind.h b/lib/internal_unwind.h
index 48acc3b..70ac6db 100644
--- a/lib/internal_unwind.h
+++ b/lib/internal_unwind.h
@@ -92,4 +92,8 @@ open_coredump(const char *elf_file, const char *exe_file, char **error_msg);
 
 void
 core_handle_free(struct core_handle *ch);
+
+struct sr_core_frame *
+resolve_frame(Dwfl *dwfl, Dwarf_Addr ip, bool minus_one);
+
 #endif /* SATYR_INTERNAL_UNWIND_H */
-- 
1.7.11.7



More information about the Crash-catcher mailing list