refactor dwarf_handler
This commit is contained in:
@@ -19,7 +19,6 @@
|
|||||||
typedef struct pst_callee_info {
|
typedef struct pst_callee_info {
|
||||||
Dwarf_Addr target;
|
Dwarf_Addr target;
|
||||||
char* origin;
|
char* origin;
|
||||||
Dwarf_Addr pc;
|
|
||||||
} pst_callee_info;
|
} pst_callee_info;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ typedef struct __pst_function {
|
|||||||
bool allocated; // whether this object was allocated or not
|
bool allocated; // whether this object was allocated or not
|
||||||
} pst_function;
|
} pst_function;
|
||||||
void pst_function_init(pst_function* fn, pst_context* _ctx, __pst_function* _parent);
|
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);
|
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_unwind(pst_function* fn, Dwarf_Addr addr);
|
||||||
bool pst_function_handle_dwarf(pst_function * fn, Dwarf_Die* d);
|
bool pst_function_handle_dwarf(pst_function * fn, Dwarf_Die* d);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include <dwarf.h>
|
#include <dwarf.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "sysutils.h"
|
#include "dwarf_handler.h"
|
||||||
#include "logger/log.h"
|
#include "logger/log.h"
|
||||||
|
|
||||||
#define USE_LIBUNWIND
|
#define USE_LIBUNWIND
|
||||||
@@ -177,8 +177,10 @@ Dwfl_Callbacks callbacks = {
|
|||||||
bool pst_handler_unwind(pst_handler* h)
|
bool pst_handler_unwind(pst_handler* h)
|
||||||
{
|
{
|
||||||
h->ctx.clean_print(&h->ctx);
|
h->ctx.clean_print(&h->ctx);
|
||||||
|
void* caller; // pointer to the function which requested to unwind stack
|
||||||
|
|
||||||
#ifdef REG_RIP // x86_64
|
#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];
|
h->ctx.sp = h->ctx.hcontext->uc_mcontext.gregs[REG_RSP];
|
||||||
pst_log(SEVERITY_DEBUG, "Original caller's SP: %#lX", h->ctx.sp);
|
pst_log(SEVERITY_DEBUG, "Original caller's SP: %#lX", h->ctx.sp);
|
||||||
#elif defined(REG_EIP) // x86_32
|
#elif defined(REG_EIP) // x86_32
|
||||||
@@ -199,9 +201,9 @@ bool pst_handler_unwind(pst_handler* h)
|
|||||||
|
|
||||||
//handle = dlopen(NULL, RTLD_NOW);
|
//handle = dlopen(NULL, RTLD_NOW);
|
||||||
Dl_info info;
|
Dl_info info;
|
||||||
dladdr(h->caller, &info);
|
dladdr(caller, &info);
|
||||||
h->ctx.base_addr = (uint64_t)info.dli_fbase;
|
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);
|
h->ctx.dwfl = dwfl_begin(&callbacks);
|
||||||
if(h->ctx.dwfl == NULL) {
|
if(h->ctx.dwfl == NULL) {
|
||||||
@@ -214,13 +216,15 @@ bool pst_handler_unwind(pst_handler* h)
|
|||||||
return false;
|
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_getcontext(&h->ctx.context);
|
||||||
unw_init_local(&h->ctx.cursor, &h->ctx.context);
|
unw_init_local(&h->ctx.cursor, &h->ctx.context);
|
||||||
h->ctx.curr_frame = &h->ctx.cursor;
|
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) {
|
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");
|
pst_log(SEVERITY_DEBUG, "Failed to get IP value");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -230,20 +234,20 @@ bool pst_handler_unwind(pst_handler* h)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(h->addr == (uint64_t)h->caller) {
|
if(addr == (uint64_t)caller) {
|
||||||
skip = 0;
|
skip = 0;
|
||||||
} else if(skip) {
|
} 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
h->ctx.print(&h->ctx, "[%-2d] ", i);
|
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* last = last_function(h);
|
||||||
pst_function* fn = add_function(h, NULL);
|
pst_function* fn = add_function(h, NULL);
|
||||||
fn->sp = sp;
|
fn->sp = sp;
|
||||||
pst_log(SEVERITY_DEBUG, "Analyze frame #%d: PC = %#lX, SP = %#lX", i, h->addr, sp);
|
pst_log(SEVERITY_DEBUG, "Analyze frame #%d: PC = %#lX, SP = %#lX", i, addr, sp);
|
||||||
if(!pst_function_unwind(fn, h->addr)) {
|
if(!pst_function_unwind(fn, addr)) {
|
||||||
del_function(fn);
|
del_function(fn);
|
||||||
} else {
|
} else {
|
||||||
if(last) {
|
if(last) {
|
||||||
@@ -260,19 +264,11 @@ bool pst_handler_unwind(pst_handler* h)
|
|||||||
void pst_handler_init(pst_handler* h, ucontext_t* hctx)
|
void pst_handler_init(pst_handler* h, ucontext_t* hctx)
|
||||||
{
|
{
|
||||||
pst_context_init(&h->ctx, hctx);
|
pst_context_init(&h->ctx, hctx);
|
||||||
h->handle = NULL;
|
|
||||||
h->addr = 0;
|
|
||||||
h->frame = NULL;
|
|
||||||
h->caller = NULL;
|
|
||||||
list_head_init(&h->functions);
|
list_head_init(&h->functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pst_handler_fini(pst_handler* h)
|
void pst_handler_fini(pst_handler* h)
|
||||||
{
|
{
|
||||||
if(h->handle) {
|
|
||||||
dlclose(h->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
clear(h);
|
clear(h);
|
||||||
pst_context_fini(&h->ctx);
|
pst_context_fini(&h->ctx);
|
||||||
}
|
}
|
||||||
@@ -33,10 +33,6 @@
|
|||||||
|
|
||||||
typedef struct pst_handler {
|
typedef struct pst_handler {
|
||||||
pst_context ctx; // context of unwinding
|
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
|
list_head functions; // list of functions in stack frame
|
||||||
} pst_handler;
|
} pst_handler;
|
||||||
void pst_handler_init(pst_handler* h, ucontext_t* hctx);
|
void pst_handler_init(pst_handler* h, ucontext_t* hctx);
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "list_head.h"
|
#include "list_head.h"
|
||||||
#include "sysutils.h"
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
#include "dwarf_handler.h"
|
||||||
|
|
||||||
#include "dwarf_stack.h"
|
#include "dwarf_stack.h"
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
#include "list_head.h"
|
#include "list_head.h"
|
||||||
|
|
||||||
#include "dwarf_stack.h"
|
#include "dwarf_stack.h"
|
||||||
#include "sysutils.h"
|
|
||||||
|
#include "dwarf_handler.h"
|
||||||
#include "dwarf_operations.h"
|
#include "dwarf_operations.h"
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "allocator.h"
|
#include "allocator.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "sysutils.h"
|
#include "dwarf_handler.h"
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// DWARF Stack value
|
// DWARF Stack value
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#include "dwarf_expression.h"
|
#include "dwarf_expression.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "sysutils.h"
|
#include "dwarf_handler.h"
|
||||||
|
|
||||||
typedef struct __reginfo {
|
typedef struct __reginfo {
|
||||||
__reginfo() {
|
__reginfo() {
|
||||||
|
|||||||
Reference in New Issue
Block a user