mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-23 07:57:50 +00:00
pull out 'rich unwind' gathering path, which takes a 'concrete unwind'
and produces a full unwind with debug-info-derived inline frames
This commit is contained in:
+24
-75
@@ -4850,74 +4850,8 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
|
||||
{
|
||||
thread_color = df_rgba_from_entity(thread);
|
||||
}
|
||||
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
|
||||
|
||||
//- rjf: compute full call stack, including concrete & inline frames
|
||||
typedef struct DF_CallStackFrame DF_CallStackFrame;
|
||||
struct DF_CallStackFrame
|
||||
{
|
||||
void *regs;
|
||||
B32 is_inline_frame;
|
||||
String8 name;
|
||||
String8 type_string;
|
||||
};
|
||||
typedef struct DF_CallStackFrameNode DF_CallStackFrameNode;
|
||||
struct DF_CallStackFrameNode
|
||||
{
|
||||
DF_CallStackFrameNode *next;
|
||||
DF_CallStackFrame v;
|
||||
};
|
||||
DF_CallStackFrame *frames = 0;
|
||||
U64 frames_count = 0;
|
||||
{
|
||||
TG_Graph *graph = tg_graph_begin(bit_size_from_arch(arch)/8, 256);
|
||||
DF_CallStackFrameNode *first_frame = 0;
|
||||
DF_CallStackFrameNode *last_frame = 0;
|
||||
for(U64 unwind_idx = 0; unwind_idx < unwind.frames.count; unwind_idx += 1)
|
||||
{
|
||||
CTRL_UnwindFrame *unwind_f = &unwind.frames.v[unwind_idx];
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(arch, unwind_f->regs);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
|
||||
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
RDI_Parsed *rdi = di_rdi_from_key(scope, &dbgi_key, 0);
|
||||
RDI_Scope *scope = rdi_scope_from_voff(rdi, rip_voff);
|
||||
RDI_Procedure *procedure = rdi_procedure_from_scope(rdi, scope);
|
||||
RDI_TypeNode *procedure_type = rdi_element_from_name_idx(rdi, TypeNodes, procedure->type_idx);
|
||||
|
||||
// rjf: add frame for inlines
|
||||
for(RDI_Scope *s = scope; s->inline_site_idx != 0; s = rdi_element_from_name_idx(rdi, Scopes, s->parent_scope_idx))
|
||||
{
|
||||
RDI_InlineSite *site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx);
|
||||
RDI_TypeNode *site_type = rdi_element_from_name_idx(rdi, TypeNodes, site->type_idx);
|
||||
DF_CallStackFrameNode *n = push_array(scratch.arena, DF_CallStackFrameNode, 1);
|
||||
SLLQueuePush(first_frame, last_frame, n);
|
||||
n->v.regs = unwind_f->regs;
|
||||
n->v.is_inline_frame = 1;
|
||||
n->v.name.str = rdi_string_from_idx(rdi, site->name_string_idx, &n->v.name.size);
|
||||
n->v.type_string = tg_string_from_key(scratch.arena, graph, rdi, tg_key_ext(tg_kind_from_rdi_type_kind(site_type->kind), (U64)site->type_idx));
|
||||
frames_count += 1;
|
||||
}
|
||||
|
||||
// rjf: add frame for concrete frame
|
||||
DF_CallStackFrameNode *n = push_array(scratch.arena, DF_CallStackFrameNode, 1);
|
||||
SLLQueuePush(first_frame, last_frame, n);
|
||||
n->v.regs = unwind_f->regs;
|
||||
n->v.is_inline_frame = 0;
|
||||
n->v.name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &n->v.name.size);
|
||||
n->v.type_string = tg_string_from_key(scratch.arena, graph, rdi, tg_key_ext(tg_kind_from_rdi_type_kind(procedure_type->kind), (U64)procedure->type_idx));
|
||||
frames_count += 1;
|
||||
}
|
||||
frames = push_array(scratch.arena, DF_CallStackFrame, frames_count);
|
||||
{
|
||||
U64 idx = 0;
|
||||
for(DF_CallStackFrameNode *f = first_frame; f != 0; f = f->next)
|
||||
{
|
||||
MemoryCopyStruct(&frames[idx], &f->v);
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
CTRL_Unwind base_unwind = df_query_cached_unwind_from_thread(thread);
|
||||
DF_Unwind rich_unwind = df_unwind_from_ctrl_unwind(scratch.arena, scope, process, &base_unwind);
|
||||
|
||||
//- rjf: grab state
|
||||
typedef struct DF_CallStackViewState DF_CallStackViewState;
|
||||
@@ -4948,8 +4882,8 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
|
||||
scroll_list_params.flags = UI_ScrollListFlag_All;
|
||||
scroll_list_params.row_height_px = floor_f32(ui_top_font_size()*2.5f);
|
||||
scroll_list_params.dim_px = dim_2f32(rect);
|
||||
scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(3, frames_count));
|
||||
scroll_list_params.item_range = r1s64(0, frames_count+1);
|
||||
scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(3, rich_unwind.frames.count));
|
||||
scroll_list_params.item_range = r1s64(0, rich_unwind.frames.count+1);
|
||||
scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1;
|
||||
}
|
||||
UI_ScrollListSignal scroll_list_sig = {0};
|
||||
@@ -4982,7 +4916,9 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
|
||||
}
|
||||
|
||||
//- rjf: frame rows
|
||||
for(S64 row_num = visible_row_range.min; row_num <= visible_row_range.max && row_num <= frames_count; row_num += 1)
|
||||
for(S64 row_num = visible_row_range.min;
|
||||
row_num <= visible_row_range.max && row_num <= rich_unwind.frames.count;
|
||||
row_num += 1)
|
||||
{
|
||||
if(row_num == 0)
|
||||
{
|
||||
@@ -4992,12 +4928,25 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
|
||||
|
||||
// rjf: unpack frame
|
||||
U64 frame_idx = row_num-1;
|
||||
DF_CallStackFrame *frame = &frames[frame_idx];
|
||||
DF_UnwindFrame *frame = &rich_unwind.frames.v[frame_idx];
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(thread->arch, frame->regs);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
|
||||
B32 frame_valid = (rip_vaddr != 0);
|
||||
String8 symbol_name = frame->name;
|
||||
String8 symbol_type_string = frame->type_string;
|
||||
TG_Graph *graph = tg_graph_begin(bit_size_from_arch(thread->arch)/8, 256);
|
||||
String8 symbol_name = {0};
|
||||
String8 symbol_type_string = {0};
|
||||
if(frame->procedure != 0)
|
||||
{
|
||||
symbol_name.str = rdi_name_from_procedure(frame->rdi, frame->procedure, &symbol_name.size);
|
||||
RDI_TypeNode *type = rdi_element_from_name_idx(frame->rdi, TypeNodes, frame->procedure->type_idx);
|
||||
symbol_type_string = tg_string_from_key(scratch.arena, graph, frame->rdi, tg_key_ext(tg_kind_from_rdi_type_kind(type->kind), frame->procedure->type_idx));
|
||||
}
|
||||
if(frame->inline_site != 0)
|
||||
{
|
||||
symbol_name.str = rdi_string_from_idx(frame->rdi, frame->inline_site->name_string_idx, &symbol_name.size);
|
||||
RDI_TypeNode *type = rdi_element_from_name_idx(frame->rdi, TypeNodes, frame->inline_site->type_idx);
|
||||
symbol_type_string = tg_string_from_key(scratch.arena, graph, frame->rdi, tg_key_ext(tg_kind_from_rdi_type_kind(type->kind), frame->inline_site->type_idx));
|
||||
}
|
||||
|
||||
// rjf: build row
|
||||
if(frame_valid) UI_NamedTableVectorF("###callstack_%p_%I64x", view, frame_idx)
|
||||
@@ -5058,7 +5007,7 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
|
||||
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_Clip, "frame_%I64x", frame_idx);
|
||||
UI_Parent(box)
|
||||
{
|
||||
if(frame->is_inline_frame)
|
||||
if(frame->inline_site != 0)
|
||||
{
|
||||
UI_PrefWidth(ui_text_dim(10, 1))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user