From 86eabe0d6def6ec37290456cbe645980147e90fe Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 15 May 2025 21:57:50 -0700 Subject: [PATCH] offer priority selection in call stack retrieval; prioritize selected thread & operations which require a result; adjust call stack builder path to be a bit more generous while waiting for memory reads --- src/ctrl/ctrl_core.c | 26 +++++++++++++++++--------- src/ctrl/ctrl_core.h | 2 +- src/raddbg/raddbg_core.c | 8 ++++---- src/raddbg/raddbg_eval.c | 2 +- src/raddbg/raddbg_views.c | 4 ++-- src/raddbg/raddbg_widgets.c | 2 +- 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index be8416f2..6a5e8830 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -3356,7 +3356,7 @@ ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U //~ rjf: Call Stack Cache Functions internal CTRL_CallStack -ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us) +ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, B32 high_priority, U64 endt_us) { CTRL_CallStack call_stack = {0}; { @@ -3419,7 +3419,7 @@ ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us) if(!is_working && (!is_good || is_stale)) { if(ctrl_u2csb_enqueue_req(thread->handle, endt_us) && - async_push_work(ctrl_call_stack_build_work)) + async_push_work(ctrl_call_stack_build_work, .priority = high_priority ? ASYNC_Priority_High : ASYNC_Priority_Low)) { ins_atomic_u64_inc_eval(&node->working_count); } @@ -6887,13 +6887,21 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) //- rjf: compute unwind to find list of all concrete frames, then // call stack, to determine list of all concrete & inline frames - U64 pre_reg_gen = ctrl_reg_gen(); - U64 pre_mem_gen = ctrl_mem_gen(); Arena *arena = arena_alloc(); - CTRL_Unwind unwind = ctrl_unwind_from_thread(arena, entity_ctx, thread_handle, 0); - CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(arena, process, &unwind); - U64 post_reg_gen = ctrl_reg_gen(); - U64 post_mem_gen = ctrl_mem_gen(); + U64 pre_reg_gen = 0; + U64 post_reg_gen = 0; + U64 pre_mem_gen = 0; + U64 post_mem_gen = 0; + CTRL_Unwind unwind = {0}; + CTRL_CallStack call_stack = {0}; + { + pre_reg_gen = ctrl_reg_gen(); + pre_mem_gen = ctrl_mem_gen(); + unwind = ctrl_unwind_from_thread(arena, entity_ctx, thread_handle, os_now_microseconds()+1000); + call_stack = ctrl_call_stack_from_unwind(arena, process, &unwind); + post_reg_gen = ctrl_reg_gen(); + post_mem_gen = ctrl_mem_gen(); + } //- rjf: store new results in cache Arena *last_arena = arena; @@ -6938,7 +6946,7 @@ ASYNC_WORK_DEF(ctrl_call_stack_build_work) // rjf: found, not committed? -> wait & retry if(found && !committed) { - os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, os_now_microseconds()+100); + os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, os_now_microseconds()+10); } } if(committed) diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 351bb8f7..45ba1a4b 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -1045,7 +1045,7 @@ internal CTRL_CallStackFrame *ctrl_call_stack_frame_from_unwind_and_inline_depth //////////////////////////////// //~ rjf: Call Stack Cache Functions -internal CTRL_CallStack ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, U64 endt_us); +internal CTRL_CallStack ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_Entity *thread, B32 high_priority, U64 endt_us); //////////////////////////////// //~ rjf: Halting All Attached Processes diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e9366882..24bbfd56 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1816,7 +1816,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) case CTRL_EntityKind_Thread: { CTRL_Scope *ctrl_scope = ctrl_scope_open(); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 1, 0); U64 concrete_frame_idx = e_interpret_ctx->reg_unwind_count; if(concrete_frame_idx < call_stack.concrete_frames_count) { @@ -6399,7 +6399,7 @@ rd_window_frame(void) Vec4F32 code_color = ui_color_from_name(str8_lit("code_default")); Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, ctrl_entity, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, ctrl_entity, ctrl_handle_match(ctrl_entity->handle, rd_base_regs()->thread), 0); if(call_stack.frames_count != 0) { ui_spacer(ui_em(1.5f, 1.f)); @@ -15640,7 +15640,7 @@ rd_frame(void) { CTRL_Scope *ctrl_scope = ctrl_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, os_now_microseconds()+10000); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 1, os_now_microseconds()+10000); CTRL_CallStackFrame *frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); if(frame == 0) { @@ -15659,7 +15659,7 @@ rd_frame(void) { CTRL_Scope *ctrl_scope = ctrl_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, os_now_microseconds()+10000); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 1, os_now_microseconds()+10000); CTRL_CallStackFrame *current_frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); CTRL_CallStackFrame *next_frame = current_frame; if(current_frame != 0) switch(kind) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index a329257e..7183fffb 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -957,7 +957,7 @@ E_TYPE_IREXT_FUNCTION_DEF(call_stack) { accel->arch = entity->arch; accel->process = ctrl_process_from_entity(entity)->handle; - accel->call_stack = ctrl_call_stack_from_thread(rd_state->frame_ctrl_scope, entity, 0); + accel->call_stack = ctrl_call_stack_from_thread(rd_state->frame_ctrl_scope, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); } scratch_end(scratch); } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 81fdc192..2022ad37 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1011,7 +1011,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) CTRL_Scope *ctrl_scope = ctrl_scope_open(); info.callstack_thread = entity; U64 frame_num = ev_block_num_from_id(block, key.child_id); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); if(1 <= frame_num && frame_num <= call_stack.frames_count) { CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1]; @@ -2841,7 +2841,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) CTRL_Scope *ctrl_scope = ctrl_scope_open(); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread, 1, 0); //- rjf: fill unwind frame annotations if(call_stack.concrete_frames_count != 0) UI_Tag(str8_lit("weak")) diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 1257da53..8dc6df38 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -525,7 +525,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e DI_Scope *di_scope = di_scope_open(); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); Arch arch = entity->arch; - CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, 0); + CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity, ctrl_handle_match(entity->handle, rd_base_regs()->thread), 0); for(U64 idx = 0, limit = 6; idx < call_stack.frames_count && idx < limit; idx += 1) { CTRL_CallStackFrame *f = &call_stack.frames[call_stack.frames_count - 1 - idx];