[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