introduce parent frame
This commit is contained in:
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user