introduce parent frame

This commit is contained in:
2020-01-16 16:22:17 +04:00
parent ab58889d93
commit ba9db80f07
5 changed files with 29 additions and 20 deletions
+4 -4
View File
@@ -121,14 +121,14 @@ uint32_t __pst_context::print_expr_block (Dwarf_Op *exprs, int len, char* buff,
int32_t off = decode_sleb128((unsigned char*)&exprs[i].number); int32_t off = decode_sleb128((unsigned char*)&exprs[i].number);
int regno = map->op_num - DW_OP_breg0; int regno = map->op_num - DW_OP_breg0;
unw_word_t ptr = 0; unw_word_t ptr = 0;
unw_get_reg(&cursor, regno, &ptr); unw_get_reg(&curr_frame, regno, &ptr);
//ptr += off; //ptr += off;
offset += snprintf(buff + offset, buff_size - offset, "%s(*%s%s%d) reg_value: 0x%lX", map->op_name, unw_regname(regno), off >=0 ? "+" : "", off, ptr); offset += snprintf(buff + offset, buff_size - offset, "%s(*%s%s%d) reg_value: 0x%lX", map->op_name, unw_regname(regno), off >=0 ? "+" : "", off, ptr);
} else if(map->op_num >= DW_OP_reg0 && map->op_num <= DW_OP_reg16) { } else if(map->op_num >= DW_OP_reg0 && map->op_num <= DW_OP_reg16) {
unw_word_t value = 0; unw_word_t value = 0;
int regno = map->op_num - DW_OP_reg0; int regno = map->op_num - DW_OP_reg0;
unw_get_reg(&cursor, regno, &value); unw_get_reg(&curr_frame, regno, &value);
offset += snprintf(buff + offset, buff_size - offset, "%s(*%s) value: 0x%lX", map->op_name, unw_regname(regno), value); offset += snprintf(buff + offset, buff_size - offset, "%s(*%s) value: 0x%lX", map->op_name, unw_regname(regno), value);
} else if(map->op_num == DW_OP_GNU_entry_value) { } else if(map->op_num == DW_OP_GNU_entry_value) {
uint32_t value = decode_uleb128((unsigned char*)&exprs[i].number); uint32_t value = decode_uleb128((unsigned char*)&exprs[i].number);
@@ -155,14 +155,14 @@ uint32_t __pst_context::print_expr_block (Dwarf_Op *exprs, int len, char* buff,
uint32_t regno = decode_uleb128((unsigned char*)&exprs[i].number); uint32_t regno = decode_uleb128((unsigned char*)&exprs[i].number);
int32_t off = decode_sleb128((unsigned char*)&exprs[i].number2); int32_t off = decode_sleb128((unsigned char*)&exprs[i].number2);
unw_word_t ptr = 0; unw_word_t ptr = 0;
unw_get_reg(&cursor, regno, &ptr); unw_get_reg(&curr_frame, regno, &ptr);
//ptr += off; //ptr += off;
offset += snprintf(buff + offset, buff_size - offset, "%s(%s%s%d) reg_value = 0x%lX", map->op_name, unw_regname(regno), off >= 0 ? "+" : "", off, ptr); offset += snprintf(buff + offset, buff_size - offset, "%s(%s%s%d) reg_value = 0x%lX", map->op_name, unw_regname(regno), off >= 0 ? "+" : "", off, ptr);
} else if(map->op_num == DW_OP_regx) { } else if(map->op_num == DW_OP_regx) {
int32_t reg = decode_sleb128((unsigned char*)&exprs[i].number); int32_t reg = decode_sleb128((unsigned char*)&exprs[i].number);
unw_word_t value = 0; unw_word_t value = 0;
unw_get_reg(&cursor, reg, &value); unw_get_reg(&curr_frame, reg, &value);
offset += snprintf(buff + offset, buff_size - offset, "%s(%s) value = 0x%lX", map->op_name, unw_regname(reg), value); offset += snprintf(buff + offset, buff_size - offset, "%s(%s) value = 0x%lX", map->op_name, unw_regname(reg), value);
} else if(map->op_num == DW_OP_addr) { } else if(map->op_num == DW_OP_addr) {
+4 -1
View File
@@ -14,6 +14,7 @@ typedef struct __pst_context {
offset = 0; offset = 0;
buff[0] = 0; buff[0] = 0;
base_addr = 0; base_addr = 0;
has_nframe = false;
} }
bool print(const char* fmt, ...); bool print(const char* fmt, ...);
@@ -22,7 +23,9 @@ typedef struct __pst_context {
ucontext_t* hcontext; // context of signal handler ucontext_t* hcontext; // context of signal handler
unw_context_t context; // context of stack trace unw_context_t context; // context of stack trace
unw_cursor_t cursor; // currently examined frame of context unw_cursor_t curr_frame; // currently examined frame of context
unw_cursor_t next_frame; // caller frame
bool has_nframe; // has next frame or not
Dwarf_Addr base_addr; // base address where process loaded Dwarf_Addr base_addr; // base address where process loaded
char buff[8192]; // stack trace buffer char buff[8192]; // stack trace buffer
+5 -7
View File
@@ -785,7 +785,7 @@ bool dw_op_breg_x(dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, D
} }
unw_word_t val = 0; unw_word_t val = 0;
if(unw_get_reg(&stack->ctx->cursor, regno, &val)) { if(unw_get_reg(&stack->ctx->curr_frame, regno, &val)) {
return false; return false;
} }
@@ -829,7 +829,7 @@ bool dw_op_call_frame_cfa(dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Wor
{ {
// since in signal handler we are know SP value, just push it to DWARF stack // since in signal handler we are know SP value, just push it to DWARF stack
unw_word_t sp; unw_word_t sp;
if(unw_get_reg(&stack->ctx->cursor, UNW_REG_SP, &sp)) { if(unw_get_reg(&stack->ctx->curr_frame, UNW_REG_SP, &sp)) {
return false; return false;
} }
@@ -844,7 +844,7 @@ bool dw_op_fbreg(dwarf_stack* stack, const dwarf_op_map* map, Dwarf_Word op1, Dw
{ {
// since in signal handler we are know SP value, just use it as DW_AT_frame_base // since in signal handler we are know SP value, just use it as DW_AT_frame_base
unw_word_t sp; unw_word_t sp;
if(unw_get_reg(&stack->ctx->cursor, UNW_REG_SP, &sp)) { if(unw_get_reg(&stack->ctx->curr_frame, UNW_REG_SP, &sp)) {
return false; return false;
} }
@@ -1067,7 +1067,7 @@ bool __dwarf_stack::get_value(uint64_t& value)
if(v->type & DWARF_TYPE_REGISTER_LOC) { if(v->type & DWARF_TYPE_REGISTER_LOC) {
// dereference register location // dereference register location
uint64_t regno = value; uint64_t regno = value;
if(unw_get_reg(&ctx->cursor, regno, &value)) { if(unw_get_reg(&ctx->curr_frame, regno, &value)) {
ctx->log(SEVERITY_ERROR, "Failed to get value of register 0x%lX", regno); ctx->log(SEVERITY_ERROR, "Failed to get value of register 0x%lX", regno);
return false; return false;
} }
@@ -1091,7 +1091,7 @@ bool __dwarf_stack::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribu
if(v && (v->type & DWARF_TYPE_REGISTER_LOC)) { if(v && (v->type & DWARF_TYPE_REGISTER_LOC)) {
unw_word_t value = 0; unw_word_t value = 0;
uint64_t regno = *((uint64_t*)v->value); uint64_t regno = *((uint64_t*)v->value);
if(unw_get_reg(&ctx->cursor, regno, &value)) { if(unw_get_reg(&ctx->curr_frame, regno, &value)) {
ctx->log(SEVERITY_ERROR, "Failed to ger value of register 0x%lX", regno); ctx->log(SEVERITY_ERROR, "Failed to ger value of register 0x%lX", regno);
return false; return false;
} }
@@ -1107,8 +1107,6 @@ bool __dwarf_stack::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribu
Dwarf_Op *expr; Dwarf_Op *expr;
size_t exprlen; size_t exprlen;
if (dwarf_getlocation(&attr_mem, &expr, &exprlen) == 0) { if (dwarf_getlocation(&attr_mem, &expr, &exprlen) == 0) {
//offset += print_expr_block (expr, exprlen, buff + offset, buff_size - offset, &attr_mem);
//offset += snprintf(buff + offset, buff_size - offset, ") ");
if(!calc_expression(expr, exprlen, &attr_mem)) { if(!calc_expression(expr, exprlen, &attr_mem)) {
ctx->log(SEVERITY_ERROR, "Failed to calculate sub-expression for operation %s(0x%lX, 0x%lX)", map->op_name, exprs[i].number, exprs[i].number2); ctx->log(SEVERITY_ERROR, "Failed to calculate sub-expression for operation %s(0x%lX, 0x%lX)", map->op_name, exprs[i].number, exprs[i].number2);
return false; return false;
+15 -7
View File
@@ -301,7 +301,7 @@ bool __pst_parameter::handle_dwarf(Dwarf_Die* result)
// determine location of parameter in stack/heap or CPU registers // determine location of parameter in stack/heap or CPU registers
attr = dwarf_attr(result, DW_AT_location, &attr_mem); attr = dwarf_attr(result, DW_AT_location, &attr_mem);
Dwarf_Addr pc; Dwarf_Addr pc;
unw_get_reg(&ctx->cursor, UNW_REG_IP, &pc); unw_get_reg(&ctx->curr_frame, UNW_REG_IP, &pc);
dwarf_stack stack(ctx); dwarf_stack stack(ctx);
char str[1024]; char str[1024];
@@ -453,7 +453,7 @@ bool __pst_function::print_dwarf()
bool __pst_function::handle_dwarf(Dwarf_Die* d) bool __pst_function::handle_dwarf(Dwarf_Die* d)
{ {
die = d; die = d;
ctx->cursor = cursor; ctx->curr_frame = cursor;
Dwarf_Attribute attr_mem; Dwarf_Attribute attr_mem;
Dwarf_Attribute* attr; Dwarf_Attribute* attr;
@@ -792,6 +792,13 @@ pst_function* __pst_handler::next_function(pst_function* f)
bool __pst_handler::handle_dwarf() bool __pst_handler::handle_dwarf()
{ {
for(pst_function* fun = next_function(NULL); fun; fun = next_function(fun)) { for(pst_function* fun = next_function(NULL); fun; fun = next_function(fun)) {
ctx.curr_frame = fun->cursor;
if(fun->parent) {
ctx.next_frame = fun->parent->cursor;
ctx.has_nframe = true;
} else {
ctx.has_nframe = false;
}
get_dwarf_function(fun); get_dwarf_function(fun);
} }
@@ -858,9 +865,9 @@ bool __pst_handler::unwind()
unw_word_t pc; unw_word_t pc;
unw_getcontext(&ctx.context); unw_getcontext(&ctx.context);
unw_init_local(&ctx.cursor, &ctx.context); unw_init_local(&ctx.curr_frame, &ctx.context);
while (unw_step(&ctx.cursor) > 0) { while (unw_step(&ctx.curr_frame) > 0) {
unw_get_reg(&ctx.cursor, UNW_REG_IP, &pc); unw_get_reg(&ctx.curr_frame, UNW_REG_IP, &pc);
if(pc == (uint64_t)caller) { if(pc == (uint64_t)caller) {
break; break;
} else { } else {
@@ -887,8 +894,9 @@ bool __pst_handler::unwind()
ctx.print("[%-2d] ", idx); ctx.print("[%-2d] ", idx);
Dwarf_Addr addr = (uintptr_t)array[i]; Dwarf_Addr addr = (uintptr_t)array[i];
#else #else
ctx.has_nframe = false;
for (int i = skipped, idx = 0; true ; ++i, ++idx) { for (int i = skipped, idx = 0; true ; ++i, ++idx) {
unw_get_reg(&ctx.cursor, UNW_REG_IP, &pc); unw_get_reg(&ctx.curr_frame, UNW_REG_IP, &pc);
addr = pc; addr = pc;
ctx.print("[%-2d] ", idx); ctx.print("[%-2d] ", idx);
#endif #endif
@@ -900,7 +908,7 @@ bool __pst_handler::unwind()
} }
ctx.print("\n"); ctx.print("\n");
#ifdef USE_LIBUNWIND #ifdef USE_LIBUNWIND
if(unw_step(&ctx.cursor) <= 0) { if(unw_step(&ctx.curr_frame) <= 0) {
break; break;
} }
#endif #endif
+1 -1
View File
@@ -88,7 +88,7 @@ typedef struct __pst_function : public SC_ListNode {
lowpc = 0; lowpc = 0;
highpc = 0; highpc = 0;
parent = NULL; parent = NULL;
cursor = _ctx->cursor; cursor = _ctx->curr_frame;
parent = _parent; parent = _parent;
} }