From 95b8b713223d6c0e33c1415fb035ca99f4b7a8be Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 Feb 2024 14:06:06 -0800 Subject: [PATCH] dedup multiple unwinder paths; just collapse down to using the ctrl one --- src/ctrl/ctrl_core.h | 2 +- src/df/core/df_core.c | 136 ++++++------------------------------------ src/df/core/df_core.h | 26 +------- src/df/gfx/df_gfx.c | 11 ++-- src/df/gfx/df_views.c | 8 +-- 5 files changed, 32 insertions(+), 151 deletions(-) diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 3aa4deef..6dfbc48d 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -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); diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 2ecee728..25ceac6e 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -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; diff --git a/src/df/core/df_core.h b/src/df/core/df_core.h index 8af91fb3..5c58efe5 100644 --- a/src/df/core/df_core.h +++ b/src/df/core/df_core.h @@ -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); diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 5b6ea870..502694a1 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -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 diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 0c6154fa..a20489ca 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -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);