eliminate launch-and-init path, switch fully to separate 'launch' and 'run' paths; snap to selected thread if no stopper thread on stopped events;

This commit is contained in:
Ryan Fleury
2024-03-27 14:09:29 -07:00
parent ee056aa45d
commit 291bf3875d
4 changed files with 62 additions and 377 deletions
+27 -354
View File
@@ -126,7 +126,7 @@ ctrl_msg_deep_copy(Arena *arena, CTRL_Msg *dst, CTRL_Msg *src)
{
MemoryCopyStruct(dst, src);
dst->path = push_str8_copy(arena, src->path);
dst->strings = str8_list_copy(arena, &src->strings);
dst->entry_points = str8_list_copy(arena, &src->entry_points);
dst->cmd_line_string_list = str8_list_copy(arena, &src->cmd_line_string_list);
dst->env_string_list = str8_list_copy(arena, &src->env_string_list);
dst->traps = ctrl_trap_list_copy(arena, &src->traps);
@@ -179,9 +179,9 @@ ctrl_serialized_string_from_msg_list(Arena *arena, CTRL_MsgList *msgs)
str8_serial_push_struct(scratch.arena, &msgs_srlzed, &msg->path.size);
str8_serial_push_data(scratch.arena, &msgs_srlzed, msg->path.str, msg->path.size);
// rjf: write general string list
str8_serial_push_struct(scratch.arena, &msgs_srlzed, &msg->strings.node_count);
for(String8Node *n = msg->strings.first; n != 0; n = n->next)
// rjf: write entry point string list
str8_serial_push_struct(scratch.arena, &msgs_srlzed, &msg->entry_points.node_count);
for(String8Node *n = msg->entry_points.first; n != 0; n = n->next)
{
str8_serial_push_struct(scratch.arena, &msgs_srlzed, &n->string.size);
str8_serial_push_data(scratch.arena, &msgs_srlzed, n->string.str, n->string.size);
@@ -279,16 +279,16 @@ ctrl_msg_list_from_serialized_string(Arena *arena, String8 string)
msg->path.str = push_array_no_zero(arena, U8, msg->path.size);
read_off += str8_deserial_read(string, read_off, msg->path.str, msg->path.size, 1);
// rjf: read general string list
U64 string_list_string_count = 0;
read_off += str8_deserial_read_struct(string, read_off, &string_list_string_count);
for(U64 idx = 0; idx < string_list_string_count; idx += 1)
// rjf: read entry point string list
U64 entry_point_list_string_count = 0;
read_off += str8_deserial_read_struct(string, read_off, &entry_point_list_string_count);
for(U64 idx = 0; idx < entry_point_list_string_count; idx += 1)
{
String8 str = {0};
read_off += str8_deserial_read_struct(string, read_off, &str.size);
str.str = push_array_no_zero(arena, U8, str.size);
read_off += str8_deserial_read(string, read_off, str.str, str.size, 1);
str8_list_push(arena, &msg->strings, str);
str8_list_push(arena, &msg->entry_points, str);
}
// rjf: read command line string list
@@ -469,6 +469,7 @@ ctrl_entity_store_alloc(void)
store->arena = arena;
store->hash_slots_count = 1024;
store->hash_slots = push_array(arena, CTRL_EntityHashSlot, store->hash_slots_count);
store->root = &ctrl_entity_nil;
return store;
}
@@ -734,7 +735,7 @@ internal void
ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list)
{
//- rjf: construct root-level entities
if(!store->root)
if(store->root == &ctrl_entity_nil)
{
CTRL_Entity *root = store->root = ctrl_entity_alloc(store, &ctrl_entity_nil, CTRL_EntityKind_Root, Architecture_Null, 0, dmn_handle_zero());
CTRL_Entity *local_machine = ctrl_entity_alloc(store, root, CTRL_EntityKind_Machine, architecture_from_context(), CTRL_MachineID_Local, dmn_handle_zero());
@@ -1750,7 +1751,7 @@ ctrl_thread__entry_point(void *p)
case CTRL_MsgKind_COUNT:{}break;
//- rjf: target operations
case CTRL_MsgKind_LaunchAndInit: {ctrl_thread__launch_and_init (ctrl_ctx, msg);}break;
case CTRL_MsgKind_Launch: {ctrl_thread__launch (ctrl_ctx, msg);}break;
case CTRL_MsgKind_Attach: {ctrl_thread__attach (ctrl_ctx, msg);}break;
case CTRL_MsgKind_Kill: {ctrl_thread__kill (ctrl_ctx, msg);}break;
case CTRL_MsgKind_Detach: {ctrl_thread__detach (ctrl_ctx, msg);}break;
@@ -1762,7 +1763,7 @@ ctrl_thread__entry_point(void *p)
{
arena_clear(ctrl_state->user_entry_point_arena);
MemoryZeroStruct(&ctrl_state->user_entry_points);
for(String8Node *n = msg->strings.first; n != 0; n = n->next)
for(String8Node *n = msg->entry_points.first; n != 0; n = n->next)
{
str8_list_push(ctrl_state->user_entry_point_arena, &ctrl_state->user_entry_points, n->string);
}
@@ -2252,14 +2253,8 @@ ctrl_eval_memory_read(void *u, void *out, U64 addr, U64 size)
//- rjf: msg kind implementations
internal void
ctrl_thread__launch_and_init(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
{
ProfBeginFunction();
Temp scratch = scratch_begin(0, 0);
//////////////////////////////
//- rjf: launch
//
OS_LaunchOptions opts = {0};
{
opts.cmd_line = msg->cmd_line_string_list;
@@ -2268,319 +2263,7 @@ ctrl_thread__launch_and_init(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
opts.inherit_env = msg->env_inherit;
}
U32 id = dmn_ctrl_launch(ctrl_ctx, &opts);
//////////////////////////////
//- rjf: record start
//
{
CTRL_EventList evts = {0};
CTRL_Event *event = ctrl_event_list_push(scratch.arena, &evts);
event->kind = CTRL_EventKind_Started;
ctrl_c2u_push_events(&evts);
}
//////////////////////////////
//- rjf: run to initialization (entry point)
//
DMN_Event *stop_event = 0;
if(id != 0)
{
DMN_Handle unfrozen_process[8] = {0};
DMN_RunCtrls run_ctrls = {0};
run_ctrls.run_entities_are_unfrozen = 1;
run_ctrls.run_entities_are_processes = 1;
for(B32 done = 0; done == 0;)
{
DMN_Event *event = ctrl_thread__next_dmn_event(scratch.arena, ctrl_ctx, msg, &run_ctrls, 0);
switch(event->kind)
{
default:{}break;
//- rjf: new process -> freeze process
case DMN_EventKind_CreateProcess:
if(run_ctrls.run_entity_count < ArrayCount(unfrozen_process))
{
unfrozen_process[run_ctrls.run_entity_count] = event->process;
run_ctrls.run_entities = &unfrozen_process[0];
run_ctrls.run_entity_count += 1;
}break;
//- rjf: breakpoint -> if it's the entry point, we're done. otherwise, keep going
case DMN_EventKind_Breakpoint:
{
for(DMN_TrapChunkNode *n = run_ctrls.traps.first; n != 0; n = n->next)
{
for(U64 idx = 0; idx < n->count; idx += 1)
{
if(n->v[idx].vaddr == event->instruction_pointer)
{
done = 1;
stop_event = event;
goto end_look_for_entry_match;
}
}
}
end_look_for_entry_match:;
}break;
//- rjf: exception -> done
case DMN_EventKind_Halt:
case DMN_EventKind_Exception:
case DMN_EventKind_Error:
{
done = 1;
stop_event = event;
}break;
//- rjf: process ended? -> remove from unfrozen processes. zero processes -> done.
case DMN_EventKind_ExitProcess:
{
for(U64 idx = 0; idx < run_ctrls.run_entity_count; idx += 1)
{
if(dmn_handle_match(run_ctrls.run_entities[idx], event->process) &&
idx+1 < run_ctrls.run_entity_count)
{
MemoryCopy(run_ctrls.run_entities+idx, run_ctrls.run_entities+idx+1, sizeof(DMN_Handle)*(run_ctrls.run_entity_count-(idx+1)));
break;
}
}
if(run_ctrls.run_entity_count > 0)
{
run_ctrls.run_entity_count -= 1;
}
if(run_ctrls.run_entity_count == 0)
{
done = 1;
stop_event = event;
}
}break;
//- rjf: done with handshake -> ready to find entry point. search launched processes
case DMN_EventKind_HandshakeComplete:
{
DBGI_Scope *scope = dbgi_scope_open();
//- rjf: add traps for all possible entry points
for(U64 process_idx = 0; process_idx < run_ctrls.run_entity_count; process_idx += 1)
{
//- rjf: unpack process & first module info
CTRL_Entity *process = ctrl_entity_from_machine_id_handle(ctrl_state->ctrl_thread_entity_store, CTRL_MachineID_Local, run_ctrls.run_entities[process_idx]);
CTRL_Entity *module = &ctrl_entity_nil;
for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next)
{
if(child->kind == CTRL_EntityKind_Module)
{
module = child;
break;
}
}
U64 module_base_vaddr = module->vaddr_range.min;
String8 exe_path = module->string;
DBGI_Parse *dbgi = dbgi_parse_from_exe_path(scope, exe_path, max_U64);
RDI_Parsed *rdi = &dbgi->rdi;
RDI_NameMap *unparsed_map = rdi_name_map_from_kind(rdi, RDI_NameMapKind_Procedures);
RDI_ParsedNameMap map = {0};
rdi_name_map_parse(rdi, unparsed_map, &map);
//- rjf: add trap for user-specified entry point, if specified
B32 entries_found = 0;
if(!entries_found)
{
for(String8Node *n = msg->strings.first; n != 0; n = n->next)
{
U32 procedure_id = 0;
{
String8 name = n->string;
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &map, name.str, name.size);
U32 id_count = 0;
U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count);
if(id_count > 0)
{
procedure_id = ids[0];
}
}
U64 voff = rdi_first_voff_from_proc(rdi, procedure_id);
if(voff != 0)
{
entries_found = 1;
DMN_Trap trap = {run_ctrls.run_entities[process_idx], module_base_vaddr + voff};
dmn_trap_chunk_list_push(scratch.arena, &run_ctrls.traps, 256, &trap);
}
}
}
//- rjf: add traps for all custom user entry points
if(!entries_found)
{
for(String8Node *n = ctrl_state->user_entry_points.first; n != 0; n = n->next)
{
U32 procedure_id = 0;
{
String8 name = n->string;
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &map, name.str, name.size);
U32 id_count = 0;
U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count);
if(id_count > 0)
{
procedure_id = ids[0];
}
}
U64 voff = rdi_first_voff_from_proc(rdi, procedure_id);
if(voff != 0)
{
DMN_Trap trap = {run_ctrls.run_entities[process_idx], module_base_vaddr + voff};
dmn_trap_chunk_list_push(scratch.arena, &run_ctrls.traps, 256, &trap);
break;
}
}
}
//- rjf: add traps for all high-level entry points
if(!entries_found)
{
String8 hi_entry_points[] =
{
str8_lit("WinMain"),
str8_lit("wWinMain"),
str8_lit("main"),
str8_lit("wmain"),
};
for(U64 idx = 0; idx < ArrayCount(hi_entry_points); idx += 1)
{
U32 procedure_id = 0;
{
String8 name = hi_entry_points[idx];
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &map, name.str, name.size);
U32 id_count = 0;
U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count);
if(id_count > 0)
{
procedure_id = ids[0];
}
}
U64 voff = rdi_first_voff_from_proc(rdi, procedure_id);
if(voff != 0)
{
entries_found = 1;
DMN_Trap trap = {run_ctrls.run_entities[process_idx], module_base_vaddr + voff};
dmn_trap_chunk_list_push(scratch.arena, &run_ctrls.traps, 256, &trap);
}
}
}
//- rjf: add trap for PE header entry
if(!entries_found)
{
U64 voff = dbgi->pe.entry_point;
if(voff != 0)
{
DMN_Trap trap = {run_ctrls.run_entities[process_idx], module_base_vaddr + voff};
dmn_trap_chunk_list_push(scratch.arena, &run_ctrls.traps, 256, &trap);
}
}
//- rjf: add traps for all low-level entry points
if(!entries_found)
{
String8 lo_entry_points[] =
{
str8_lit("WinMainCRTStartup"),
str8_lit("wWinMainCRTStartup"),
str8_lit("mainCRTStartup"),
str8_lit("wmainCRTStartup"),
};
for(U64 idx = 0; idx < ArrayCount(lo_entry_points); idx += 1)
{
U32 procedure_id = 0;
{
String8 name = lo_entry_points[idx];
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &map, name.str, name.size);
U32 id_count = 0;
U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count);
if(id_count > 0)
{
procedure_id = ids[0];
}
}
U64 voff = rdi_first_voff_from_proc(rdi, procedure_id);
if(voff != 0)
{
entries_found = 1;
DMN_Trap trap = {run_ctrls.run_entities[process_idx], module_base_vaddr + voff};
dmn_trap_chunk_list_push(scratch.arena, &run_ctrls.traps, 256, &trap);
}
}
}
//- rjf: no entry point found -> done
if(run_ctrls.traps.trap_count == 0)
{
done = 1;
stop_event = event;
}
}
dbgi_scope_close(scope);
}break;
}
}
}
//////////////////////////////
//- rjf: record bad stop
//
if(stop_event == 0 && id == 0)
{
CTRL_EventList evts = {0};
CTRL_Event *event = ctrl_event_list_push(scratch.arena, &evts);
event->kind = CTRL_EventKind_Error;
event->cause = CTRL_EventCause_Error;
ctrl_c2u_push_events(&evts);
}
//////////////////////////////
//- rjf: record stop
//
{
CTRL_EventList evts = {0};
CTRL_Event *event = ctrl_event_list_push(scratch.arena, &evts);
event->kind = CTRL_EventKind_Stopped;
event->msg_id = msg->msg_id;
if(stop_event != 0)
{
event->cause = ctrl_event_cause_from_dmn_event_kind(stop_event->kind);
event->machine_id = CTRL_MachineID_Local;
event->entity = stop_event->thread;
event->parent = stop_event->process;
event->exception_code = stop_event->code;
event->vaddr_rng = r1u64(stop_event->address, stop_event->address);
event->rip_vaddr = stop_event->instruction_pointer;
}
ctrl_c2u_push_events(&evts);
}
//////////////////////////////
//- rjf: push request resolution event
//
{
CTRL_EventList evts = {0};
CTRL_Event *evt = ctrl_event_list_push(scratch.arena, &evts);
evt->kind = CTRL_EventKind_LaunchAndInitDone;
evt->machine_id= CTRL_MachineID_Local;
evt->msg_id = msg->msg_id;
evt->entity_id = id;
ctrl_c2u_push_events(&evts);
}
//////////////////////////////
//- rjf: disable 'step-over-stuck' behavior
//
{
ctrl_state->disable_stuck_thread_step = 1;
}
scratch_end(scratch);
ProfEnd();
(void)id;
}
internal void
@@ -2928,24 +2611,6 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &trap_net_traps);
}
//////////////////////////////
//- rjf: launch if needed
//
B32 launch_triggered = 0;
U32 launch_id = 0;
if(msg->run_flags & CTRL_RunFlag_Launch)
{
OS_LaunchOptions opts = {0};
{
opts.cmd_line = msg->cmd_line_string_list;
opts.path = msg->path;
opts.env = msg->env_string_list;
opts.inherit_env = msg->env_inherit;
}
launch_id = dmn_ctrl_launch(ctrl_ctx, &opts);
launch_triggered = (launch_id != 0);
}
//////////////////////////////
//- rjf: record start
//
@@ -3048,13 +2713,21 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
//////////////////////////
//- rjf: on launches, detect entry points, place traps
//
if(launch_triggered && !launch_done_first_module && event->kind == DMN_EventKind_LoadModule)
if(msg->run_flags & CTRL_RunFlag_StopOnEntryPoint && !launch_done_first_module && event->kind == DMN_EventKind_HandshakeComplete)
{
launch_done_first_module = 1;
//- rjf: unpack process/module info
CTRL_Entity *process = ctrl_entity_from_machine_id_handle(ctrl_state->ctrl_thread_entity_store, CTRL_MachineID_Local, event->process);
CTRL_Entity *module = ctrl_entity_from_machine_id_handle(ctrl_state->ctrl_thread_entity_store, CTRL_MachineID_Local, event->module);
CTRL_Entity *module = &ctrl_entity_nil;
for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next)
{
if(child->kind == CTRL_EntityKind_Module)
{
module = child;
break;
}
}
U64 module_base_vaddr = module->vaddr_range.min;
String8 exe_path = module->string;
DBGI_Parse *dbgi = dbgi_parse_from_exe_path(scope, exe_path, max_U64);
@@ -3067,7 +2740,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
B32 entries_found = 0;
if(!entries_found)
{
for(String8Node *n = msg->strings.first; n != 0; n = n->next)
for(String8Node *n = msg->entry_points.first; n != 0; n = n->next)
{
U32 procedure_id = 0;
{
@@ -3144,7 +2817,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
{
entries_found = 1;
DMN_Trap trap = {process->handle, module_base_vaddr + voff};
dmn_trap_chunk_list_push(scratch.arena, &run_ctrls.traps, 256, &trap);
dmn_trap_chunk_list_push(scratch.arena, &entry_traps, 256, &trap);
}
}
}
+4 -5
View File
@@ -215,7 +215,7 @@ struct CTRL_UserBreakpointList
typedef enum CTRL_MsgKind
{
CTRL_MsgKind_Null,
CTRL_MsgKind_LaunchAndInit,
CTRL_MsgKind_Launch,
CTRL_MsgKind_Attach,
CTRL_MsgKind_Kill,
CTRL_MsgKind_Detach,
@@ -229,8 +229,7 @@ CTRL_MsgKind;
typedef U32 CTRL_RunFlags;
enum
{
CTRL_RunFlag_Launch = (1<<0),
CTRL_RunFlag_StopOnEntryPoint = (1<<1),
CTRL_RunFlag_StopOnEntryPoint = (1<<0),
};
typedef struct CTRL_Msg CTRL_Msg;
@@ -247,7 +246,7 @@ struct CTRL_Msg
B32 env_inherit;
U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64];
String8 path;
String8List strings;
String8List entry_points;
String8List cmd_line_string_list;
String8List env_string_list;
CTRL_TrapList traps;
@@ -715,7 +714,7 @@ internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_
internal B32 ctrl_eval_memory_read(void *u, void *out, U64 addr, U64 size);
//- rjf: msg kind implementations
internal void ctrl_thread__launch_and_init(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__attach(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__kill(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__detach(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
+29 -17
View File
@@ -3764,10 +3764,6 @@ df_push_ctrl_msg(CTRL_Msg *msg)
{
CTRL_Msg *dst = ctrl_msg_list_push(df_state->ctrl_msg_arena, &df_state->ctrl_msgs);
ctrl_msg_deep_copy(df_state->ctrl_msg_arena, dst, msg);
if(dst->kind == CTRL_MsgKind_LaunchAndInit)
{
df_state->ctrl_is_running = 1;
}
if(df_state->ctrl_soft_halt_issued == 0 && df_ctrl_targets_running())
{
df_state->ctrl_soft_halt_issued = 1;
@@ -3778,7 +3774,7 @@ df_push_ctrl_msg(CTRL_Msg *msg)
//- rjf: control thread running
internal void
df_ctrl_run(DF_RunKind run, DF_Entity *run_thread, CTRL_TrapList *run_traps)
df_ctrl_run(DF_RunKind run, DF_Entity *run_thread, CTRL_RunFlags flags, CTRL_TrapList *run_traps)
{
DBGI_Scope *scope = dbgi_scope_open();
Temp scratch = scratch_begin(0, 0);
@@ -3788,6 +3784,7 @@ df_ctrl_run(DF_RunKind run, DF_Entity *run_thread, CTRL_TrapList *run_traps)
{
DF_EntityList user_bps = df_query_cached_entity_list_with_kind(DF_EntityKind_Breakpoint);
DF_Entity *process = df_entity_ancestor_from_kind(run_thread, DF_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;
@@ -3887,6 +3884,7 @@ df_ctrl_run(DF_RunKind run, DF_Entity *run_thread, CTRL_TrapList *run_traps)
df_state->ctrl_last_run_kind = run;
df_state->ctrl_last_run_frame_idx = df_frame_index();
df_state->ctrl_last_run_thread = df_handle_from_entity(run_thread);
df_state->ctrl_last_run_flags = flags;
df_state->ctrl_last_run_traps = ctrl_trap_list_copy(df_state->ctrl_last_run_arena, &run_traps_copy);
df_state->ctrl_is_running = 1;
@@ -6599,6 +6597,19 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
df_cmd_list_push(arena, cmds, &params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectThread));
}
// rjf: if no stop-causing thread, and if selected thread, snap to selected
if(df_entity_is_nil(stop_thread))
{
DF_Entity *selected_thread = df_entity_from_handle(df_state->ctrl_ctx.thread);
if(!df_entity_is_nil(selected_thread))
{
DF_CmdParams params = df_cmd_params_zero();
params.entity = df_handle_from_entity(selected_thread);
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_Entity);
df_cmd_list_push(arena, cmds, &params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindThread));
}
}
// rjf: thread hit user breakpoint -> increment breakpoint hit count
if(event->cause == CTRL_EventCause_UserBreakpoint)
{
@@ -6888,6 +6899,9 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
if(!df_entity_is_nil(request_entity))
{
df_entity_mark_for_deletion(request_entity);
// TODO(rjf): @launch_and_init_x
#if 0
switch(request_entity->subkind)
{
case CTRL_MsgKind_LaunchAndInit:
@@ -6907,6 +6921,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
}
}break;
}
#endif
}
// rjf: collect stop info
@@ -7133,28 +7148,25 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
// rjf: build corresponding request entity
DF_Entity *request_entity = df_entity_alloc(0, df_entity_root(), DF_EntityKind_CtrlRequest);
{
request_entity->subkind = CTRL_MsgKind_LaunchAndInit;
request_entity->subkind = CTRL_MsgKind_Launch;
request_entity->entity_handle = df_handle_from_entity(target);
}
// rjf: push message to launch
{
CTRL_Msg msg = {CTRL_MsgKind_LaunchAndInit};
CTRL_Msg msg = {CTRL_MsgKind_Launch};
msg.msg_id = request_entity->id;
msg.path = path;
msg.cmd_line_string_list = cmdln_strings;
msg.env_inherit = 1;
MemoryCopyArray(msg.exception_code_filters, df_state->ctrl_exception_code_filters);
str8_list_push(scratch.arena, &msg.strings, entry);
str8_list_push(scratch.arena, &msg.entry_points, entry);
df_push_ctrl_msg(&msg);
}
}
// rjf: run if needed
if(core_cmd_kind == DF_CoreCmdKind_LaunchAndRun)
{
df_ctrl_run(DF_RunKind_Run, &df_g_nil_entity, 0);
}
// rjf: run
df_ctrl_run(DF_RunKind_Run, &df_g_nil_entity, CTRL_RunFlag_StopOnEntryPoint * (core_cmd_kind == DF_CoreCmdKind_LaunchAndInit), 0);
}
// rjf: no targets -> error
@@ -7258,7 +7270,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
}
if(good_to_run)
{
df_ctrl_run(DF_RunKind_Run, &df_g_nil_entity, 0);
df_ctrl_run(DF_RunKind_Run, &df_g_nil_entity, 0, 0);
}
else
{
@@ -7327,11 +7339,11 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
}
if(good && traps.count != 0)
{
df_ctrl_run(DF_RunKind_Step, thread, &traps);
df_ctrl_run(DF_RunKind_Step, thread, 0, &traps);
}
if(good && traps.count == 0)
{
df_ctrl_run(DF_RunKind_SingleStep, thread, &traps);
df_ctrl_run(DF_RunKind_SingleStep, thread, 0, &traps);
}
}
}break;
@@ -7344,7 +7356,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
{
if(df_ctrl_targets_running())
{
df_ctrl_run(df_state->ctrl_last_run_kind, df_entity_from_handle(df_state->ctrl_last_run_thread), &df_state->ctrl_last_run_traps);
df_ctrl_run(df_state->ctrl_last_run_kind, df_entity_from_handle(df_state->ctrl_last_run_thread), df_state->ctrl_last_run_flags, &df_state->ctrl_last_run_traps);
}
}break;
case DF_CoreCmdKind_SetThreadIP:
+2 -1
View File
@@ -1172,6 +1172,7 @@ struct DF_State
DF_RunKind ctrl_last_run_kind;
U64 ctrl_last_run_frame_idx;
DF_Handle ctrl_last_run_thread;
CTRL_RunFlags ctrl_last_run_flags;
CTRL_TrapList ctrl_last_run_traps;
U64 ctrl_run_gen;
B32 ctrl_is_running;
@@ -1567,7 +1568,7 @@ internal DF_Entity *df_log_from_entity(DF_Entity *entity);
internal void df_push_ctrl_msg(CTRL_Msg *msg);
//- rjf: control thread running
internal void df_ctrl_run(DF_RunKind run, DF_Entity *run_thread, CTRL_TrapList *run_traps);
internal void df_ctrl_run(DF_RunKind run, DF_Entity *target, DF_Entity *run_thread, CTRL_RunFlags flags, CTRL_TrapList *run_traps);
//- rjf: stopped info from the control thread
internal CTRL_Event df_ctrl_last_stop_event(void);