mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-07 14:28:40 +00:00
organize demon2 by thread api
This commit is contained in:
+14
-18
@@ -172,28 +172,26 @@ internal U64 dmn_rsp_from_thread(DMN_Handle thread);
|
|||||||
internal void dmn_init(void);
|
internal void 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 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)
|
|
||||||
|
|
||||||
internal U32 dmn_launch_process(OS_LaunchOptions *options);
|
internal U32 dmn_launch_process(OS_LaunchOptions *options);
|
||||||
internal B32 dmn_attach_process(U32 pid);
|
internal B32 dmn_attach_process(U32 pid);
|
||||||
internal B32 dmn_kill_process(DMN_Handle process, U32 exit_code);
|
internal B32 dmn_kill_process(DMN_Handle process, U32 exit_code);
|
||||||
internal B32 dmn_detach_process(DMN_Handle process);
|
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
|
//- rjf: processes
|
||||||
internal U64 dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst);
|
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_read_reg_block(DMN_Handle handle, void *reg_block);
|
||||||
internal B32 dmn_thread_write_reg_block(DMN_Handle handle, void *reg_block);
|
internal B32 dmn_thread_write_reg_block(DMN_Handle handle, void *reg_block);
|
||||||
|
|
||||||
////////////////////////////////
|
//- rjf: system process listing
|
||||||
//~ rjf: @dmn_os_hooks System Process Listing (Implemented Per-OS)
|
|
||||||
|
|
||||||
internal void dmn_process_iter_begin(DMN_ProcessIter *iter);
|
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 B32 dmn_process_iter_next(Arena *arena, DMN_ProcessIter *iter, DMN_ProcessInfo *info_out);
|
||||||
internal void dmn_process_iter_end(DMN_ProcessIter *iter);
|
internal void dmn_process_iter_end(DMN_ProcessIter *iter);
|
||||||
|
|||||||
@@ -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
|
internal U32
|
||||||
dmn_run_gen(void)
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal U64
|
internal B32
|
||||||
dmn_mem_gen(void)
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal U64
|
internal B32
|
||||||
dmn_reg_gen(void)
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
internal B32
|
||||||
//~ rjf: @dmn_os_hooks Running/Halting (Implemented Per-OS)
|
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
|
internal DMN_EventList
|
||||||
dmn_run(Arena *arena, DMN_RunCtrls *ctrls)
|
dmn_run(Arena *arena, DMN_RunCtrls *ctrls)
|
||||||
@@ -2195,6 +2322,9 @@ dmn_run(Arena *arena, DMN_RunCtrls *ctrls)
|
|||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ rjf: @dmn_os_hooks Halting (Implemented Per-OS)
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
dmn_halt(U64 code, U64 user_data)
|
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
|
//- rjf: run/memory/register counters
|
||||||
dmn_launch_process(OS_LaunchOptions *options)
|
|
||||||
{
|
|
||||||
Temp scratch = scratch_begin(0, 0);
|
|
||||||
U32 result = 0;
|
|
||||||
|
|
||||||
//- rjf: produce exe / arguments string
|
internal U64
|
||||||
String8 cmd = {0};
|
dmn_run_gen(void)
|
||||||
if(options->cmd_line.first != 0)
|
|
||||||
{
|
{
|
||||||
String8List args = {0};
|
U64 result = ins_atomic_u64_eval(&dmn_w32_shared->run_gen);
|
||||||
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
internal U64
|
||||||
dmn_attach_process(U32 pid)
|
dmn_mem_gen(void)
|
||||||
{
|
{
|
||||||
B32 result = 0;
|
U64 result = ins_atomic_u64_eval(&dmn_w32_shared->mem_gen);
|
||||||
if(DebugActiveProcess((DWORD)pid))
|
|
||||||
{
|
|
||||||
result = 1;
|
|
||||||
dmn_w32_shared->new_process_pending = 1;
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
internal U64
|
||||||
dmn_kill_process(DMN_Handle process, U32 exit_code)
|
dmn_reg_gen(void)
|
||||||
{
|
{
|
||||||
B32 result = 0;
|
U64 result = ins_atomic_u64_eval(&dmn_w32_shared->reg_gen);
|
||||||
DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process);
|
|
||||||
if(TerminateProcess(process_entity->handle, exit_code))
|
|
||||||
{
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
return result;
|
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
|
//- rjf: processes
|
||||||
|
|
||||||
internal U64
|
internal U64
|
||||||
@@ -2466,8 +2465,7 @@ dmn_thread_write_reg_block(DMN_Handle handle, void *reg_block)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
//- rjf: system process listing
|
||||||
//~ rjf: @dmn_os_hooks System Process Listing (Implemented Per-OS)
|
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
dmn_process_iter_begin(DMN_ProcessIter *iter)
|
dmn_process_iter_begin(DMN_ProcessIter *iter)
|
||||||
|
|||||||
Reference in New Issue
Block a user