mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-17 06:41:27 -07:00
167 lines
4.4 KiB
C++
167 lines
4.4 KiB
C++
// Copyright (c) 2024 Epic Games Tools
|
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
|
|
|
#include "base/base_inc.h"
|
|
#include "os/os_inc.h"
|
|
#include "demon/demon_inc.h"
|
|
#include "syms_helpers/syms_internal_overrides.h"
|
|
#include "syms/syms_inc.h"
|
|
#include "syms_helpers/syms_helpers.h"
|
|
|
|
#include "base/base_inc.c"
|
|
#include "os/os_inc.c"
|
|
#include "demon/demon_inc.c"
|
|
#include "syms_helpers/syms_internal_overrides.c"
|
|
#include "syms/syms_inc.c"
|
|
#include "syms_helpers/syms_helpers.c"
|
|
|
|
internal SYMS_String8
|
|
file_load_func_for_syms(void *user, SYMS_Arena *arena, SYMS_String8 file_name){
|
|
String8 data = os_read_file(arena, str8_from_syms(file_name));
|
|
SYMS_String8 result = syms_from_str8(data);
|
|
return(result);
|
|
}
|
|
|
|
int
|
|
main(int argument_count, char **arguments)
|
|
{
|
|
os_init(argument_count, arguments);
|
|
Temp scratch = scratch_begin(0, 0);
|
|
|
|
// setup
|
|
demon_init();
|
|
|
|
// parse arguments
|
|
String8 executable_file_name = {0};
|
|
U64 bp_address = 0;
|
|
|
|
{
|
|
String8List command_line_arguments = os_get_command_line_arguments();
|
|
CmdLine cmd_line = cmd_line_from_string_list(scratch.arena, command_line_arguments);
|
|
if (cmd_line.inputs.first != 0){
|
|
executable_file_name = cmd_line.inputs.first->string;
|
|
}
|
|
String8 bp_string = cmd_line_string(cmd_line, str8_lit("bp"));
|
|
try_u64_from_str8_c_rules(bp_string, &bp_address);
|
|
}
|
|
|
|
// check parameters
|
|
if (bp_address == 0 || executable_file_name.size == 0){
|
|
printf("bad parameters\n");
|
|
exit(0);
|
|
}
|
|
|
|
// demon launch
|
|
OS_LaunchOptions launch_opts = {0};
|
|
str8_list_push(scratch.arena, &launch_opts.cmd_line, executable_file_name);
|
|
launch_opts.path = os_get_path(scratch.arena, OS_SystemPath_Current);
|
|
U32 process_id = demon_launch_process(&launch_opts);
|
|
if (process_id == 0){
|
|
printf("could not launch: '%.*s'\n", str8_varg(executable_file_name));
|
|
exit(0);
|
|
}
|
|
|
|
// demon loop
|
|
{
|
|
DEMON_Handle process = 0;
|
|
DEMON_Handle thread = 0;
|
|
|
|
B32 hit_bp = false;
|
|
U64 single_step_counter = 0;
|
|
|
|
U64 counter = 0;
|
|
for (;;){
|
|
Temp temp = temp_begin(scratch.arena);
|
|
|
|
DEMON_RunCtrls run_controls = {0};
|
|
DEMON_Trap traps[1];
|
|
|
|
if (!hit_bp){
|
|
if (process != 0){
|
|
run_controls.trap_count = 1;
|
|
run_controls.traps = traps;
|
|
run_controls.traps[0].process = process;
|
|
run_controls.traps[0].address = bp_address;
|
|
}
|
|
}
|
|
else{
|
|
run_controls.single_step_thread = thread;
|
|
}
|
|
|
|
DEMON_EventList events = demon_run(temp.arena, run_controls);
|
|
|
|
for (DEMON_Event *event = events.first;
|
|
event != 0;
|
|
event = event->next, counter += 1){
|
|
// update tracking state
|
|
switch (event->kind){
|
|
case DEMON_EventKind_CreateProcess:
|
|
{
|
|
process = event->process;
|
|
}break;
|
|
|
|
case DEMON_EventKind_ExitProcess:
|
|
{
|
|
if (event->process == process){
|
|
process = 0;
|
|
}
|
|
}break;
|
|
|
|
case DEMON_EventKind_CreateThread:
|
|
{
|
|
thread = event->thread;
|
|
}break;
|
|
|
|
case DEMON_EventKind_Breakpoint:
|
|
{
|
|
hit_bp = true;
|
|
}break;
|
|
|
|
case DEMON_EventKind_SingleStep:
|
|
{
|
|
single_step_counter += 1;
|
|
|
|
SYMS_RegX64 regs1 = {0};
|
|
demon_read_x64_regs(thread, ®s1);
|
|
demon_write_x64_regs(thread, ®s1);
|
|
SYMS_RegX64 regs2 = {0};
|
|
demon_read_x64_regs(thread, ®s2);
|
|
if (!MemoryMatchStruct(®s1, ®s2)){
|
|
printf("mismatch at single_step_counter=%llu\n", single_step_counter);
|
|
}
|
|
|
|
if (single_step_counter == 1000){
|
|
goto end_loop;
|
|
}
|
|
}break;
|
|
|
|
case DEMON_EventKind_NotAttached:
|
|
{
|
|
fprintf(stderr, "not attached - exiting\n");
|
|
goto end_loop;
|
|
}break;
|
|
|
|
case DEMON_EventKind_NotInitialized:
|
|
case DEMON_EventKind_UnexpectedFailure:
|
|
{
|
|
fprintf(stderr, "unexpected error - exiting\n");
|
|
goto end_loop;
|
|
}break;
|
|
}
|
|
}
|
|
|
|
goto end_it;
|
|
end_loop:
|
|
temp_end(temp);
|
|
goto loop_exit;
|
|
end_it:;
|
|
}
|
|
|
|
loop_exit:;
|
|
}
|
|
|
|
printf("[done]\n");
|
|
scratch_end(scratch);
|
|
}
|
|
|