From 2272b4a14ced9f867262bacb71e5c534bd4b6d3a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 8 Sep 2024 10:23:32 -0700 Subject: [PATCH] eliminate d_ctrl_run helper intermediate; switch to using simplified passdown types for breakpoints, rather than entities, in ctrl run parameterization --- src/dbg_engine/dbg_engine_core.c | 248 ++++++++++++--------------- src/dbg_engine/dbg_engine_core.h | 5 +- src/dbg_frontend/dbg_frontend_core.c | 8 +- 3 files changed, 121 insertions(+), 140 deletions(-) diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 3c5d123d..ec92ce41 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -3321,7 +3321,7 @@ d_unwind_from_ctrl_unwind(Arena *arena, DI_Scope *di_scope, D_Entity *process, C //- rjf: state which parameterizes runs, but can be live-edited -> hash internal U128 -d_hash_from_ctrl_param_state(void) +d_hash_from_ctrl_param_state(D_BreakpointArray *breakpoints) { U128 result = {0}; Temp scratch = scratch_begin(0, 0); @@ -3333,17 +3333,14 @@ d_hash_from_ctrl_param_state(void) { str8_list_push(scratch.arena, &strings, str8_struct(&n->handle)); } - D_EntityList bps = d_query_cached_entity_list_with_kind(D_EntityKind_Breakpoint); - for(D_EntityNode *n = bps.first; n != 0; n = n->next) + for(U64 idx = 0; idx < breakpoints->count; idx += 1) { - D_Entity *bp = n->entity; - D_Entity *loc = d_entity_child_from_kind(bp, D_EntityKind_Location); - D_Entity *cnd = d_entity_child_from_kind(bp, D_EntityKind_Condition); - str8_list_push(scratch.arena, &strings, str8_struct(&bp->disabled)); - str8_list_push(scratch.arena, &strings, loc->string); - str8_list_push(scratch.arena, &strings, str8_struct(&loc->text_point)); - str8_list_push(scratch.arena, &strings, str8_struct(&loc->vaddr)); - str8_list_push(scratch.arena, &strings, str8_struct(&cnd->string)); + D_Breakpoint *bp = &breakpoints->v[idx]; + str8_list_push(scratch.arena, &strings, bp->file_path); + str8_list_push(scratch.arena, &strings, str8_struct(&bp->pt)); + str8_list_push(scratch.arena, &strings, bp->symbol_name); + str8_list_push(scratch.arena, &strings, str8_struct(&bp->vaddr)); + str8_list_push(scratch.arena, &strings, bp->condition); } } @@ -3369,115 +3366,6 @@ d_push_ctrl_msg(CTRL_Msg *msg) } } -//- rjf: control thread running - -internal void -d_ctrl_run(D_RunKind run, D_Entity *run_thread, CTRL_RunFlags flags, CTRL_TrapList *run_traps) -{ - Temp scratch = scratch_begin(0, 0); - - // rjf: compute hash of all run-parameterization entities, store - { - d_state->ctrl_last_run_param_state_hash = d_hash_from_ctrl_param_state(); - } - - // rjf: build run message - CTRL_Msg msg = {(run == D_RunKind_Run || run == D_RunKind_Step) ? CTRL_MsgKind_Run : CTRL_MsgKind_SingleStep}; - { - D_EntityList user_bps = d_query_cached_entity_list_with_kind(D_EntityKind_Breakpoint); - D_Entity *process = d_entity_ancestor_from_kind(run_thread, D_EntityKind_Process); - msg.run_flags = flags; - msg.machine_id = run_thread->ctrl_machine_id; - msg.entity = run_thread->ctrl_handle; - msg.parent = process->ctrl_handle; - MemoryCopyArray(msg.exception_code_filters, d_state->ctrl_exception_code_filters); - if(run_traps != 0) - { - MemoryCopyStruct(&msg.traps, run_traps); - } - for(D_EntityNode *user_bp_n = user_bps.first; - user_bp_n != 0; - user_bp_n = user_bp_n->next) - { - // rjf: unpack user breakpoint entity - D_Entity *user_bp = user_bp_n->entity; - if(user_bp->disabled) - { - continue; - } - D_Entity *loc = d_entity_child_from_kind(user_bp, D_EntityKind_Location); - D_Entity *cnd = d_entity_child_from_kind(user_bp, D_EntityKind_Condition); - - // rjf: textual location -> add breakpoints for all possible override locations - if(loc->flags & D_EntityFlag_HasTextPoint) - { - String8List overrides = d_possible_overrides_from_file_path(scratch.arena, loc->string); - for(String8Node *n = overrides.first; n != 0; n = n->next) - { - CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_FileNameAndLineColNumber}; - ctrl_user_bp.string = n->string; - ctrl_user_bp.pt = loc->text_point; - ctrl_user_bp.condition = cnd->string; - ctrl_user_breakpoint_list_push(scratch.arena, &msg.user_bps, &ctrl_user_bp); - } - } - - // rjf: virtual address location -> add breakpoint for address - else if(loc->flags & D_EntityFlag_HasVAddr) - { - CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_VirtualAddress}; - ctrl_user_bp.u64 = loc->vaddr; - ctrl_user_bp.condition = cnd->string; - ctrl_user_breakpoint_list_push(scratch.arena, &msg.user_bps, &ctrl_user_bp); - } - - // rjf: symbol name location -> add breakpoint for symbol name - else if(loc->string.size != 0) - { - CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_SymbolNameAndOffset}; - ctrl_user_bp.string = loc->string; - ctrl_user_bp.condition = cnd->string; - ctrl_user_breakpoint_list_push(scratch.arena, &msg.user_bps, &ctrl_user_bp); - } - } - for(D_HandleNode *n = d_state->frozen_threads.first; n != 0; n = n->next) - { - D_Entity *thread = d_entity_from_handle(n->handle); - if(!d_entity_is_nil(thread)) - { - CTRL_MachineIDHandlePair pair = {thread->ctrl_machine_id, thread->ctrl_handle}; - ctrl_machine_id_handle_pair_list_push(scratch.arena, &msg.freeze_state_threads, &pair); - } - } - msg.freeze_state_is_frozen = 1; - } - - // rjf: push msg - d_push_ctrl_msg(&msg); - - // rjf: copy run traps to scratch (needed, if the caller can pass `d_state->ctrl_last_run_traps`) - CTRL_TrapList run_traps_copy = {0}; - if(run_traps != 0) - { - run_traps_copy = ctrl_trap_list_copy(scratch.arena, run_traps); - } - - // rjf: store last run info - arena_clear(d_state->ctrl_last_run_arena); - d_state->ctrl_last_run_kind = run; - d_state->ctrl_last_run_frame_idx = d_frame_index(); - d_state->ctrl_last_run_thread = d_handle_from_entity(run_thread); - d_state->ctrl_last_run_flags = flags; - d_state->ctrl_last_run_traps = ctrl_trap_list_copy(d_state->ctrl_last_run_arena, &run_traps_copy); - d_state->ctrl_is_running = 1; - - // rjf: reset selected frame to top unwind - d_state->base_regs.v.unwind_count = 0; - d_state->base_regs.v.inline_depth = 0; - - scratch_end(scratch); -} - //- rjf: stopped info from the control thread internal CTRL_Event @@ -6865,6 +6753,20 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, DI_ } } + ////////////////////////////// + //- rjf: compute state parameterization hash for ctrl runs, if ctrl is running - + // if the hash doesn't match the one for the last run, we need to soft-halt and + // re-send down the parameterization state + // + if(d_ctrl_targets_running()) + { + U128 state_hash = d_hash_from_ctrl_param_state(breakpoints); + if(!u128_match(state_hash, d_state->ctrl_last_run_param_state_hash)) + { + d_cmd(D_CmdKind_SoftHaltRefresh); + } + } + ////////////////////////////// //- rjf: process top-level commands // @@ -8464,7 +8366,97 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, DI_ // rjf: do run if needed if(need_run) { - d_ctrl_run(run_kind, run_thread, run_flags, &run_traps); + // rjf: compute hash of all run-parameterization entities, store + { + d_state->ctrl_last_run_param_state_hash = d_hash_from_ctrl_param_state(breakpoints); + } + + // rjf: build run message + CTRL_Msg msg = {(run_kind == D_RunKind_Run || run_kind == D_RunKind_Step) ? CTRL_MsgKind_Run : CTRL_MsgKind_SingleStep}; + { + D_EntityList user_bps = d_query_cached_entity_list_with_kind(D_EntityKind_Breakpoint); + D_Entity *process = d_entity_ancestor_from_kind(run_thread, D_EntityKind_Process); + msg.run_flags = run_flags; + msg.machine_id = run_thread->ctrl_machine_id; + msg.entity = run_thread->ctrl_handle; + msg.parent = process->ctrl_handle; + MemoryCopyArray(msg.exception_code_filters, d_state->ctrl_exception_code_filters); + MemoryCopyStruct(&msg.traps, &run_traps); + for(D_EntityNode *user_bp_n = user_bps.first; + user_bp_n != 0; + user_bp_n = user_bp_n->next) + { + // rjf: unpack user breakpoint entity + D_Entity *user_bp = user_bp_n->entity; + if(user_bp->disabled) + { + continue; + } + D_Entity *loc = d_entity_child_from_kind(user_bp, D_EntityKind_Location); + D_Entity *cnd = d_entity_child_from_kind(user_bp, D_EntityKind_Condition); + + // rjf: textual location -> add breakpoints for all possible override locations + if(loc->flags & D_EntityFlag_HasTextPoint) + { + String8List overrides = d_possible_overrides_from_file_path(scratch.arena, loc->string); + for(String8Node *n = overrides.first; n != 0; n = n->next) + { + CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_FileNameAndLineColNumber}; + ctrl_user_bp.string = n->string; + ctrl_user_bp.pt = loc->text_point; + ctrl_user_bp.condition = cnd->string; + ctrl_user_breakpoint_list_push(scratch.arena, &msg.user_bps, &ctrl_user_bp); + } + } + + // rjf: virtual address location -> add breakpoint for address + else if(loc->flags & D_EntityFlag_HasVAddr) + { + CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_VirtualAddress}; + ctrl_user_bp.u64 = loc->vaddr; + ctrl_user_bp.condition = cnd->string; + ctrl_user_breakpoint_list_push(scratch.arena, &msg.user_bps, &ctrl_user_bp); + } + + // rjf: symbol name location -> add breakpoint for symbol name + else if(loc->string.size != 0) + { + CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_SymbolNameAndOffset}; + ctrl_user_bp.string = loc->string; + ctrl_user_bp.condition = cnd->string; + ctrl_user_breakpoint_list_push(scratch.arena, &msg.user_bps, &ctrl_user_bp); + } + } + for(D_HandleNode *n = d_state->frozen_threads.first; n != 0; n = n->next) + { + D_Entity *thread = d_entity_from_handle(n->handle); + if(!d_entity_is_nil(thread)) + { + CTRL_MachineIDHandlePair pair = {thread->ctrl_machine_id, thread->ctrl_handle}; + ctrl_machine_id_handle_pair_list_push(scratch.arena, &msg.freeze_state_threads, &pair); + } + } + msg.freeze_state_is_frozen = 1; + } + + // rjf: push msg + d_push_ctrl_msg(&msg); + + // rjf: copy run traps to scratch (needed, if run_traps can be `d_state->ctrl_last_run_traps`) + CTRL_TrapList run_traps_copy = ctrl_trap_list_copy(scratch.arena, &run_traps); + + // rjf: store last run info + arena_clear(d_state->ctrl_last_run_arena); + d_state->ctrl_last_run_kind = run_kind; + d_state->ctrl_last_run_frame_idx = d_frame_index(); + d_state->ctrl_last_run_thread = d_handle_from_entity(run_thread); + d_state->ctrl_last_run_flags = run_flags; + d_state->ctrl_last_run_traps = ctrl_trap_list_copy(d_state->ctrl_last_run_arena, &run_traps_copy); + d_state->ctrl_is_running = 1; + + // rjf: reset selected frame to top unwind + d_state->base_regs.v.unwind_count = 0; + d_state->base_regs.v.inline_depth = 0; } } scratch_end(scratch); @@ -8665,20 +8657,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, DI_ } e_select_interpret_ctx(interpret_ctx); - ////////////////////////////// - //- rjf: compute state parameterization hash for ctrl runs, if ctrl is running - - // if the hash doesn't match the one for the last run, we need to soft-halt and - // re-send down the parameterization state - // - if(d_ctrl_targets_running()) - { - U128 state_hash = d_hash_from_ctrl_param_state(); - if(!u128_match(state_hash, d_state->ctrl_last_run_param_state_hash)) - { - d_cmd(D_CmdKind_SoftHaltRefresh); - } - } - ////////////////////////////// //- rjf: send messages to control // diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index da369010..77545e20 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -1380,14 +1380,11 @@ internal D_Unwind d_unwind_from_ctrl_unwind(Arena *arena, DI_Scope *di_scope, D_ //~ rjf: Target Controls //- rjf: state which parameterizes runs, but can be live-edited -> hash -internal U128 d_hash_from_ctrl_param_state(void); +internal U128 d_hash_from_ctrl_param_state(D_BreakpointArray *breakpoints); //- rjf: control message dispatching internal void d_push_ctrl_msg(CTRL_Msg *msg); -//- rjf: control thread running -internal void d_ctrl_run(D_RunKind run, D_Entity *run_thread, CTRL_RunFlags flags, CTRL_TrapList *run_traps); - //- rjf: stopped info from the control thread internal CTRL_Event d_ctrl_last_stop_event(void); diff --git a/src/dbg_frontend/dbg_frontend_core.c b/src/dbg_frontend/dbg_frontend_core.c index a8566f62..c682ff73 100644 --- a/src/dbg_frontend/dbg_frontend_core.c +++ b/src/dbg_frontend/dbg_frontend_core.c @@ -8219,9 +8219,14 @@ df_frame(void) breakpoints.count = bp_entities.count; breakpoints.v = push_array(scratch.arena, D_Breakpoint, breakpoints.count); U64 idx = 0; - for(D_EntityNode *n = bp_entities.first; n != 0; n = n->next, idx += 1) + for(D_EntityNode *n = bp_entities.first; n != 0; n = n->next) { D_Entity *src_bp = n->entity; + if(src_bp->disabled) + { + breakpoints.count -= 1; + continue; + } D_Entity *src_bp_loc = d_entity_child_from_kind(src_bp, D_EntityKind_Location); D_Entity *src_bp_cnd = d_entity_child_from_kind(src_bp, D_EntityKind_Condition); D_Breakpoint *dst_bp = &breakpoints.v[idx]; @@ -8230,6 +8235,7 @@ df_frame(void) dst_bp->symbol_name = src_bp_loc->string; dst_bp->vaddr = src_bp_loc->vaddr; dst_bp->condition = src_bp_cnd->string; + idx += 1; } }