From 99f4bd72be700240b7a87c212698cbd78c01a4b9 Mon Sep 17 00:00:00 2001 From: Nikolai Nosov Date: Sun, 2 Feb 2020 14:58:53 +0400 Subject: [PATCH] fixed several bugs related to refactoring --- framework/context.cpp | 7 ------- framework/context.h | 1 - framework/dwarf_call_site.cpp | 14 +++++++++++++- framework/dwarf_call_site.h | 4 ++-- framework/dwarf_function.cpp | 16 +++++++++------- framework/dwarf_stack.cpp | 3 ++- framework/sysutils.cpp | 26 +++++++++++++++----------- 7 files changed, 41 insertions(+), 30 deletions(-) diff --git a/framework/context.cpp b/framework/context.cpp index 2a3a0e9..4b76d1f 100644 --- a/framework/context.cpp +++ b/framework/context.cpp @@ -73,11 +73,6 @@ bool print(pst_context* ctx, const char* fmt, ...) return nret; } -void log(SC_LogSeverity severity, const char* fmt, ...) -{ - pst_log(severity, fmt); -} - bool print_expr_block (pst_context* ctx, Dwarf_Op *exprs, int exprlen, Dwarf_Attribute* attr) { ctx->clean_print(ctx); @@ -162,14 +157,12 @@ void pst_context_init(pst_context* ctx, ucontext_t* hctx) // methods ctx->clean_print = clean_print; ctx->print = print; - ctx->log = log; ctx->print_expr = print_expr_block; ctx->print_registers = print_registers; ctx->print_stack = print_stack; // fields ctx->hcontext = hctx; - ctx->clean_print(ctx); ctx->base_addr = 0; ctx->sp = 0; ctx->cfa = 0; diff --git a/framework/context.h b/framework/context.h index f056fcb..c564b34 100644 --- a/framework/context.h +++ b/framework/context.h @@ -31,7 +31,6 @@ typedef struct pst_context { // methods void (*clean_print) (pst_context* ctx); bool (*print) (pst_context* ctx, const char* fmt, ...); - void (*log) (SC_LogSeverity severity, const char*fmt, ...); bool (*print_expr) (pst_context* ctx, Dwarf_Op *exprs, int exprlen, Dwarf_Attribute* attr); void (*print_registers) (pst_context* ctx, int from, int to); void (*print_stack) (pst_context* ctx, int max, uint64_t next_cfa); diff --git a/framework/dwarf_call_site.cpp b/framework/dwarf_call_site.cpp index 0bef02b..99f9283 100644 --- a/framework/dwarf_call_site.cpp +++ b/framework/dwarf_call_site.cpp @@ -150,7 +150,11 @@ bool site_handle_dwarf(pst_call_site* site, Dwarf_Die* child) void pst_call_site_init(pst_call_site* site, pst_context* c, uint64_t tgt, const char* orn) { // methods - + site->add_param = site_add_param; + site->del_param = site_del_param; + site->next_param = site_next_param; + site->find_param = site_find_param; + site->handle_dwarf = site_handle_dwarf; // fields list_node_init(&site->node); @@ -330,6 +334,14 @@ pst_call_site* storage_find_call_site(pst_call_site_storage* storage, pst_functi void pst_call_site_storage_init(pst_call_site_storage* storage, pst_context* ctx) { + // methods + storage->handle_dwarf = storage_handle_dwarf; + storage->add_call_site = storage_add_call_site; + storage->del_call_site = storage_del_call_site; + storage->find_call_site = storage_find_call_site; + storage->next_call_site = storage_next_call_site; + + // fields storage->ctx = ctx; list_head_init(&storage->call_sites); hash_head_init(&storage->cs_to_target); diff --git a/framework/dwarf_call_site.h b/framework/dwarf_call_site.h index 25c9d7d..bfea109 100644 --- a/framework/dwarf_call_site.h +++ b/framework/dwarf_call_site.h @@ -57,7 +57,7 @@ typedef struct pst_call_site { pst_call_site_param* (*add_param) (pst_call_site* site); void (*del_param) (pst_call_site* site, pst_call_site_param* p); pst_call_site_param* (*next_param) (pst_call_site* site, pst_call_site_param* p); - pst_call_site_param* (*find_param) (pst_call_site* site, pst_dwarf_expr& expr); + pst_call_site_param* (*find_param) (pst_call_site* site, pst_dwarf_expr* expr); bool (*handle_dwarf) (pst_call_site* site, Dwarf_Die* die); // fields @@ -78,7 +78,7 @@ typedef struct __pst_function pst_function; // ----------------------------------------------------------------------------------- typedef struct pst_call_site_storage { // methods - bool (*handle_dwarf) (pst_call_site_storage* storage, Dwarf_Die* result); + bool (*handle_dwarf) (pst_call_site_storage* storage, Dwarf_Die* result, pst_function* info); pst_call_site* (*add_call_site) (pst_call_site_storage* storage, uint64_t target, const char* origin); void (*del_call_site) (pst_call_site_storage* storage, pst_call_site* site); pst_call_site* (*find_call_site) (pst_call_site_storage* storage, pst_function* callee); diff --git a/framework/dwarf_function.cpp b/framework/dwarf_function.cpp index 5fb79e9..12626b8 100644 --- a/framework/dwarf_function.cpp +++ b/framework/dwarf_function.cpp @@ -167,7 +167,7 @@ bool fn_handle_lexical_block(pst_function* fn, Dwarf_Die* result) break; } case DW_TAG_GNU_call_site: - fn->call_sites.handle_dwarf(&fn->call_sites, &child); + fn->call_sites.handle_dwarf(&fn->call_sites, &child, fn); break; case DW_TAG_inlined_subroutine: pst_log(SEVERITY_DEBUG, "Skipping Lexical block tag 'DW_TAG_inlined_subroutine'"); @@ -192,8 +192,8 @@ bool fn_handle_dwarf(pst_function * fn, Dwarf_Die* d) // get list of offsets from process base address of continuous memory ranges where function's code resides // if(dwarf_haspc(d, pc)) { - dwarf_lowpc(d, &fn->lowpc); - dwarf_highpc(d, &fn->highpc); + dwarf_lowpc(d, &fn->lowpc); + dwarf_highpc(d, &fn->highpc); // } else { // pst_log(SEVERITY_ERROR, "Function's '%s' DIE hasn't definitions of memory offsets of function's code", dwarf_diename(d)); // return false; @@ -281,7 +281,7 @@ bool fn_handle_dwarf(pst_function * fn, Dwarf_Die* d) break; } case DW_TAG_GNU_call_site: - fn->call_sites.handle_dwarf(&fn->call_sites, &result); + fn->call_sites.handle_dwarf(&fn->call_sites, &result, fn); break; // case DW_TAG_inlined_subroutine: @@ -344,7 +344,7 @@ bool fn_unwind(pst_function* fn, Dwarf_Addr addr) if(str) { *str = 0; } - fn->name = function_name; + fn->name = pst_strdup(function_name); free(function_name); } @@ -352,6 +352,7 @@ bool fn_unwind(pst_function* fn, Dwarf_Addr addr) free(demangle_name); } + pst_log(SEVERITY_DEBUG, "func_name = %s", fn->name); return true; } @@ -407,8 +408,9 @@ bool fn_get_frame(pst_function* fn) } fn->ctx->print_expr(fn->ctx, cfa_ops, cfa_nops, NULL); + pst_decl(pst_dwarf_stack, stack, fn->ctx); - if(stack.calc(&stack, cfa_ops, cfa_nops, NULL, fn) && stack.get_value(&stack, &fn->cfa)) { + if(stack.calc(&stack, cfa_ops, cfa_nops, NULL, NULL) && stack.get_value(&stack, &fn->cfa)) { pst_log(SEVERITY_INFO, "Function %s(...): CFA expression: %s ==> %#lX", fn->name, fn->ctx->buff, fn->cfa); // setup context to match CFA for frame @@ -444,7 +446,7 @@ void pst_function_init(pst_function* fn, pst_context* _ctx, __pst_function* _par fn->die = NULL; fn->name = NULL; list_head_init(&fn->params); - pst_call_site_storage_init(&fn->call_sites, fn->ctx); + pst_call_site_storage_init(&fn->call_sites, _ctx); fn->sp = 0; fn->cfa = 0; diff --git a/framework/dwarf_stack.cpp b/framework/dwarf_stack.cpp index 0277b37..ed207e6 100644 --- a/framework/dwarf_stack.cpp +++ b/framework/dwarf_stack.cpp @@ -227,7 +227,7 @@ bool stack_calc(pst_dwarf_stack* st, Dwarf_Op *exprs, int expr_len, Dwarf_Attrib pst_dwarf_expr loc; pst_dwarf_expr_init(&loc); loc.setup(&loc, expr, exprlen); - pst_call_site_param* param = cs->find_param(cs, loc); + pst_call_site_param* param = cs->find_param(cs, &loc); pst_dwarf_expr_fini(&loc); if(!param) { pst_log(SEVERITY_ERROR, "Failed to find call site parameter while calculate DW_OP_GNU_entry_value expression"); @@ -261,6 +261,7 @@ void pst_dwarf_stack_init(pst_dwarf_stack* st, pst_context* ctx) { pst_assert(st && ctx); + list_head_init(&st->expr); list_head_init(&st->values); st->push = stack_push; st->push_value = stack_push_value; diff --git a/framework/sysutils.cpp b/framework/sysutils.cpp index 11883c7..ca73d65 100644 --- a/framework/sysutils.cpp +++ b/framework/sysutils.cpp @@ -42,18 +42,18 @@ bool handler_get_dwarf_function(pst_handler* h, pst_function* fun) Dwarf_Die* cdie = dwfl_module_addrdie(h->ctx.module, fun->pc, &mod_cu); //Dwarf_Die* cdie = dwfl_addrdie(dwfl, addr, &mod_bias); if(!cdie) { - h->ctx.log(SEVERITY_INFO, "Failed to find DWARF DIE for address %X", fun->pc); + pst_log(SEVERITY_INFO, "Failed to find DWARF DIE for address %X", fun->pc); return false; } if(dwarf_tag(cdie) != DW_TAG_compile_unit) { - h->ctx.log(SEVERITY_DEBUG, "Skipping non-cu die. DWARF tag: 0x%X, name = %s", dwarf_tag(cdie), dwarf_diename(cdie)); + pst_log(SEVERITY_DEBUG, "Skipping non-cu die. DWARF tag: 0x%X, name = %s", dwarf_tag(cdie), dwarf_diename(cdie)); return false; } Dwarf_Die result; if(dwarf_child(cdie, &result)) { - h->ctx.log(SEVERITY_ERROR, "No child DIE found for CU %s", dwarf_diename(cdie)); + pst_log(SEVERITY_ERROR, "No child DIE found for CU %s", dwarf_diename(cdie)); return false; } @@ -134,9 +134,9 @@ bool handler_handle_dwarf(pst_handler* h) Dl_info info; //for(pst_function* fun = next_function(NULL); fun; fun = next_function(fun)) { - for(pst_function* fun = (pst_function*)handler_last_function(h); fun; fun = h->prev_function(h, fun)) { + for(pst_function* fun = handler_last_function(h); fun; fun = h->prev_function(h, fun)) { dladdr((void*)(fun->pc), &info); - h->ctx.log(SEVERITY_INFO, "Function %s(...): module name: %s, base address: %p, CFA: %#lX", fun->name, info.dli_fname, info.dli_fbase, fun->parent ? fun->parent->sp : 0); + pst_log(SEVERITY_INFO, "Function %s(...): module name: %s, base address: %p, CFA: %#lX", fun->name, info.dli_fname, info.dli_fbase, fun->parent ? fun->parent->sp : 0); // setup context h->ctx.module = dwfl_addrmodule(h->ctx.dwfl, fun->pc); @@ -180,7 +180,7 @@ bool handler_unwind(pst_handler* h) #ifdef REG_RIP // x86_64 h->caller = (void *) h->ctx.hcontext->uc_mcontext.gregs[REG_RIP]; h->ctx.sp = h->ctx.hcontext->uc_mcontext.gregs[REG_RSP]; - h->ctx.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 caller_address = (void *) uctx->uc_mcontext.gregs[REG_EIP]); #elif defined(__arm__) @@ -201,7 +201,7 @@ bool handler_unwind(pst_handler* h) Dl_info info; dladdr(h->caller, &info); h->ctx.base_addr = (uint64_t)info.dli_fbase; - h->ctx.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", h->caller, info.dli_fbase, info.dli_fname); h->ctx.dwfl = dwfl_begin(&callbacks); if(h->ctx.dwfl == NULL) { @@ -221,19 +221,19 @@ bool handler_unwind(pst_handler* h) h->ctx.curr_frame = &h->ctx.cursor; 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)) { - h->ctx.log(SEVERITY_DEBUG, "Failed to get IP value"); + pst_log(SEVERITY_DEBUG, "Failed to get IP value"); continue; } unw_word_t sp; if(unw_get_reg(h->ctx.curr_frame, UNW_REG_SP, &sp)) { - h->ctx.log(SEVERITY_DEBUG, "Failed to get SP value"); + pst_log(SEVERITY_DEBUG, "Failed to get SP value"); continue; } if(h->addr == (uint64_t)h->caller) { skip = 0; } else if(skip) { - h->ctx.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, h->addr, sp); continue; } @@ -242,7 +242,7 @@ bool handler_unwind(pst_handler* h) pst_function* last = handler_last_function(h); pst_function* fn = h->add_function(h, NULL); fn->sp = sp; - h->ctx.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, h->addr, sp); if(!fn->unwind(fn, h->addr)) { h->del_function(fn); } else { @@ -251,6 +251,7 @@ bool handler_unwind(pst_handler* h) } //get_frame(fun); } + pst_log(SEVERITY_DEBUG, "fname = %s", fn->name); h->ctx.print(&h->ctx, "\n"); } @@ -265,6 +266,9 @@ void pst_handler_init(pst_handler* h, ucontext_t* hctx) h->del_function = handler_del_function; h->next_function = handler_next_function; h->prev_function = handler_prev_function; + h->handle_dwarf = handler_handle_dwarf; + h->print_dwarf = handler_print_dwarf; + h->unwind = handler_unwind; // fields pst_context_init(&h->ctx, hctx);