organize demon2 by thread api

This commit is contained in:
Ryan Fleury
2024-03-22 15:15:33 -07:00
parent ca01e66ea2
commit 07bbf1b43c
2 changed files with 169 additions and 175 deletions
+14 -18
View File
@@ -172,28 +172,26 @@ internal U64 dmn_rsp_from_thread(DMN_Handle thread);
internal void dmn_init(void);
////////////////////////////////
//~ rjf: @dmn_os_hooks Run/Memory/Register Counters
internal U64 dmn_run_gen(void);
internal U64 dmn_mem_gen(void);
internal U64 dmn_reg_gen(void);
////////////////////////////////
//~ rjf: @dmn_os_hooks Running/Halting (Implemented Per-OS)
internal DMN_EventList dmn_run(Arena *arena, DMN_RunCtrls *ctrls);
internal void dmn_halt(U64 code, U64 user_data);
////////////////////////////////
//~ rjf: @dmn_os_hooks Process Launching/Attaching/Killing/Detaching (Implemented Per-OS)
//~ rjf: @dmn_os_hooks Blocking Control Thread Operations (Implemented Per-OS)
internal U32 dmn_launch_process(OS_LaunchOptions *options);
internal B32 dmn_attach_process(U32 pid);
internal B32 dmn_kill_process(DMN_Handle process, U32 exit_code);
internal B32 dmn_detach_process(DMN_Handle process);
internal DMN_EventList dmn_run(Arena *arena, DMN_RunCtrls *ctrls);
////////////////////////////////
//~ rjf: @dmn_os_hooks Process/Thread Reads/Writes (Implemented Per-OS)
//~ rjf: @dmn_os_hooks Halting (Implemented Per-OS)
internal void dmn_halt(U64 code, U64 user_data);
////////////////////////////////
//~ rjf: @dmn_os_hooks Introspection Functions (Implemented Per-OS)
//- rjf: run/memory/register counters
internal U64 dmn_run_gen(void);
internal U64 dmn_mem_gen(void);
internal U64 dmn_reg_gen(void);
//- rjf: processes
internal U64 dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst);
@@ -208,9 +206,7 @@ internal U64 dmn_tls_root_vaddr_from_thread(DMN_Handle handle);
internal B32 dmn_thread_read_reg_block(DMN_Handle handle, void *reg_block);
internal B32 dmn_thread_write_reg_block(DMN_Handle handle, void *reg_block);
////////////////////////////////
//~ rjf: @dmn_os_hooks System Process Listing (Implemented Per-OS)
//- rjf: system process listing
internal void dmn_process_iter_begin(DMN_ProcessIter *iter);
internal B32 dmn_process_iter_next(Arena *arena, DMN_ProcessIter *iter, DMN_ProcessInfo *info_out);
internal void dmn_process_iter_end(DMN_ProcessIter *iter);
+155 -157
View File
@@ -1108,31 +1108,158 @@ dmn_init(void)
}
////////////////////////////////
//~ rjf: @dmn_os_hooks Run/Memory/Register Counters
//~ rjf: @dmn_os_hooks Blocking Control Thread Operations (Implemented Per-OS)
internal U64
dmn_run_gen(void)
internal U32
dmn_launch_process(OS_LaunchOptions *options)
{
U64 result = ins_atomic_u64_eval(&dmn_w32_shared->run_gen);
Temp scratch = scratch_begin(0, 0);
U32 result = 0;
//- rjf: produce exe / arguments string
String8 cmd = {0};
if(options->cmd_line.first != 0)
{
String8List args = {0};
String8 exe_path = options->cmd_line.first->string;
str8_list_pushf(scratch.arena, &args, "\"%S\"", exe_path);
for(String8Node *n = options->cmd_line.first->next; n != 0; n = n->next)
{
str8_list_push(scratch.arena, &args, n->string);
}
StringJoin join_params = {0};
join_params.sep = str8_lit(" ");
cmd = str8_list_join(scratch.arena, &args, &join_params);
}
//- rjf: produce environment strings
String8 env = {0};
{
String8List all_opts = options->env;
if(options->inherit_env != 0)
{
MemoryZeroStruct(&all_opts);
str8_list_push(scratch.arena, &all_opts, str8_lit("_NO_DEBUG_HEAP=1"));
for(String8Node *n = options->env.first; n != 0; n = n->next)
{
str8_list_push(scratch.arena, &all_opts, n->string);
}
for(String8Node *n = dmn_w32_shared->env_strings.first; n != 0; n = n->next)
{
str8_list_push(scratch.arena, &all_opts, n->string);
}
}
StringJoin join_params2 = {0};
join_params2.sep = str8_lit("\0");
join_params2.post = str8_lit("\0");
env = str8_list_join(scratch.arena, &all_opts, &join_params2);
}
//- rjf: produce utf-16 strings
String16 cmd16 = str16_from_8(scratch.arena, cmd);
String16 dir16 = str16_from_8(scratch.arena, options->path);
String16 env16 = str16_from_8(scratch.arena, env);
//- rjf: launch
DWORD access_flags = CREATE_UNICODE_ENVIRONMENT|DEBUG_PROCESS;
STARTUPINFOW startup_info = {sizeof(startup_info)};
PROCESS_INFORMATION process_info = {0};
AllocConsole();
if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, 1, access_flags, (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info))
{
// check if we are 32-bit app, and just close it immediately
BOOL is_wow = 0;
IsWow64Process(process_info.hProcess, &is_wow);
if(is_wow)
{
MessageBox(0, "Sorry, The RAD Debugger only debugs 64-bit applications currently.", "Process error", MB_OK|MB_ICONSTOP);
DebugActiveProcessStop(process_info.dwProcessId);
TerminateProcess(process_info.hProcess,0xffffffff);
}
else
{
result = process_info.dwProcessId;
dmn_w32_shared->new_process_pending = 1;
}
CloseHandle(process_info.hProcess);
CloseHandle(process_info.hThread);
}
else
{
MessageBox(0, "Error starting process.", "Process error", MB_OK|MB_ICONSTOP);
}
FreeConsole();
//- rjf: eliminate all handles which have stuck around from the AllocConsole
{
SetStdHandle(STD_INPUT_HANDLE, 0);
SetStdHandle(STD_OUTPUT_HANDLE, 0);
SetStdHandle(STD_ERROR_HANDLE, 0);
}
scratch_end(scratch);
return result;
}
internal U64
dmn_mem_gen(void)
internal B32
dmn_attach_process(U32 pid)
{
U64 result = ins_atomic_u64_eval(&dmn_w32_shared->mem_gen);
B32 result = 0;
if(DebugActiveProcess((DWORD)pid))
{
result = 1;
dmn_w32_shared->new_process_pending = 1;
}
return result;
}
internal U64
dmn_reg_gen(void)
internal B32
dmn_kill_process(DMN_Handle process, U32 exit_code)
{
U64 result = ins_atomic_u64_eval(&dmn_w32_shared->reg_gen);
B32 result = 0;
DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process);
if(TerminateProcess(process_entity->handle, exit_code))
{
result = 1;
}
return result;
}
////////////////////////////////
//~ rjf: @dmn_os_hooks Running/Halting (Implemented Per-OS)
internal B32
dmn_detach_process(DMN_Handle process)
{
B32 result = 0;
DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process);
// rjf: resume threads
for(DMN_W32_Entity *child = process_entity->first;
child != &dmn_w32_entity_nil;
child = child->next)
{
if(child->kind == DMN_W32_EntityKind_Thread)
{
DWORD resume_result = ResumeThread(child->handle);
(void)resume_result;
}
}
// rjf: detach
{
DWORD pid = (DWORD)process_entity->id;
if(DebugActiveProcessStop(pid))
{
result = 1;
}
}
// rjf: push into list of processes to generate events for later
if(result != 0)
{
dmn_handle_list_push(dmn_w32_shared->detach_arena, &dmn_w32_shared->detach_processes, process);
}
return result;
}
internal DMN_EventList
dmn_run(Arena *arena, DMN_RunCtrls *ctrls)
@@ -2195,6 +2322,9 @@ dmn_run(Arena *arena, DMN_RunCtrls *ctrls)
return events;
}
////////////////////////////////
//~ rjf: @dmn_os_hooks Halting (Implemented Per-OS)
internal void
dmn_halt(U64 code, U64 user_data)
{
@@ -2223,162 +2353,31 @@ dmn_halt(U64 code, U64 user_data)
}
////////////////////////////////
//~ rjf: @dmn_os_hooks Process Launching/Attaching/Killing/Detaching (Implemented Per-OS)
//~ rjf: @dmn_os_hooks Introspection Functions (Implemented Per-OS)
internal U32
dmn_launch_process(OS_LaunchOptions *options)
//- rjf: run/memory/register counters
internal U64
dmn_run_gen(void)
{
Temp scratch = scratch_begin(0, 0);
U32 result = 0;
//- rjf: produce exe / arguments string
String8 cmd = {0};
if(options->cmd_line.first != 0)
{
String8List args = {0};
String8 exe_path = options->cmd_line.first->string;
str8_list_pushf(scratch.arena, &args, "\"%S\"", exe_path);
for(String8Node *n = options->cmd_line.first->next; n != 0; n = n->next)
{
str8_list_push(scratch.arena, &args, n->string);
}
StringJoin join_params = {0};
join_params.sep = str8_lit(" ");
cmd = str8_list_join(scratch.arena, &args, &join_params);
}
//- rjf: produce environment strings
String8 env = {0};
{
String8List all_opts = options->env;
if(options->inherit_env != 0)
{
MemoryZeroStruct(&all_opts);
str8_list_push(scratch.arena, &all_opts, str8_lit("_NO_DEBUG_HEAP=1"));
for(String8Node *n = options->env.first; n != 0; n = n->next)
{
str8_list_push(scratch.arena, &all_opts, n->string);
}
for(String8Node *n = dmn_w32_shared->env_strings.first; n != 0; n = n->next)
{
str8_list_push(scratch.arena, &all_opts, n->string);
}
}
StringJoin join_params2 = {0};
join_params2.sep = str8_lit("\0");
join_params2.post = str8_lit("\0");
env = str8_list_join(scratch.arena, &all_opts, &join_params2);
}
//- rjf: produce utf-16 strings
String16 cmd16 = str16_from_8(scratch.arena, cmd);
String16 dir16 = str16_from_8(scratch.arena, options->path);
String16 env16 = str16_from_8(scratch.arena, env);
//- rjf: launch
DWORD access_flags = CREATE_UNICODE_ENVIRONMENT|DEBUG_PROCESS;
STARTUPINFOW startup_info = {sizeof(startup_info)};
PROCESS_INFORMATION process_info = {0};
AllocConsole();
if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, 1, access_flags, (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info))
{
// check if we are 32-bit app, and just close it immediately
BOOL is_wow = 0;
IsWow64Process(process_info.hProcess, &is_wow);
if(is_wow)
{
MessageBox(0, "Sorry, The RAD Debugger only debugs 64-bit applications currently.", "Process error", MB_OK|MB_ICONSTOP);
DebugActiveProcessStop(process_info.dwProcessId);
TerminateProcess(process_info.hProcess,0xffffffff);
}
else
{
result = process_info.dwProcessId;
dmn_w32_shared->new_process_pending = 1;
}
CloseHandle(process_info.hProcess);
CloseHandle(process_info.hThread);
}
else
{
MessageBox(0, "Error starting process.", "Process error", MB_OK|MB_ICONSTOP);
}
FreeConsole();
//- rjf: eliminate all handles which have stuck around from the AllocConsole
{
SetStdHandle(STD_INPUT_HANDLE, 0);
SetStdHandle(STD_OUTPUT_HANDLE, 0);
SetStdHandle(STD_ERROR_HANDLE, 0);
}
scratch_end(scratch);
U64 result = ins_atomic_u64_eval(&dmn_w32_shared->run_gen);
return result;
}
internal B32
dmn_attach_process(U32 pid)
internal U64
dmn_mem_gen(void)
{
B32 result = 0;
if(DebugActiveProcess((DWORD)pid))
{
result = 1;
dmn_w32_shared->new_process_pending = 1;
}
U64 result = ins_atomic_u64_eval(&dmn_w32_shared->mem_gen);
return result;
}
internal B32
dmn_kill_process(DMN_Handle process, U32 exit_code)
internal U64
dmn_reg_gen(void)
{
B32 result = 0;
DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process);
if(TerminateProcess(process_entity->handle, exit_code))
{
result = 1;
}
U64 result = ins_atomic_u64_eval(&dmn_w32_shared->reg_gen);
return result;
}
internal B32
dmn_detach_process(DMN_Handle process)
{
B32 result = 0;
DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process);
// rjf: resume threads
for(DMN_W32_Entity *child = process_entity->first;
child != &dmn_w32_entity_nil;
child = child->next)
{
if(child->kind == DMN_W32_EntityKind_Thread)
{
DWORD resume_result = ResumeThread(child->handle);
(void)resume_result;
}
}
// rjf: detach
{
DWORD pid = (DWORD)process_entity->id;
if(DebugActiveProcessStop(pid))
{
result = 1;
}
}
// rjf: push into list of processes to generate events for later
if(result != 0)
{
dmn_handle_list_push(dmn_w32_shared->detach_arena, &dmn_w32_shared->detach_processes, process);
}
return result;
}
////////////////////////////////
//~ rjf: @dmn_os_hooks Process/Thread Reads/Writes (Implemented Per-OS)
//- rjf: processes
internal U64
@@ -2466,8 +2465,7 @@ dmn_thread_write_reg_block(DMN_Handle handle, void *reg_block)
return result;
}
////////////////////////////////
//~ rjf: @dmn_os_hooks System Process Listing (Implemented Per-OS)
//- rjf: system process listing
internal void
dmn_process_iter_begin(DMN_ProcessIter *iter)