dedup multiple unwinder paths; just collapse down to using the ctrl one

This commit is contained in:
Ryan Fleury
2024-02-05 14:06:06 -08:00
parent ef317c1ffc
commit 95b8b71322
5 changed files with 32 additions and 151 deletions
+1 -1
View File
@@ -548,7 +548,7 @@ internal U64 ctrl_tls_root_vaddr_from_thread(CTRL_MachineID machine_id, CTRL_Han
internal CTRL_Handle ctrl_module_from_process_vaddr(CTRL_MachineID machine_id, CTRL_Handle process, U64 vaddr);
//- rjf: unwinding
internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_MachineID machine_id, CTRL_Handle thread);
internal CTRL_Unwind ctrl_unwind_from_process_thread(Arena *arena, CTRL_MachineID machine_id, CTRL_Handle process, CTRL_Handle thread);
//- rjf: name -> register/alias hash tables, for eval
internal EVAL_String2NumMap *ctrl_string2reg_from_arch(Architecture arch);
+17 -119
View File
@@ -3605,113 +3605,11 @@ df_architecture_from_entity(DF_Entity *entity)
return entity->arch;
}
internal DF_Unwind
internal CTRL_Unwind
df_push_unwind_from_thread(Arena *arena, DF_Entity *thread)
{
ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1);
DBGI_Scope *scope = dbgi_scope_open();
Architecture arch = df_architecture_from_entity(thread);
U64 arch_reg_block_size = regs_block_size_from_architecture(arch);
DF_Unwind unwind = {0};
unwind.error = 1;
switch(arch)
{
default:{}break;
case Architecture_x64:
{
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
// rjf: grab initial register block
void *regs_block = push_array(scratch.arena, U8, arch_reg_block_size);
B32 regs_block_good = 0;
{
void *regs_raw = ctrl_reg_block_from_thread(thread->ctrl_machine_id, thread->ctrl_handle);
if(regs_raw != 0)
{
MemoryCopy(regs_block, regs_raw, arch_reg_block_size);
regs_block_good = 1;
}
}
// rjf: grab initial memory view
B32 stack_memview_good = 0;
UNW_MemView stack_memview = {0};
if(regs_block_good)
{
U64 stack_base_unrounded = thread->stack_base;
U64 stack_top_unrounded = regs_rsp_from_arch_block(arch, regs_block);
U64 stack_base = AlignPow2(stack_base_unrounded, KB(4));
U64 stack_top = AlignDownPow2(stack_top_unrounded, KB(4));
U64 stack_size = stack_base - stack_top;
if(stack_base >= stack_top)
{
String8 stack_memory = {0};
stack_memory.str = push_array_no_zero(scratch.arena, U8, stack_size);
stack_memory.size = ctrl_process_read(process->ctrl_machine_id, process->ctrl_handle, r1u64(stack_top, stack_top+stack_size), stack_memory.str);
if(stack_memory.size != 0)
{
stack_memview_good = 1;
stack_memview.data = stack_memory.str;
stack_memview.addr_first = stack_top;
stack_memview.addr_opl = stack_base;
}
}
}
// rjf: loop & unwind
UNW_MemView memview = stack_memview;
if(stack_memview_good) for(;;)
{
unwind.error = 0;
// rjf: regs -> rip*module*binary
U64 rip = regs_rip_from_arch_block(arch, regs_block);
DF_Entity *module = df_module_from_process_vaddr(process, rip);
DF_Entity *binary = df_binary_file_from_module(module);
// rjf: cancel on 0 rip
if(rip == 0)
{
break;
}
// rjf: binary -> all the binary info
String8 binary_full_path = df_full_path_from_entity(scratch.arena, binary);
DBGI_Parse *dbgi = dbgi_parse_from_exe_path(scope, binary_full_path, 0);
String8 binary_data = str8((U8 *)dbgi->exe_base, dbgi->exe_props.size);
// rjf: valid step -> push frame
DF_UnwindFrame *frame = push_array(arena, DF_UnwindFrame, 1);
frame->rip = rip;
frame->regs = push_array_no_zero(arena, U8, arch_reg_block_size);
MemoryCopy(frame->regs, regs_block, arch_reg_block_size);
SLLQueuePush(unwind.first, unwind.last, frame);
unwind.count += 1;
// rjf: unwind one step
UNW_Result unwind_step = unw_pe_x64(binary_data, &dbgi->pe, df_base_vaddr_from_module(module), &memview, (UNW_X64_Regs *)regs_block);
// rjf: cancel on bad step
if(unwind_step.dead != 0)
{
break;
}
if(unwind_step.missed_read != 0)
{
unwind.error = 1;
break;
}
if(unwind_step.stack_pointer == 0)
{
break;
}
}
}break;
}
dbgi_scope_close(scope);
scratch_end(scratch);
ProfEnd();
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
CTRL_Unwind unwind = ctrl_unwind_from_process_thread(arena, thread->ctrl_machine_id, process->ctrl_handle, thread->ctrl_handle);
return unwind;
}
@@ -3729,9 +3627,9 @@ df_rip_from_thread_unwind(DF_Entity *thread, U64 unwind_count)
U64 result = df_rip_from_thread(thread);
if(unwind_count != 0)
{
DF_Unwind unwind = df_push_unwind_from_thread(scratch.arena, thread);
CTRL_Unwind unwind = df_push_unwind_from_thread(scratch.arena, thread);
U64 unwind_idx = 0;
for(DF_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next, unwind_idx += 1)
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next, unwind_idx += 1)
{
if(unwind_count == unwind_idx)
{
@@ -4186,14 +4084,14 @@ df_eval_from_string(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_
DF_Entity *thread = df_entity_from_handle(ctrl_ctx->thread);
DF_Entity *process = thread->parent;
U64 unwind_count = ctrl_ctx->unwind_count;
DF_Unwind unwind = df_query_cached_unwind_from_thread(thread);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
Architecture arch = df_architecture_from_entity(thread);
U64 reg_size = regs_block_size_from_architecture(arch);
U64 thread_unwind_ip_vaddr = 0;
void *thread_unwind_regs_block = push_array(scratch.arena, U8, reg_size);
{
U64 idx = 0;
for(DF_UnwindFrame *f = unwind.first; f != 0; f = f->next, idx += 1)
for(CTRL_UnwindFrame *f = unwind.first; f != 0; f = f->next, idx += 1)
{
if(idx == unwind_count)
{
@@ -4339,11 +4237,11 @@ df_value_mode_eval_from_eval(TG_Graph *graph, RADDBG_Parsed *rdbg, DF_CtrlCtx *c
TG_Key type_key = eval.type_key;
U64 type_byte_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, type_key);
U64 reg_off = eval.offset;
DF_Unwind unwind = df_query_cached_unwind_from_thread(thread);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
if(unwind.first != 0)
{
U64 unwind_idx = 0;
for(DF_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next, unwind_idx += 1)
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next, unwind_idx += 1)
{
if(unwind_idx == ctrl_ctx->unwind_count && frame->regs != 0)
{
@@ -4858,7 +4756,7 @@ df_commit_eval_value(TG_Graph *graph, RADDBG_Parsed *rdbg, DF_CtrlCtx *ctrl_ctx,
}break;
case EVAL_EvalMode_Reg:
{
DF_Unwind unwind = df_query_cached_unwind_from_thread(thread);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
Architecture arch = df_architecture_from_entity(thread);
U64 reg_block_size = regs_block_size_from_architecture(arch);
if(unwind.first != 0 &&
@@ -6232,11 +6130,11 @@ df_push_active_target_list(Arena *arena)
//- rjf: per-run caches
internal DF_Unwind
internal CTRL_Unwind
df_query_cached_unwind_from_thread(DF_Entity *thread)
{
ProfBeginFunction();
DF_Unwind result = {0};
CTRL_Unwind result = {0};
DF_RunUnwindCache *cache = &df_state->unwind_cache;
if(cache->table_size != 0)
{
@@ -6261,7 +6159,7 @@ internal U64
df_query_cached_rip_from_thread(DF_Entity *thread)
{
U64 result = 0;
DF_Unwind unwind = df_query_cached_unwind_from_thread(thread);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
if(unwind.first != 0)
{
result = unwind.first->rip;
@@ -6273,9 +6171,9 @@ internal U64
df_query_cached_rip_from_thread_unwind(DF_Entity *thread, U64 unwind_count)
{
U64 result = 0;
DF_Unwind unwind = df_query_cached_unwind_from_thread(thread);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
U64 unwind_idx = 0;
for(DF_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next, unwind_idx += 1)
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next, unwind_idx += 1)
{
if(unwind_idx == unwind_count)
{
@@ -7284,7 +7182,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
case DF_CoreCmdKind_StepOut:
{
// rjf: thread => full unwind
DF_Unwind unwind = df_query_cached_unwind_from_thread(thread);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
// rjf: use first unwind frame to generate trap
if(unwind.first != 0 && unwind.first->next != 0)
@@ -7453,7 +7351,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
case DF_CoreCmdKind_SelectUnwind:
{
DF_Entity *thread = df_entity_from_handle(df_state->ctrl_ctx.thread);
DF_Unwind unwind = df_query_cached_unwind_from_thread(thread);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
U64 max_unwind = unwind.count ? unwind.count-1 : 0;
U64 index = Clamp(0, params.index, max_unwind);
df_state->ctrl_ctx.unwind_count = index;
+3 -23
View File
@@ -242,26 +242,6 @@ struct DF_CtrlFlowInfo
S64 cumulative_sp_delta;
};
////////////////////////////////
//~ rjf: Unwind Types
typedef struct DF_UnwindFrame DF_UnwindFrame;
struct DF_UnwindFrame
{
DF_UnwindFrame *next;
U64 rip;
void *regs;
};
typedef struct DF_Unwind DF_Unwind;
struct DF_Unwind
{
DF_UnwindFrame *first;
DF_UnwindFrame *last;
U64 count;
B32 error;
};
////////////////////////////////
//~ rjf: Evaluation Types
@@ -958,7 +938,7 @@ struct DF_RunUnwindCacheNode
{
DF_RunUnwindCacheNode *hash_next;
DF_Handle thread;
DF_Unwind unwind;
CTRL_Unwind unwind;
};
typedef struct DF_RunUnwindCacheSlot DF_RunUnwindCacheSlot;
@@ -1531,7 +1511,7 @@ internal DF_Entity *df_module_from_process_vaddr(DF_Entity *process, U64 vaddr);
internal DF_Entity *df_module_from_thread(DF_Entity *thread);
internal U64 df_tls_base_vaddr_from_thread(DF_Entity *thread);
internal Architecture df_architecture_from_entity(DF_Entity *entity);
internal DF_Unwind df_push_unwind_from_thread(Arena *arena, DF_Entity *thread);
internal CTRL_Unwind df_push_unwind_from_thread(Arena *arena, DF_Entity *thread);
internal U64 df_rip_from_thread(DF_Entity *thread);
internal U64 df_rip_from_thread_unwind(DF_Entity *thread, U64 unwind_count);
internal EVAL_String2NumMap *df_push_locals_map_from_binary_voff(Arena *arena, DBGI_Scope *scope, DF_Entity *binary, U64 voff);
@@ -1661,7 +1641,7 @@ internal DF_EntityList df_push_active_binary_list(Arena *arena);
internal DF_EntityList df_push_active_target_list(Arena *arena);
//- rjf: per-run caches
internal DF_Unwind df_query_cached_unwind_from_thread(DF_Entity *thread);
internal CTRL_Unwind df_query_cached_unwind_from_thread(DF_Entity *thread);
internal U64 df_query_cached_rip_from_thread(DF_Entity *thread);
internal U64 df_query_cached_rip_from_thread_unwind(DF_Entity *thread, U64 unwind_count);
internal EVAL_String2NumMap *df_query_cached_locals_map_from_binary_voff(DF_Entity *binary, U64 voff);
+7 -4
View File
@@ -3498,9 +3498,9 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D
if(df_icon_buttonf(DF_IconKind_Clipboard, "Copy Call Stack").clicked)
{
DF_Entity *process = df_entity_ancestor_from_kind(entity, DF_EntityKind_Process);
DF_Unwind unwind = df_query_cached_unwind_from_thread(entity);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(entity);
String8List lines = {0};
for(DF_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next)
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next)
{
U64 rip_vaddr = frame->rip;
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
@@ -8681,8 +8681,8 @@ df_entity_tooltips(DF_Entity *entity)
}
ui_spacer(ui_em(1.5f, 1.f));
DF_Entity *process = df_entity_ancestor_from_kind(entity, DF_EntityKind_Process);
DF_Unwind unwind = df_query_cached_unwind_from_thread(entity);
for(DF_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next)
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(entity);
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next)
{
U64 rip_vaddr = frame->rip;
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
@@ -8869,6 +8869,9 @@ df_entity_desc_button(DF_Window *ws, DF_Entity *entity, FuzzyMatchRangeList *nam
{
ui_label(str8_lit("(Disabled)"));
}
if(entity->kind == DF_EntityKind_Thread)
{
}
}
//- rjf: do interaction on main box
+4 -4
View File
@@ -4042,7 +4042,7 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
{
thread_color = df_rgba_from_entity(thread);
}
DF_Unwind unwind = df_query_cached_unwind_from_thread(thread);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
//- rjf: grab state
typedef struct DF_CallStackViewState DF_CallStackViewState;
@@ -4102,7 +4102,7 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
//- rjf: frame rows
U64 frame_idx = 0;
for(DF_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next, frame_idx += 1)
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next, frame_idx += 1)
{
// rjf: out of range -> skip (TODO(rjf): this should be an array...)
if(frame_idx+1 < visible_row_range.min || visible_row_range.max < frame_idx+1)
@@ -7751,13 +7751,13 @@ DF_VIEW_UI_FUNCTION_DEF(Memory)
};
AnnotationList *visible_memory_annotations = push_array(scratch.arena, AnnotationList, visible_memory_size);
{
DF_Unwind unwind = df_query_cached_unwind_from_thread(thread);
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
//- rjf: fill unwind frame annotations
if(unwind.first != 0)
{
U64 last_stack_top = regs_rsp_from_arch_block(thread->arch, unwind.first->regs);
for(DF_UnwindFrame *f = unwind.first->next; f != 0; f = f->next)
for(CTRL_UnwindFrame *f = unwind.first->next; f != 0; f = f->next)
{
U64 f_stack_top = regs_rsp_from_arch_block(thread->arch, f->regs);
Rng1U64 frame_vaddr_range = r1u64(last_stack_top, f_stack_top);