From 4f5e795ae9c8d0197dc234f09e7c35f1a6053786 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 7 Oct 2026 12:58:24 -0600 Subject: [PATCH] dbg_server, remote controller connections checkpoint --- project.4coder | 2 +- src/dbg_engine/dbg_engine.mdesk | 4 + src/dbg_engine/dbg_engine_ctrl.c | 4 + src/dbg_engine/dbg_engine_user.c | 18 +++ src/dbg_engine/dbg_engine_user.h | 2 + src/dbg_engine/generated/dbg_engine.meta.h | 2 + .../dbg_server.c} | 21 +++- src/dbg_server/dbg_server.h | 118 ++++++++++++++++++ src/dbg_server/dbg_server_client.c | 24 ++++ src/dbg_server/dbg_server_client.h | 13 ++ src/dbg_server/dbg_server_host.c | 28 +++++ src/dbg_server/dbg_server_host.h | 15 +++ src/dbg_server/dbg_server_remote.c | 2 + src/dbg_server/dbg_server_remote.h | 7 ++ src/raddbg/generated/raddbg.meta.c | 12 +- src/raddbg/generated/raddbg.meta.h | 6 +- src/raddbg/raddbg.mdesk | 4 +- src/raddbg/raddbg_core.c | 60 ++++++++- src/raddbg/raddbg_main.c | 7 ++ src/raddbg_server/raddbg_server.h | 99 --------------- 20 files changed, 338 insertions(+), 110 deletions(-) rename src/{raddbg_server/raddbg_server.c => dbg_server/dbg_server.c} (87%) create mode 100644 src/dbg_server/dbg_server.h create mode 100644 src/dbg_server/dbg_server_client.c create mode 100644 src/dbg_server/dbg_server_client.h create mode 100644 src/dbg_server/dbg_server_host.c create mode 100644 src/dbg_server/dbg_server_host.h create mode 100644 src/dbg_server/dbg_server_remote.c create mode 100644 src/dbg_server/dbg_server_remote.h delete mode 100644 src/raddbg_server/raddbg_server.h diff --git a/project.4coder b/project.4coder index a6fa152c..360ba491 100644 --- a/project.4coder +++ b/project.4coder @@ -49,7 +49,7 @@ commands = // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry debug", .linux = "./build.sh raddbg debug", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry debug", .linux = "./build.sh raddbg debug meta", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [raddbg wsl] // .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/dbg_engine/dbg_engine.mdesk b/src/dbg_engine/dbg_engine.mdesk index cbcf517e..df8d4e09 100644 --- a/src/dbg_engine/dbg_engine.mdesk +++ b/src/dbg_engine/dbg_engine.mdesk @@ -58,6 +58,10 @@ D_CmdTable: // | | | //- rjf: crash dump opening {OpenCrashDump 1 1 `folder:\\"$input\\"` FilePath 0 0 0 0 0 1 1 FileOutline "open_crash_dump" "Open Crash Dump" "Opens a crash dump file and recreates debuggee state at the time of the crash." "" "" } + + //- rjf: remote debugger connecting + {OpenRemoteDebugger 1 1 "" String 0 0 0 0 0 1 1 Machine "open_remote_debugger" "Open Remote Debugger" "Opens a remote debugger by IP address." "" "" } + {CloseRemoteDebugger 1 1 "query:machines" CtrlEntity 0 0 0 0 0 1 1 Machine "close_remote_debugger" "Close Remote Debugger" "Closes a remote debugger." "" "" } } @enum D_CmdKind: diff --git a/src/dbg_engine/dbg_engine_ctrl.c b/src/dbg_engine/dbg_engine_ctrl.c index 8eafd57c..1b5ba1c7 100644 --- a/src/dbg_engine/dbg_engine_ctrl.c +++ b/src/dbg_engine/dbg_engine_ctrl.c @@ -2527,6 +2527,10 @@ d_ctrl_thread__entry_point(void *p) case D_MsgKind_Null: case D_MsgKind_COUNT:{}break; + //- rjf: remote debuggers + case D_MsgKind_OpenRemoteDebugger:{}break; + case D_MsgKind_CloseRemoteDebugger:{}break; + //- rjf: target operations case D_MsgKind_Launch: {d_ctrl_thread__launch (ctrl_ctx, msg);}break; case D_MsgKind_Attach: {d_ctrl_thread__attach (ctrl_ctx, msg);}break; diff --git a/src/dbg_engine/dbg_engine_user.c b/src/dbg_engine/dbg_engine_user.c index 8a9215ac..e11e2b50 100644 --- a/src/dbg_engine/dbg_engine_user.c +++ b/src/dbg_engine/dbg_engine_user.c @@ -2191,6 +2191,24 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P MemoryCopyArray(msg->exception_code_filters, exception_code_filters); msg->auto_download_debug_info = auto_download_debug_info; }break; + + //- rjf: opening/closing remote debuggers + case D_CmdKind_OpenRemoteDebugger: + { + D_Msg *msg = d_msg_list_push(scratch.arena, &ctrl_msgs); + msg->kind = D_MsgKind_OpenRemoteDebugger; + msg->path = str8_copy(scratch.arena, params->string); + MemoryCopyArray(msg->exception_code_filters, exception_code_filters); + msg->auto_download_debug_info = auto_download_debug_info; + }break; + case D_CmdKind_CloseRemoteDebugger: + { + D_Msg *msg = d_msg_list_push(scratch.arena, &ctrl_msgs); + msg->kind = D_MsgKind_CloseRemoteDebugger; + msg->entity = params->entity; + MemoryCopyArray(msg->exception_code_filters, exception_code_filters); + msg->auto_download_debug_info = auto_download_debug_info; + }break; } // rjf: do run if needed diff --git a/src/dbg_engine/dbg_engine_user.h b/src/dbg_engine/dbg_engine_user.h index 7cf59551..c4efad3b 100644 --- a/src/dbg_engine/dbg_engine_user.h +++ b/src/dbg_engine/dbg_engine_user.h @@ -160,6 +160,8 @@ struct D_RunLocalsCache typedef enum D_MsgKind { D_MsgKind_Null, + D_MsgKind_OpenRemoteDebugger, + D_MsgKind_CloseRemoteDebugger, D_MsgKind_Launch, D_MsgKind_Attach, D_MsgKind_OpenCrashDump, diff --git a/src/dbg_engine/generated/dbg_engine.meta.h b/src/dbg_engine/generated/dbg_engine.meta.h index 2391d4d2..e3943a97 100644 --- a/src/dbg_engine/generated/dbg_engine.meta.h +++ b/src/dbg_engine/generated/dbg_engine.meta.h @@ -45,6 +45,8 @@ D_CmdKind_SetEntityName, D_CmdKind_DownloadModuleDebugInfo, D_CmdKind_Attach, D_CmdKind_OpenCrashDump, +D_CmdKind_OpenRemoteDebugger, +D_CmdKind_CloseRemoteDebugger, D_CmdKind_COUNT, } D_CmdKind; diff --git a/src/raddbg_server/raddbg_server.c b/src/dbg_server/dbg_server.c similarity index 87% rename from src/raddbg_server/raddbg_server.c rename to src/dbg_server/dbg_server.c index 96e81200..9dce96f0 100644 --- a/src/raddbg_server/raddbg_server.c +++ b/src/dbg_server/dbg_server.c @@ -4,16 +4,16 @@ //////////////////////////////// //~ rjf: Message Parsing -internal RDS_Msg -rds_msg_from_data(Arena *arena, String8 data) +internal DS_Msg +ds_msg_from_serialized(Arena *arena, String8 data) { //- rjf: unpack message U16 magic_maybe = 0; str8_deserial_read_struct(data, 0, &magic_maybe); //- rjf: parse message - RDS_Msg msg = {0}; - if(magic_maybe == RDS_MSG_MAGIC) + DS_Msg msg = {0}; + if(magic_maybe == DS_MSG_MAGIC) { U64 off = sizeof(magic_maybe); @@ -79,3 +79,16 @@ rds_msg_from_data(Arena *arena, String8 data) return msg; } + +internal String8 +ds_serialized_from_msg(Arena *arena, DS_Msg *msg) +{ + Temp scratch = scratch_begin(&arena, 1); + String8List srl = {0}; + { + // TODO(rjf) + } + scratch_end(scratch); + String8 result = str8_list_join(arena, &srl, 0); + return result; +} diff --git a/src/dbg_server/dbg_server.h b/src/dbg_server/dbg_server.h new file mode 100644 index 00000000..7f1520c0 --- /dev/null +++ b/src/dbg_server/dbg_server.h @@ -0,0 +1,118 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef DBG_SERVER_H +#define DBG_SERVER_H + +//////////////////////////////// +//~ rjf: Messages (Client -> Server) + +#define DS_MSG_MAGIC 0x7273 + +typedef enum DS_MsgKind +{ + DS_MsgKind_Null, + + //- rjf: debuggee attaching/detaching ops + DS_MsgKind_Launch, + DS_MsgKind_Attach, + DS_MsgKind_Kill, + DS_MsgKind_Detach, + + //- rjf: running ops + DS_MsgKind_Run, + DS_MsgKind_SingleStep, + + //- rjf: halting + DS_MsgKind_Halt, + + //- rjf: memory ops + DS_MsgKind_MemoryReserve, + DS_MsgKind_MemoryCommit, + DS_MsgKind_MemoryDecommit, + DS_MsgKind_MemoryRelease, + DS_MsgKind_MemoryProtect, + DS_MsgKind_MemoryRead, + DS_MsgKind_MemoryWrite, + + //- rjf: thread ops + DS_MsgKind_ThreadRegBlockRead, + DS_MsgKind_ThreadRegBlockWrite, + DS_MsgKind_ThreadGetModuleTLSVAddr, + + //- rjf: system ops + DS_MsgKind_ListSystemProcesses, +} +DS_MsgKind; + +typedef U32 DS_MsgFlags; +enum +{ + DS_MsgFlag_InheritEnv = (1<<0), + DS_MsgFlag_DebugSubprocesses = (1<<1), + DS_MsgFlag_IgnorePreviousException = (1<<2), + DS_MsgFlag_RunEntitiesAreUnfrozen = (1<<3), + DS_MsgFlag_RunEntitiesAreProcesses = (1<<4), +}; + +typedef struct DS_Msg DS_Msg; +struct DS_Msg +{ + DS_MsgKind kind; + DS_MsgFlags flags; + U64 id; + + //- rjf: general parameters + Rng1U64 vaddr_range; + AccessFlags access_flags; + DMN_Handle entity; + U64 pid; + + //- rjf: process launching parameters + String8List command_line; + String8 path; + String8List env; + + //- rjf: running parameters + DMN_TrapChunkList traps; + DMN_HandleArray run_entities; +}; + +//////////////////////////////// +//~ rjf: Server Instance + +typedef enum DS_InstKind +{ + DS_InstKind_Host, + DS_InstKind_Remote, +} +DS_InstKind; + +typedef struct DS_Inst DS_Inst; +struct DS_Inst +{ + DS_InstKind kind; + U64 u64[1]; +}; + +//////////////////////////////// +//~ rjf: Responses (Server -> Client responses to messages) + +typedef struct DS_Response DS_Response; +struct DS_Response +{ + U64 id; + DS_Inst inst; + String8 data; + DMN_Handle entity; + U64 pid; + DMN_EventList events; +}; + +//////////////////////////////// +//~ rjf: Message Parsing + +internal DS_Msg ds_msg_from_serialized(Arena *arena, String8 data); +internal String8 ds_serialized_from_msg(Arena *arena, DS_Msg msg); + +#endif // DBG_SERVER_H diff --git a/src/dbg_server/dbg_server_client.c b/src/dbg_server/dbg_server_client.c new file mode 100644 index 00000000..7d253777 --- /dev/null +++ b/src/dbg_server/dbg_server_client.c @@ -0,0 +1,24 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal B32 +ds_push_msg(GuardedRing *out_ring, DS_Inst inst, DS_Msg *msg, U64 endt_us) +{ + B32 result = 0; + switch(inst.kind) + { + default:{}break; + case DS_InstKind_Host: + { + result = ds_push_msg__host(out_ring, msg, endt_us); + }break; + } + return result; +} + +internal B32 +ds_pop_response(Arena *arena, GuardedRing *out_ring, DS_Response *response_out, U64 endt_us) +{ + B32 result = 0; + return result; +} diff --git a/src/dbg_server/dbg_server_client.h b/src/dbg_server/dbg_server_client.h new file mode 100644 index 00000000..cffb3eca --- /dev/null +++ b/src/dbg_server/dbg_server_client.h @@ -0,0 +1,13 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef DBG_SERVER_CLIENT_H +#define DBG_SERVER_CLIENT_H + +//////////////////////////////// +//~ rjf: Messages/Responses + +internal B32 ds_push_msg(GuardedRing *out_ring, DS_Inst inst, DS_Msg *msg, U64 endt_us); +internal B32 ds_pop_response(Arena *arena, GuardedRing *out_ring, DS_Response *response_out, U64 endt_us); + +#endif // DBG_SERVER_CLIENT_H diff --git a/src/dbg_server/dbg_server_host.c b/src/dbg_server/dbg_server_host.c new file mode 100644 index 00000000..4b9e5811 --- /dev/null +++ b/src/dbg_server/dbg_server_host.c @@ -0,0 +1,28 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal B32 +ds_push_msg__host(GuardedRing *out_ring, DS_Msg *msg, U64 endt_us) +{ + B32 result = 1; + switch(msg->kind) + { + default:{}break; + + //- rjf: launching + case DS_MsgKind_Launch: + { + ProcessLaunchParams params = {0}; + { + params.cmd_line = msg->command_line; + params.path = msg->path; + params.env = msg->env; + params.inherit_env = !!(msg->flags & DS_MsgFlag_InheritEnv); + params.debug_subprocesses = !!(msg->flags & DS_MsgFlag_DebugSubprocesses); + } + U32 pid = dmn_ctrl_launch(0, ¶ms); + }break; + + } + return result; +} diff --git a/src/dbg_server/dbg_server_host.h b/src/dbg_server/dbg_server_host.h new file mode 100644 index 00000000..1e6a8e67 --- /dev/null +++ b/src/dbg_server/dbg_server_host.h @@ -0,0 +1,15 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef DBG_SERVER_HOST_H +#define DBG_SERVER_HOST_H + +typedef struct DS_HostState DS_HostState; +struct DS_HostState +{ + Arena *arena; +}; + +internal B32 ds_push_msg__host(GuardedRing *out_ring, DS_Msg *msg, U64 endt_us); + +#endif // DBG_SERVER_HOST_H diff --git a/src/dbg_server/dbg_server_remote.c b/src/dbg_server/dbg_server_remote.c new file mode 100644 index 00000000..ae447aab --- /dev/null +++ b/src/dbg_server/dbg_server_remote.c @@ -0,0 +1,2 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) diff --git a/src/dbg_server/dbg_server_remote.h b/src/dbg_server/dbg_server_remote.h new file mode 100644 index 00000000..9cb853c2 --- /dev/null +++ b/src/dbg_server/dbg_server_remote.h @@ -0,0 +1,7 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef DBG_SERVER_REMOTE_H +#define DBG_SERVER_REMOTE_H + +#endif // DBG_SERVER_REMOTE_H diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 87f97090..cbe210e7 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -62,7 +62,7 @@ str8_lit_comp(""), str8_lit_comp(""), }; -RD_VocabInfo rd_vocab_info_table[370] = +RD_VocabInfo rd_vocab_info_table[374] = { {str8_lit_comp("type_view"), str8_lit_comp("type_views"), str8_lit_comp("Type View"), str8_lit_comp("Type Views"), RD_IconKind_Binoculars}, {str8_lit_comp("file_path_map"), str8_lit_comp("file_path_maps"), str8_lit_comp("File Path Map"), str8_lit_comp("File Path Maps"), RD_IconKind_FileOutline}, @@ -214,6 +214,8 @@ RD_VocabInfo rd_vocab_info_table[370] = {str8_lit_comp("download_module_debug_info"), str8_lit_comp(""), str8_lit_comp("Download Module Debug Info"), str8_lit_comp(""), RD_IconKind_Module}, {str8_lit_comp("attach"), str8_lit_comp(""), str8_lit_comp("Attach"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("open_crash_dump"), str8_lit_comp(""), str8_lit_comp("Open Crash Dump"), str8_lit_comp(""), RD_IconKind_FileOutline}, +{str8_lit_comp("open_remote_debugger"), str8_lit_comp(""), str8_lit_comp("Open Remote Debugger"), str8_lit_comp(""), RD_IconKind_Machine}, +{str8_lit_comp("close_remote_debugger"), str8_lit_comp(""), str8_lit_comp("Close Remote Debugger"), str8_lit_comp(""), RD_IconKind_Machine}, {str8_lit_comp("exit"), str8_lit_comp(""), str8_lit_comp("Exit"), str8_lit_comp(""), RD_IconKind_X}, {str8_lit_comp("open_palette"), str8_lit_comp(""), str8_lit_comp("Open Palette"), str8_lit_comp(""), RD_IconKind_List}, {str8_lit_comp("run_command"), str8_lit_comp(""), str8_lit_comp("Run Command"), str8_lit_comp(""), RD_IconKind_Null}, @@ -221,6 +223,8 @@ RD_VocabInfo rd_vocab_info_table[370] = {str8_lit_comp("state"), str8_lit_comp(""), str8_lit_comp("State"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("eval"), str8_lit_comp(""), str8_lit_comp("Eval"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("line_from_vaddr"), str8_lit_comp(""), str8_lit_comp("Line From Virtual Address"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("remote_controller_connect"), str8_lit_comp(""), str8_lit_comp("Remote Controller Connect"), str8_lit_comp(""), RD_IconKind_Null}, +{str8_lit_comp("remote_controller_connect"), str8_lit_comp(""), str8_lit_comp("Remote Controller Connect"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("wm_event"), str8_lit_comp(""), str8_lit_comp("OS Event"), str8_lit_comp(""), RD_IconKind_Null}, {str8_lit_comp("select_thread"), str8_lit_comp(""), str8_lit_comp("Select Thread"), str8_lit_comp(""), RD_IconKind_Thread}, {str8_lit_comp("select_unwind"), str8_lit_comp(""), str8_lit_comp("Select Unwind"), str8_lit_comp(""), RD_IconKind_Null}, @@ -599,7 +603,7 @@ Rng1U64 rd_reg_slot_range_table[56] = {OffsetOf(RD_Regs, wm_event), OffsetOf(RD_Regs, wm_event) + sizeof(WM_Event *)}, }; -RD_CmdKindInfo rd_cmd_kind_info_table[257] = +RD_CmdKindInfo rd_cmd_kind_info_table[261] = { {0}, { str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Cfg, str8_lit_comp("query:targets")}}, @@ -638,6 +642,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[257] = { str8_lit_comp("download_module_debug_info"), str8_lit_comp("Tries to download a module's debug info from symbol server(s)."), str8_lit_comp(""), str8_lit_comp("{module_commands}"), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CtrlEntity, str8_lit_comp("query:modules")}}, { str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_PID, str8_lit_comp("query:unattached_processes")}}, { str8_lit_comp("open_crash_dump"), str8_lit_comp("Opens a crash dump file and recreates debuggee state at the time of the crash."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_FilePath, str8_lit_comp("folder:\"$input\"")}}, +{ str8_lit_comp("open_remote_debugger"), str8_lit_comp("Opens a remote debugger by IP address."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_String, str8_lit_comp("")}}, +{ str8_lit_comp("close_remote_debugger"), str8_lit_comp("Closes a remote debugger."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CtrlEntity, str8_lit_comp("query:machines")}}, { str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}}, { str8_lit_comp("open_palette"), str8_lit_comp("Opens the palette."), str8_lit_comp("help,cmd,lister"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}}, { str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_CmdName, str8_lit_comp("query:commands")}}, @@ -645,6 +651,8 @@ RD_CmdKindInfo rd_cmd_kind_info_table[257] = { str8_lit_comp("state"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}}, { str8_lit_comp("eval"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Expr, str8_lit_comp("")}}, { str8_lit_comp("line_from_vaddr"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Vaddr, str8_lit_comp("")}}, +{ str8_lit_comp("remote_controller_connect"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}}, +{ str8_lit_comp("remote_controller_connect"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}}, { str8_lit_comp("wm_event"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*0), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("")}}, { str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*1)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*1)|(RD_QueryFlag_Required*1), RD_RegSlot_Thread, str8_lit_comp("query:threads")}}, { str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp(""), (RD_CmdKindFlag_ListInUI*0)|(RD_CmdKindFlag_ListInIPCDocs*1), {(RD_QueryFlag_AllowFiles*0)|(RD_QueryFlag_AllowFolders*0)|(RD_QueryFlag_CodeInput*0)|(RD_QueryFlag_KeepOldInput*0)|(RD_QueryFlag_SelectOldInput*0)|(RD_QueryFlag_Floating*0)|(RD_QueryFlag_Required*0), RD_RegSlot_Null, str8_lit_comp("query:call_stack")}}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index 8ce32f7e..950f11d3 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -106,6 +106,8 @@ RD_CmdKind_SetEntityName, RD_CmdKind_DownloadModuleDebugInfo, RD_CmdKind_Attach, RD_CmdKind_OpenCrashDump, +RD_CmdKind_OpenRemoteDebugger, +RD_CmdKind_CloseRemoteDebugger, RD_CmdKind_Exit, RD_CmdKind_OpenPalette, RD_CmdKind_RunCommand, @@ -113,6 +115,8 @@ RD_CmdKind_RunExternalDriverTextCommand, RD_CmdKind_State, RD_CmdKind_Eval, RD_CmdKind_LineFromVAddr, +RD_CmdKind_RemoteControllerConnect, +RD_CmdKind_RemoteControllerDisconnect, RD_CmdKind_WMEvent, RD_CmdKind_SelectThread, RD_CmdKind_SelectUnwind, @@ -630,7 +634,7 @@ Z(getting_started)\ C_LINKAGE_BEGIN extern String8 rd_tab_fast_path_view_name_table[25]; extern String8 rd_tab_fast_path_query_name_table[25]; -extern RD_VocabInfo rd_vocab_info_table[370]; +extern RD_VocabInfo rd_vocab_info_table[374]; extern RD_NameSchemaInfo rd_name_schema_info_table[39]; extern String8 rd_reg_slot_code_name_table[56]; extern Rng1U64 rd_reg_slot_range_table[56]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 5dbf075f..836bff3e 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -1046,7 +1046,9 @@ RD_CmdTable: // | | | | {State 0 0 1 "" Null 0 0 0 0 0 0 0 Null "state" "State" "" "" "" } {Eval 0 0 1 "" Expr 0 0 0 0 0 0 0 Null "eval" "Eval" "" "" "" } {LineFromVAddr 0 0 1 "" Vaddr 0 0 0 0 0 0 0 Null "line_from_vaddr" "Line From Virtual Address" "" "" "" } - + {RemoteControllerConnect 0 0 1 "" Null 0 0 0 0 0 0 0 Null "remote_controller_connect" "Remote Controller Connect" "" "" "" } + {RemoteControllerDisconnect 0 0 1 "" Null 0 0 0 0 0 0 0 Null "remote_controller_connect" "Remote Controller Connect" "" "" "" } + //- rjf: os event passthrough {WMEvent 0 0 0 "" Null 0 0 0 0 0 0 0 Null "wm_event" "OS Event" "" "" "" } diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index a992380a..1e1dfd1c 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -7903,12 +7903,50 @@ rd_window_frame(void) } } + // rjf: remote controller viz + { + CFG_Node *root = cfg_node_root(); + CFG_Node *transient = cfg_node_child_from_string(root, s("transient")); + CFG_NodePtrList remote_controllers = cfg_node_child_list_from_string(scratch.arena, transient, s("remote_controller")); + for EachNode(n, CFG_NodePtrNode, remote_controllers.first) + { + CFG_Node *rc = n->v; + String8 ip_addr = rc->first->string; + UI_VisualMargin(ui_top_font_size()*0.5f) + UI_CornerRadius(ui_top_font_size()*0.5f) + { + ui_set_next_pref_width(ui_children_sum(1)); + ui_set_next_child_layout_axis(Axis2_X); + UI_Box *rc_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable| + UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawHotEffects| + UI_BoxFlag_DrawActiveEffects, + "###rc_button"); + wm_window_push_custom_title_bar_client_area(ws->os, rc_box->rect); + UI_Parent(rc_box) + UI_PrefWidth(ui_text_dim(10, 0)) + UI_TextAlignment(UI_TextAlign_Center) + UI_Padding(ui_em(0.5f, 1.f)) + RD_Font(RD_FontSlot_Icons) + UI_TagF("pop") + { + ui_label(rd_icon_kind_text_table[RD_IconKind_Machine]); + } + UI_Signal rc_sig = ui_signal_from_box(rc_box); + if(ui_hovering(rc_sig)) UI_Tooltip + { + ui_label(ip_addr); + } + } + } + } + // rjf: loaded project viz if(do_user_prof) { CFG_Node *root = cfg_node_root(); - CFG_Node *project = cfg_node_child_from_string(root, str8_lit("project")); - CFG_Node *name = cfg_node_child_from_string(project, str8_lit("name")); + CFG_Node *project = cfg_node_child_from_string(root, s("project")); + CFG_Node *name = cfg_node_child_from_string(project, s("name")); String8 project_name = name->first->string; if(project_name.size == 0) { @@ -13934,6 +13972,24 @@ rd_frame(void) } str8_list_pushf(rd_state->cmd_output_arena, &rd_state->cmd_outputs, "}\n"); }break; + case RD_CmdKind_RemoteControllerConnect: + { + CFG_Node *transient = cfg_node_child_from_string(cfg_node_root(), s("transient")); + CFG_Node *ctrlr = cfg_node_new(rd_state->cfg, transient, s("remote_controller")); + cfg_node_new(rd_state->cfg, ctrlr, rd_regs()->string); + }break; + case RD_CmdKind_RemoteControllerDisconnect: + { + CFG_Node *transient = cfg_node_child_from_string(cfg_node_root(), s("transient")); + for(CFG_Node *child = transient; child != &cfg_nil_node; child = child->next) + { + if(str8_match(child->string, s("remote_controller"), 0) && str8_match(child->first->string, rd_regs()->string, 0)) + { + cfg_node_release(rd_state->cfg, child); + break; + } + } + }break; //- rjf: exiting case RD_CmdKind_Exit: diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 4b6dd33a..139750f7 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -1,6 +1,13 @@ // Copyright (c) Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +//////////////////////////////// +//~ rjf: remote TODO notes +// +// [ ] ui -> ui? +// [ ] ui (w/ debug info) -> ui (w/out debug info)? +// [ ] ctrl -> slim server? + //////////////////////////////// //~ rjf: linux TODO notes // diff --git a/src/raddbg_server/raddbg_server.h b/src/raddbg_server/raddbg_server.h deleted file mode 100644 index 47b0fc51..00000000 --- a/src/raddbg_server/raddbg_server.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RADDBG_SERVER_H -#define RADDBG_SERVER_H - -//////////////////////////////// -//~ rjf: Messages (Client -> Server) - -#define RDS_MSG_MAGIC 0x7273 - -typedef enum RDS_MsgKind -{ - RDS_MsgKind_Null, - - //- rjf: debuggee attaching/detaching ops - RDS_MsgKind_Launch, RDS_MsgKind_DemonThreadHandledFirst = RDS_MsgKind_Launch, - RDS_MsgKind_Attach, - RDS_MsgKind_Kill, - RDS_MsgKind_Detach, - - //- rjf: running ops - RDS_MsgKind_Run, - RDS_MsgKind_SingleStep, RDS_MsgKind_DemonThreadHandledLast = RDS_MsgKind_SingleStep, - - //- rjf: halting - RDS_MsgKind_Halt, - - //- rjf: memory ops - RDS_MsgKind_MemoryReserve, - RDS_MsgKind_MemoryCommit, - RDS_MsgKind_MemoryDecommit, - RDS_MsgKind_MemoryRelease, - RDS_MsgKind_MemoryProtect, - RDS_MsgKind_MemoryRead, - RDS_MsgKind_MemoryWrite, - - //- rjf: thread ops - RDS_MsgKind_ThreadRegBlockRead, - RDS_MsgKind_ThreadRegBlockWrite, - RDS_MsgKind_ThreadGetModuleTLSVAddr, - - //- rjf: system ops - RDS_MsgKind_ListSystemProcesses, -} -RDS_MsgKind; - -typedef U32 RDS_MsgFlags; -enum -{ - RDS_MsgFlag_InheritEnv = (1<<0), - RDS_MsgFlag_DebugSubprocesses = (1<<1), - RDS_MsgFlag_IgnorePreviousException = (1<<2), - RDS_MsgFlag_RunEntitiesAreUnfrozen = (1<<3), - RDS_MsgFlag_RunEntitiesAreProcesses = (1<<4), -}; - -typedef struct RDS_Msg RDS_Msg; -struct RDS_Msg -{ - RDS_MsgKind kind; - RDS_MsgFlags flags; - U64 id; - - //- rjf: general parameters - Rng1U64 vaddr_range; - AccessFlags access_flags; - DMN_Handle entity; - U64 pid; - - //- rjf: process launching parameters - String8List command_line; - String8 path; - String8List env; - - //- rjf: running parameters - DMN_TrapChunkList traps; - DMN_HandleArray run_entities; -}; - -//////////////////////////////// -//~ rjf: Responses (Server -> Client responses to messages) - -typedef struct RDS_Response RDS_Response; -struct RDS_Response -{ - U64 id; - String8 data; - DMN_Handle entity; - U64 pid; - U64 demon_event_count; -}; - -//////////////////////////////// -//~ rjf: Message Parsing - -internal RDS_Msg rds_msg_from_data(Arena *arena, String8 data); - -#endif // RADDBG_SERVER_H