From d1536953b04dd1c0587a0d6e8351376ed2d3ea92 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 11 May 2026 14:21:43 -0700 Subject: [PATCH] p2r: eliminate spurious duplicate address vmap entries; upgrade step-out with block stepping functionality --- src/dbg_engine/dbg_engine_user.c | 45 ++++++++++++-------------------- src/mule/mule_main.cpp | 8 ++++++ src/rdi_make/rdi_make_local.c | 2 +- 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/dbg_engine/dbg_engine_user.c b/src/dbg_engine/dbg_engine_user.c index 5cc0be1f..2927988d 100644 --- a/src/dbg_engine/dbg_engine_user.c +++ b/src/dbg_engine/dbg_engine_user.c @@ -758,6 +758,7 @@ d_trap_net_from_thread__step_out_scope(Arena *arena, D_Entity *thread) D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process); D_Entity *module = d_module_from_process_vaddr(process, ip_vaddr); DI_Key dbgi_key = d_dbgi_key_from_module(module); + D_CallStack callstack = d_call_stack_from_thread(access, thread->handle, 1, read_endt_us); // rjf: ip => enclosing scope's list(voff_range) Rng1U64List scope_voff_rngs = {0}; @@ -786,6 +787,7 @@ d_trap_net_from_thread__step_out_scope(Arena *arena, D_Entity *thread) D_ProcessMemorySlice code_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, vaddr_range, 0, read_endt_us); if(!code_slice.any_byte_bad) { + result.good_read = 1; String8 code = code_slice.data; DASM_CtrlFlowInfo ctrl_flow_info = dasm_ctrl_flow_info_from_arch_vaddr_code(scratch.arena, DASM_InstFlag_Branch|DASM_InstFlag_UnconditionalJump|DASM_InstFlag_Return, arch, vaddr_range.min, code); @@ -796,7 +798,7 @@ d_trap_net_from_thread__step_out_scope(Arena *arena, D_Entity *thread) B32 jump_dest_vaddr_is_out_of_scope = 1; for EachNode(scope_n, Rng1U64Node, scope_voff_rngs.first) { - if(contains_1u64(scope_n->v, jump_dest_vaddr)) + if(contains_1u64(scope_n->v, d_voff_from_vaddr(module, jump_dest_vaddr))) { jump_dest_vaddr_is_out_of_scope = 0; break; @@ -815,7 +817,7 @@ d_trap_net_from_thread__step_out_scope(Arena *arena, D_Entity *thread) B32 opl_vaddr_is_out_of_scope = 1; for EachNode(scope_n, Rng1U64Node, scope_voff_rngs.first) { - if(contains_1u64(scope_n->v, opl_vaddr)) + if(contains_1u64(scope_n->v, d_voff_from_vaddr(module, opl_vaddr))) { opl_vaddr_is_out_of_scope = 0; break; @@ -835,6 +837,19 @@ d_trap_net_from_thread__step_out_scope(Arena *arena, D_Entity *thread) } } + // rjf: use first unwind frame to generate trap + if(result.good_read && callstack.concrete_frames_count > 1) + { + ARCH_Info *arch_info = arch_info_from_arch(thread->arch); + U64 vaddr = arch_ip_from_reg_block(arch_info, callstack.concrete_frames[1]->regs); + D_Trap trap = {D_TrapFlag_EndStepping|D_TrapFlag_IgnoreStackPointerCheck, vaddr}; + d_trap_list_push(arena, &result.traps, &trap); + } + else + { + result.good_read = 0; + } + access_close(access); scratch_end(scratch); } @@ -1909,33 +1924,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P case D_CmdKind_StepOverInst: {trap_net = d_trap_net_from_thread__step_over_inst(scratch.arena, thread);}break; case D_CmdKind_StepIntoLine: {trap_net = d_trap_net_from_thread__step_into_line(scratch.arena, thread);}break; case D_CmdKind_StepOverLine: {trap_net = d_trap_net_from_thread__step_over_line(scratch.arena, thread);}break; -#if 0 case D_CmdKind_StepOut: {trap_net = d_trap_net_from_thread__step_out_scope(scratch.arena, thread);}break; -#else - case D_CmdKind_StepOut: - { - Access *access = access_open(); - - // rjf: thread => call stack - D_CallStack callstack = d_call_stack_from_thread(access, thread->handle, 1, now_time_us()+10000); - - // rjf: use first unwind frame to generate trap - if(callstack.concrete_frames_count > 1) - { - ARCH_Info *arch_info = arch_info_from_arch(thread->arch); - U64 vaddr = arch_ip_from_reg_block(arch_info, callstack.concrete_frames[1]->regs); - D_Trap trap = {D_TrapFlag_EndStepping|D_TrapFlag_IgnoreStackPointerCheck, vaddr}; - d_trap_list_push(scratch.arena, &trap_net.traps, &trap); - trap_net.good_read = 1; - } - else - { - log_user_error(str8_lit("Could not find the return address of the current callstack frame successfully.")); - } - - access_close(access); - }break; -#endif } B32 good_trap_net = (trap_net.good_read || !trap_net.good_line_info); if(good_trap_net && trap_net.traps.count != 0) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 23948081..be842092 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -681,6 +681,14 @@ type_coverage_eval_tests(void) OutputDebugStringA("\n"); } + if(1) + { + OutputDebugStringA("this is inside a branch!\n"); + OutputDebugStringA("foo"); + OutputDebugStringA("bar"); + OutputDebugStringA("baz"); + } + const int32_t x1 = 3; const int32_t y1 = -10; const int32_t z1 = x1 + y1; diff --git a/src/rdi_make/rdi_make_local.c b/src/rdi_make/rdi_make_local.c index b2d1c063..638e456f 100644 --- a/src/rdi_make/rdi_make_local.c +++ b/src/rdi_make/rdi_make_local.c @@ -852,7 +852,7 @@ rdim_bake(Arena *arena, RDIM_BakeParams *params) SLLStackPush(top_range, r); r->voff_range = voff_range; r->idx = idx; - if(voff_range.min != last_recorded_voff || (vmap_ptr->idx != idx && vmap_ptr->idx != 0)) + if(voff_range.min != last_recorded_voff) { vmap_ptr += 1; }