use CFA derived from DWARF info instad of libunwind caller's SP since

libunwind don't show right SP for callers in shared objects
This commit is contained in:
2020-01-24 16:54:05 +04:00
parent 48f37ec3e8
commit 80018f8808
2 changed files with 6 additions and 1 deletions
+4 -1
View File
@@ -599,6 +599,7 @@ bool __pst_function::handle_dwarf(Dwarf_Die* d)
dwarf_diename(d), lowpc, highpc, pc - ctx->base_addr, info.start_ip, info.start_ip - ctx->base_addr); dwarf_diename(d), lowpc, highpc, pc - ctx->base_addr, info.start_ip, info.start_ip - ctx->base_addr);
ctx->print_registers(0x0, 0x10); ctx->print_registers(0x0, 0x10);
ctx->log(SEVERITY_INFO, "Function %s(...): CFA: %#lX %s", dwarf_diename(d), parent ? parent->sp : 0, ctx->buff); ctx->log(SEVERITY_INFO, "Function %s(...): CFA: %#lX %s", dwarf_diename(d), parent ? parent->sp : 0, ctx->buff);
ctx->log(SEVERITY_INFO, "Function %s(...): %s", dwarf_diename(d), ctx->buff);
// determine function's stack frame base // determine function's stack frame base
attr = dwarf_attr(die, DW_AT_frame_base, &attr_mem); attr = dwarf_attr(die, DW_AT_frame_base, &attr_mem);
@@ -799,6 +800,7 @@ bool __pst_handler::get_frame(pst_function* fun)
if(st.calc_expression(cfa_ops, cfa_nops, NULL) && st.get_value(v)) { if(st.calc_expression(cfa_ops, cfa_nops, NULL) && st.get_value(v)) {
//ctx.sp = v; //ctx.sp = v;
ctx.log(SEVERITY_INFO, "Function %s(...): CFA expression: %s ==> %#lX", fun->name.c_str(), str, v); ctx.log(SEVERITY_INFO, "Function %s(...): CFA expression: %s ==> %#lX", fun->name.c_str(), str, v);
fun->cfa = v;
} else { } else {
ctx.log(SEVERITY_ERROR, "Failed to calculate CFA expression"); ctx.log(SEVERITY_ERROR, "Failed to calculate CFA expression");
} }
@@ -921,13 +923,14 @@ bool __pst_handler::handle_dwarf()
ctx.log(SEVERITY_INFO, "Function %s(...): module name: %s, base address: %p, CFA: %#lX", fun->name.c_str(), info.dli_fname, info.dli_fbase, fun->parent ? fun->parent->sp : 0); ctx.log(SEVERITY_INFO, "Function %s(...): module name: %s, base address: %p, CFA: %#lX", fun->name.c_str(), info.dli_fname, info.dli_fbase, fun->parent ? fun->parent->sp : 0);
ctx.curr_frame = &fun->cursor; ctx.curr_frame = &fun->cursor;
ctx.sp = fun->sp; ctx.sp = fun->sp;
ctx.cfa = fun->parent ? fun->parent->sp : 0; //ctx.cfa = fun->parent ? fun->parent->sp : 0;
if(fun->parent) { if(fun->parent) {
ctx.next_frame = &fun->parent->cursor; ctx.next_frame = &fun->parent->cursor;
} else { } else {
ctx.next_frame = 0; ctx.next_frame = 0;
} }
get_frame(fun); get_frame(fun);
ctx.cfa = fun->cfa;
ctx.curr_frame = &fun->cursor; ctx.curr_frame = &fun->cursor;
ctx.next_frame = NULL; ctx.next_frame = NULL;
+2
View File
@@ -88,6 +88,7 @@ typedef struct __pst_function : public SC_ListNode {
memcpy(&cursor, _ctx->curr_frame, sizeof(cursor)); memcpy(&cursor, _ctx->curr_frame, sizeof(cursor));
parent = _parent; parent = _parent;
sp = 0; sp = 0;
cfa = 0;
} }
~__pst_function() { ~__pst_function() {
@@ -112,6 +113,7 @@ typedef struct __pst_function : public SC_ListNode {
SC_ListHead params; // function's parameters SC_ListHead params; // function's parameters
unw_word_t pc; // address between lowpc & highpc (plus base address offset). actually, currently executed command unw_word_t pc; // address between lowpc & highpc (plus base address offset). actually, currently executed command
unw_word_t sp; // SP register in function's frame unw_word_t sp; // SP register in function's frame
unw_word_t cfa;
unw_cursor_t cursor; // copy of stack state of the function unw_cursor_t cursor; // copy of stack state of the function
int line; // line in code where function is defined int line; // line in code where function is defined
std::string file; // file name (DWARF Compilation Unit) where function is defined std::string file; // file name (DWARF Compilation Unit) where function is defined