disable single-step-stuck-thread behavior when launching-and-initing, such that breakpoints on entry point will not be stepped over

This commit is contained in:
Ryan Fleury
2024-03-22 17:17:08 -07:00
parent 995804cc78
commit c26274ac70
5 changed files with 92 additions and 59 deletions
+17 -1
View File
@@ -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};
+3 -2
View File
@@ -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);
+66 -55
View File
@@ -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;
+3
View File
@@ -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);
+3 -1
View File
@@ -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