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);
int regno = map->op_num - DW_OP_breg0;
unw_word_t ptr = 0;
unw_get_reg(&cursor, regno, &ptr);
unw_get_reg(&curr_frame, regno, &ptr);
//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);
} else if(map->op_num >= DW_OP_reg0 && map->op_num <= DW_OP_reg16) {
unw_word_t value = 0;
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);
} else if(map->op_num == DW_OP_GNU_entry_value) {
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);
int32_t off = decode_sleb128((unsigned char*)&exprs[i].number2);
unw_word_t ptr = 0;
unw_get_reg(&cursor, regno, &ptr);
unw_get_reg(&curr_frame, regno, &ptr);
//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);
} else if(map->op_num == DW_OP_regx) {
int32_t reg = decode_sleb128((unsigned char*)&exprs[i].number);
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);
} else if(map->op_num == DW_OP_addr) {
+4 -1
View File
@@ -14,6 +14,7 @@ typedef struct __pst_context {
offset = 0;
buff[0] = 0;
base_addr = 0;
has_nframe = false;
}
bool print(const char* fmt, ...);
@@ -22,7 +23,9 @@ typedef struct __pst_context {
ucontext_t* hcontext; // context of signal handler
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
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;
if(unw_get_reg(&stack->ctx->cursor, regno, &val)) {
if(unw_get_reg(&stack->ctx->curr_frame, regno, &val)) {
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
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;
}
@@ -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
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;
}
@@ -1067,7 +1067,7 @@ bool __dwarf_stack::get_value(uint64_t& value)
if(v->type & DWARF_TYPE_REGISTER_LOC) {
// dereference register location
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);
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)) {
unw_word_t value = 0;
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);
return false;
}
@@ -1107,8 +1107,6 @@ bool __dwarf_stack::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribu
Dwarf_Op *expr;
size_t exprlen;
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)) {
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;
+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
attr = dwarf_attr(result, DW_AT_location, &attr_mem);
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);
char str[1024];
@@ -453,7 +453,7 @@ bool __pst_function::print_dwarf()
bool __pst_function::handle_dwarf(Dwarf_Die* d)
{
die = d;
ctx->cursor = cursor;
ctx->curr_frame = cursor;
Dwarf_Attribute attr_mem;
Dwarf_Attribute* attr;
@@ -792,6 +792,13 @@ pst_function* __pst_handler::next_function(pst_function* f)
bool __pst_handler::handle_dwarf()
{
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);
}
@@ -858,9 +865,9 @@ bool __pst_handler::unwind()
unw_word_t pc;
unw_getcontext(&ctx.context);
unw_init_local(&ctx.cursor, &ctx.context);
while (unw_step(&ctx.cursor) > 0) {
unw_get_reg(&ctx.cursor, UNW_REG_IP, &pc);
unw_init_local(&ctx.curr_frame, &ctx.context);
while (unw_step(&ctx.curr_frame) > 0) {
unw_get_reg(&ctx.curr_frame, UNW_REG_IP, &pc);
if(pc == (uint64_t)caller) {
break;
} else {
@@ -887,8 +894,9 @@ bool __pst_handler::unwind()
ctx.print("[%-2d] ", idx);
Dwarf_Addr addr = (uintptr_t)array[i];
#else
ctx.has_nframe = false;
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;
ctx.print("[%-2d] ", idx);
#endif
@@ -900,7 +908,7 @@ bool __pst_handler::unwind()
}
ctx.print("\n");
#ifdef USE_LIBUNWIND
if(unw_step(&ctx.cursor) <= 0) {
if(unw_step(&ctx.curr_frame) <= 0) {
break;
}
#endif
+1 -1
View File
@@ -88,7 +88,7 @@ typedef struct __pst_function : public SC_ListNode {
lowpc = 0;
highpc = 0;
parent = NULL;
cursor = _ctx->cursor;
cursor = _ctx->curr_frame;
parent = _parent;
}