From 70e39e14a90ff962f76ae4434d9f7c3692755603 Mon Sep 17 00:00:00 2001 From: Nikolai Nosov Date: Mon, 3 Feb 2020 17:55:33 +0400 Subject: [PATCH] refactor dwarf_handler --- framework/dwarf_call_site.h | 1 - framework/dwarf_function.h | 2 +- framework/{sysutils.cpp => dwarf_handler.cpp} | 34 ++++++++----------- framework/{sysutils.h => dwarf_handler.h} | 4 --- framework/dwarf_operations.h | 2 +- framework/dwarf_stack.cpp | 3 +- framework/dwarf_stack.h | 2 +- framework/dwarf_utils.h | 2 +- main.cpp | 2 +- 9 files changed, 22 insertions(+), 30 deletions(-) rename framework/{sysutils.cpp => dwarf_handler.cpp} (91%) rename framework/{sysutils.h => dwarf_handler.h} (80%) diff --git a/framework/dwarf_call_site.h b/framework/dwarf_call_site.h index d0f85e9..52f04eb 100644 --- a/framework/dwarf_call_site.h +++ b/framework/dwarf_call_site.h @@ -19,7 +19,6 @@ typedef struct pst_callee_info { Dwarf_Addr target; char* origin; - Dwarf_Addr pc; } pst_callee_info; diff --git a/framework/dwarf_function.h b/framework/dwarf_function.h index 9af6e85..390e3a4 100644 --- a/framework/dwarf_function.h +++ b/framework/dwarf_function.h @@ -39,8 +39,8 @@ typedef struct __pst_function { bool allocated; // whether this object was allocated or not } pst_function; void pst_function_init(pst_function* fn, pst_context* _ctx, __pst_function* _parent); -void pst_function_fini(pst_function* fn); pst_function* pst_function_new(pst_context* _ctx, __pst_function* _parent); +void pst_function_fini(pst_function* fn); bool pst_function_unwind(pst_function* fn, Dwarf_Addr addr); bool pst_function_handle_dwarf(pst_function * fn, Dwarf_Die* d); diff --git a/framework/sysutils.cpp b/framework/dwarf_handler.cpp similarity index 91% rename from framework/sysutils.cpp rename to framework/dwarf_handler.cpp index ebb20a1..ef44149 100644 --- a/framework/sysutils.cpp +++ b/framework/dwarf_handler.cpp @@ -16,7 +16,7 @@ #include #include -#include "sysutils.h" +#include "dwarf_handler.h" #include "logger/log.h" #define USE_LIBUNWIND @@ -177,8 +177,10 @@ Dwfl_Callbacks callbacks = { bool pst_handler_unwind(pst_handler* h) { h->ctx.clean_print(&h->ctx); + void* caller; // pointer to the function which requested to unwind stack + #ifdef REG_RIP // x86_64 - h->caller = (void *) h->ctx.hcontext->uc_mcontext.gregs[REG_RIP]; + caller = (void *) h->ctx.hcontext->uc_mcontext.gregs[REG_RIP]; h->ctx.sp = h->ctx.hcontext->uc_mcontext.gregs[REG_RSP]; pst_log(SEVERITY_DEBUG, "Original caller's SP: %#lX", h->ctx.sp); #elif defined(REG_EIP) // x86_32 @@ -199,9 +201,9 @@ bool pst_handler_unwind(pst_handler* h) //handle = dlopen(NULL, RTLD_NOW); Dl_info info; - dladdr(h->caller, &info); + dladdr(caller, &info); h->ctx.base_addr = (uint64_t)info.dli_fbase; - pst_log(SEVERITY_INFO, "Process address information: PC address: %p, base address: %p, object name: %s", h->caller, info.dli_fbase, info.dli_fname); + pst_log(SEVERITY_INFO, "Process address information: PC address: %p, base address: %p, object name: %s", caller, info.dli_fbase, info.dli_fname); h->ctx.dwfl = dwfl_begin(&callbacks); if(h->ctx.dwfl == NULL) { @@ -214,13 +216,15 @@ bool pst_handler_unwind(pst_handler* h) return false; } - h->ctx.print(&h->ctx, "Stack trace: caller = %p\n", h->caller); + h->ctx.print(&h->ctx, "Stack trace: caller = %p\n", caller); unw_getcontext(&h->ctx.context); unw_init_local(&h->ctx.cursor, &h->ctx.context); h->ctx.curr_frame = &h->ctx.cursor; + + Dwarf_Addr addr; // address of currently processed function for(int i = 0, skip = 1; unw_step(h->ctx.curr_frame) > 0; ++i) { - if(unw_get_reg(h->ctx.curr_frame, UNW_REG_IP, &h->addr)) { + if(unw_get_reg(h->ctx.curr_frame, UNW_REG_IP, &addr)) { pst_log(SEVERITY_DEBUG, "Failed to get IP value"); continue; } @@ -230,20 +234,20 @@ bool pst_handler_unwind(pst_handler* h) continue; } - if(h->addr == (uint64_t)h->caller) { + if(addr == (uint64_t)caller) { skip = 0; } else if(skip) { - pst_log(SEVERITY_DEBUG, "Skipping frame #%d: PC = %#lX, SP = %#lX", i, h->addr, sp); + pst_log(SEVERITY_DEBUG, "Skipping frame #%d: PC = %#lX, SP = %#lX", i, addr, sp); continue; } h->ctx.print(&h->ctx, "[%-2d] ", i); - h->ctx.module = dwfl_addrmodule(h->ctx.dwfl, h->addr); + h->ctx.module = dwfl_addrmodule(h->ctx.dwfl, addr); pst_function* last = last_function(h); pst_function* fn = add_function(h, NULL); fn->sp = sp; - pst_log(SEVERITY_DEBUG, "Analyze frame #%d: PC = %#lX, SP = %#lX", i, h->addr, sp); - if(!pst_function_unwind(fn, h->addr)) { + pst_log(SEVERITY_DEBUG, "Analyze frame #%d: PC = %#lX, SP = %#lX", i, addr, sp); + if(!pst_function_unwind(fn, addr)) { del_function(fn); } else { if(last) { @@ -260,19 +264,11 @@ bool pst_handler_unwind(pst_handler* h) void pst_handler_init(pst_handler* h, ucontext_t* hctx) { pst_context_init(&h->ctx, hctx); - h->handle = NULL; - h->addr = 0; - h->frame = NULL; - h->caller = NULL; list_head_init(&h->functions); } void pst_handler_fini(pst_handler* h) { - if(h->handle) { - dlclose(h->handle); - } - clear(h); pst_context_fini(&h->ctx); } diff --git a/framework/sysutils.h b/framework/dwarf_handler.h similarity index 80% rename from framework/sysutils.h rename to framework/dwarf_handler.h index 7b6ed23..06638e6 100644 --- a/framework/sysutils.h +++ b/framework/dwarf_handler.h @@ -33,10 +33,6 @@ typedef struct pst_handler { pst_context ctx; // context of unwinding - void* handle; // process handle - Dwarf_Addr addr; // address of currently processed function - Dwarf_Frame* frame; // currently processed stack frame - void* caller; // pointer to the function which requested to unwind stack list_head functions; // list of functions in stack frame } pst_handler; void pst_handler_init(pst_handler* h, ucontext_t* hctx); diff --git a/framework/dwarf_operations.h b/framework/dwarf_operations.h index 8f22385..233ee9f 100644 --- a/framework/dwarf_operations.h +++ b/framework/dwarf_operations.h @@ -4,8 +4,8 @@ #include "common.h" #include "list_head.h" -#include "sysutils.h" #include "context.h" +#include "dwarf_handler.h" #include "dwarf_stack.h" diff --git a/framework/dwarf_stack.cpp b/framework/dwarf_stack.cpp index ea7bbfe..51df01a 100644 --- a/framework/dwarf_stack.cpp +++ b/framework/dwarf_stack.cpp @@ -13,7 +13,8 @@ #include "list_head.h" #include "dwarf_stack.h" -#include "sysutils.h" + +#include "dwarf_handler.h" #include "dwarf_operations.h" // ----------------------------------------------------------------------------------- diff --git a/framework/dwarf_stack.h b/framework/dwarf_stack.h index 6c34b51..8ad6d97 100644 --- a/framework/dwarf_stack.h +++ b/framework/dwarf_stack.h @@ -13,7 +13,7 @@ #include "common.h" #include "allocator.h" #include "context.h" -#include "sysutils.h" +#include "dwarf_handler.h" // ----------------------------------------------------------------------------------- // DWARF Stack value diff --git a/framework/dwarf_utils.h b/framework/dwarf_utils.h index b70a5d9..fde682a 100644 --- a/framework/dwarf_utils.h +++ b/framework/dwarf_utils.h @@ -12,7 +12,7 @@ #include "dwarf_expression.h" #include "context.h" -#include "sysutils.h" +#include "dwarf_handler.h" typedef struct __reginfo { __reginfo() { diff --git a/main.cpp b/main.cpp index 3a8e733..a7b8a10 100644 --- a/main.cpp +++ b/main.cpp @@ -3,7 +3,7 @@ #include #include "context.h" -#include "sysutils.h" +#include "dwarf_handler.h" typedef enum { DEF_1 = 1,