diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index fa06d999..390c5a6e 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1715,6 +1715,11 @@ ctrl_thread__entry_point(void *p) //- rjf: get next messages CTRL_MsgList msgs = ctrl_u2c_pop_msgs(scratch.arena); + //- rjf: enable stuck-thread-step behavior in all cases - can be silently enabled by launch_and_init for subsequent messages + { + ctrl_state->disable_stuck_thread_step = 0; + } + //- rjf: process messages DMN_CtrlExclusiveAccessScope { @@ -2658,6 +2663,13 @@ ctrl_thread__launch_and_init(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) ctrl_c2u_push_events(&evts); } + ////////////////////////////// + //- rjf: disable 'step-over-stuck' behavior + // + { + ctrl_state->disable_stuck_thread_step = 1; + } + scratch_end(scratch); ProfEnd(); } @@ -2862,7 +2874,11 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) // the user breakpoint. // B32 target_thread_is_on_user_bp_and_trap_net_trap = 0; - if(stop_event == 0) + if(ctrl_state->disable_stuck_thread_step) + { + ctrl_state->disable_stuck_thread_step = 0; + } + else if(stop_event == 0 && !ctrl_state->disable_stuck_thread_step) { // rjf: gather stuck threads DMN_HandleList stuck_threads = {0}; diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 02ca8006..cf459fe7 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -522,6 +522,7 @@ struct CTRL_State String8List user_entry_points; U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]; U64 process_counter; + B32 disable_stuck_thread_step; // rjf: user -> memstream ring buffer U64 u2ms_ring_size; @@ -694,8 +695,8 @@ internal CTRL_EventList ctrl_c2u_pop_events(Arena *arena); internal void ctrl_thread__entry_point(void *p); //- rjf: breakpoint resolution -internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_MachineID machine_id, DMN_Handle process, DMN_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); -internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_MachineID machine_id, DMN_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); +internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_MachineID machine_id, DMN_Handle process, DMN_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); +internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_MachineID machine_id, DMN_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); //- rjf: attached process running/event gathering internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, DMN_RunCtrls *run_ctrls, CTRL_Spoof *spoof); diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index df6ae29f..a96dbe5e 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -3757,6 +3757,71 @@ df_log_from_entity(DF_Entity *entity) //////////////////////////////// //~ rjf: Target Controls +//- rjf: control user breakpoint gathering + +internal CTRL_UserBreakpointList +df_push_ctrl_user_breakpoints(Arena *arena) +{ + CTRL_UserBreakpointList user_bps_out = {0}; + DF_EntityList user_bp_entities = df_query_cached_entity_list_with_kind(DF_EntityKind_Breakpoint); + for(DF_EntityNode *user_bp_n = user_bp_entities.first; + user_bp_n != 0; + user_bp_n = user_bp_n->next) + { + // rjf: unpack user breakpoint entity + DF_Entity *user_bp = user_bp_n->entity; + if(user_bp->b32 == 0) + { + continue; + } + DF_Entity *file = df_entity_ancestor_from_kind(user_bp, DF_EntityKind_File); + DF_Entity *symb = df_entity_child_from_kind(user_bp, DF_EntityKind_EntryPointName); + DF_EntityList overrides = df_possible_overrides_from_entity(arena, file); + for(DF_EntityNode *override_n = overrides.first; override_n != 0; override_n = override_n->next) + { + DF_Entity *override = override_n->entity; + DF_Entity *condition_child = df_entity_child_from_kind(user_bp, DF_EntityKind_Condition); + String8 condition = condition_child->name; + + // rjf: generate user breakpoint info depending on breakpoint placement + CTRL_UserBreakpointKind ctrl_user_bp_kind = CTRL_UserBreakpointKind_FileNameAndLineColNumber; + String8 ctrl_user_bp_string = {0}; + TxtPt ctrl_user_bp_pt = {0}; + U64 ctrl_user_bp_u64 = 0; + { + if(user_bp->flags & DF_EntityFlag_HasTextPoint) + { + ctrl_user_bp_kind = CTRL_UserBreakpointKind_FileNameAndLineColNumber; + ctrl_user_bp_string = df_full_path_from_entity(arena, override); + ctrl_user_bp_pt = user_bp->text_point; + } + else if(user_bp->flags & DF_EntityFlag_HasVAddr) + { + ctrl_user_bp_kind = CTRL_UserBreakpointKind_VirtualAddress; + ctrl_user_bp_u64 = user_bp->vaddr; + } + else if(!df_entity_is_nil(symb)) + { + ctrl_user_bp_kind = CTRL_UserBreakpointKind_SymbolNameAndOffset; + ctrl_user_bp_string = symb->name; + ctrl_user_bp_u64 = user_bp->u64; + } + } + + // rjf: push user breakpoint to list + { + CTRL_UserBreakpoint ctrl_user_bp = {ctrl_user_bp_kind}; + ctrl_user_bp.string = ctrl_user_bp_string; + ctrl_user_bp.pt = ctrl_user_bp_pt; + ctrl_user_bp.u64 = ctrl_user_bp_u64; + ctrl_user_bp.condition = condition; + ctrl_user_breakpoint_list_push(arena, &user_bps_out, &ctrl_user_bp); + } + } + } + return user_bps_out; +} + //- rjf: control message dispatching internal void @@ -3796,61 +3861,7 @@ df_ctrl_run(DF_RunKind run, DF_Entity *run_thread, CTRL_TrapList *run_traps) { MemoryCopyStruct(&msg.traps, run_traps); } - for(DF_EntityNode *user_bp_n = user_bps.first; - user_bp_n != 0; - user_bp_n = user_bp_n->next) - { - // rjf: unpack user breakpoint entity - DF_Entity *user_bp = user_bp_n->entity; - if(user_bp->b32 == 0) - { - continue; - } - DF_Entity *file = df_entity_ancestor_from_kind(user_bp, DF_EntityKind_File); - DF_Entity *symb = df_entity_child_from_kind(user_bp, DF_EntityKind_EntryPointName); - DF_EntityList overrides = df_possible_overrides_from_entity(scratch.arena, file); - for(DF_EntityNode *override_n = overrides.first; override_n != 0; override_n = override_n->next) - { - DF_Entity *override = override_n->entity; - DF_Entity *condition_child = df_entity_child_from_kind(user_bp, DF_EntityKind_Condition); - String8 condition = condition_child->name; - - // rjf: generate user breakpoint info depending on breakpoint placement - CTRL_UserBreakpointKind ctrl_user_bp_kind = CTRL_UserBreakpointKind_FileNameAndLineColNumber; - String8 ctrl_user_bp_string = {0}; - TxtPt ctrl_user_bp_pt = {0}; - U64 ctrl_user_bp_u64 = 0; - { - if(user_bp->flags & DF_EntityFlag_HasTextPoint) - { - ctrl_user_bp_kind = CTRL_UserBreakpointKind_FileNameAndLineColNumber; - ctrl_user_bp_string = df_full_path_from_entity(scratch.arena, override); - ctrl_user_bp_pt = user_bp->text_point; - } - else if(user_bp->flags & DF_EntityFlag_HasVAddr) - { - ctrl_user_bp_kind = CTRL_UserBreakpointKind_VirtualAddress; - ctrl_user_bp_u64 = user_bp->vaddr; - } - else if(!df_entity_is_nil(symb)) - { - ctrl_user_bp_kind = CTRL_UserBreakpointKind_SymbolNameAndOffset; - ctrl_user_bp_string = symb->name; - ctrl_user_bp_u64 = user_bp->u64; - } - } - - // rjf: push user breakpoint to list - { - CTRL_UserBreakpoint ctrl_user_bp = {ctrl_user_bp_kind}; - ctrl_user_bp.string = ctrl_user_bp_string; - ctrl_user_bp.pt = ctrl_user_bp_pt; - ctrl_user_bp.u64 = ctrl_user_bp_u64; - ctrl_user_bp.condition = condition; - ctrl_user_breakpoint_list_push(scratch.arena, &msg.user_bps, &ctrl_user_bp); - } - } - } + msg.user_bps = df_push_ctrl_user_breakpoints(scratch.arena); if(df_state->ctrl_solo_stepping_mode && !df_entity_is_nil(run_thread)) { msg.freeze_state_is_frozen = 0; diff --git a/src/df/core/df_core.h b/src/df/core/df_core.h index 7ba02bf4..07e42d08 100644 --- a/src/df/core/df_core.h +++ b/src/df/core/df_core.h @@ -1563,6 +1563,9 @@ internal DF_Entity *df_log_from_entity(DF_Entity *entity); //////////////////////////////// //~ rjf: Target Controls +//- rjf: control user breakpoint gathering +internal CTRL_UserBreakpointList df_push_ctrl_user_breakpoints(Arena *arena); + //- rjf: control message dispatching internal void df_push_ctrl_msg(CTRL_Msg *msg); diff --git a/src/raddbg/raddbg.h b/src/raddbg/raddbg.h index 9e4442c2..60701850 100644 --- a/src/raddbg/raddbg.h +++ b/src/raddbg/raddbg.h @@ -2,10 +2,12 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) //////////////////////////////// -//~ rjf: Demon Pass Tasks +//~ rjf: Demon/Cleanup Pass Tasks // // [ ] TLS eval -> in-process-memory EXE info // [ ] unwinding -> in-process-memory EXE info +// [ ] "root" concept in hash store, which buckets keys & allows usage code to +// jettison a collection of keys in retained mode fashion // [x] solidify synchronization mechanisms for usage of demon layer // [x] TLS eval correctness // [x] freezing thread while running -> soft-halt