diff --git a/project.4coder b/project.4coder index 360ba491..da10909d 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 meta", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg_server 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_ctrl.c b/src/dbg_engine/dbg_engine_ctrl.c index 1b5ba1c7..0aa67934 100644 --- a/src/dbg_engine/dbg_engine_ctrl.c +++ b/src/dbg_engine/dbg_engine_ctrl.c @@ -1,33 +1,6 @@ // Copyright (c) Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -//////////////////////////////// -//~ rjf: Local Host Demon Interface - -D_DemonInterface d_local_demon = -{ - dmn_ctrl_exclusive_access_begin, - dmn_ctrl_exclusive_access_end, - dmn_ctrl_launch, - dmn_ctrl_attach, - dmn_ctrl_kill, - dmn_ctrl_detach, - dmn_ctrl_run, - dmn_halt, - dmn_access_open, - dmn_access_close, - dmn_process_memory_reserve, - dmn_process_memory_commit, - dmn_process_memory_decommit, - dmn_process_memory_release, - dmn_process_memory_protect, - dmn_process_read, - dmn_process_write, - dmn_thread_read_reg_block, - dmn_thread_write_reg_block, - dmn_thread_get_module_tls_vaddr, -}; - //////////////////////////////// //~ rjf: Basic Type Functions diff --git a/src/dbg_engine/dbg_engine_ctrl.h b/src/dbg_engine/dbg_engine_ctrl.h index c1bd93bc..b6adaf01 100644 --- a/src/dbg_engine/dbg_engine_ctrl.h +++ b/src/dbg_engine/dbg_engine_ctrl.h @@ -313,68 +313,6 @@ struct D_ModuleReqCacheNode #define D_WAKEUP_FUNCTION_DEF(name) void name(void) typedef D_WAKEUP_FUNCTION_DEF(D_WakeupFunctionType); -//////////////////////////////// -//~ rjf: Demon Interface V-Table - -typedef struct D_DemonInterface D_DemonInterface; -struct D_DemonInterface -{ - //- rjf: control - void (*ctrl_exclusive_access_begin)(void); - void (*ctrl_exclusive_access_end)(void); - U32 (*launch)(DMN_CtrlCtx *ctx, ProcessLaunchParams *params); - B32 (*attach)(DMN_CtrlCtx *ctx, U32 pid); - B32 (*kill)(DMN_CtrlCtx *ctx, DMN_Handle process, U32 exit_code); - B32 (*detach)(DMN_CtrlCtx *ctx, DMN_Handle process); - DMN_EventList (*run)(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls); - - //- rjf: halting - void (*halt)(U64 code, U64 user_data); - - //- rjf: non-blocking-control-thread access barriers - B32 (*access_open)(void); - void (*access_close)(void); - - //- rjf: process memory - U64 (*reserve_memory)(DMN_Handle process, U64 vaddr, U64 size); - void (*commit_memory)(DMN_Handle process, U64 vaddr, U64 size); - void (*decommit_memory)(DMN_Handle process, U64 vaddr, U64 size); - void (*release_memory)(DMN_Handle process, U64 vaddr, U64 size); - void (*protect_memory)(DMN_Handle process, U64 vaddr, U64 size, AccessFlags flags); - U64 (*read_memory)(DMN_Handle process, Rng1U64 range, void *dst); - B32 (*write_memory)(DMN_Handle process, Rng1U64 range, void *src); - - //- rjf: threads - B32 (*thread_read_reg_block)(DMN_Handle thread, void *dst); - B32 (*thread_write_reg_block)(DMN_Handle thread, void *src); - B32 (*thread_get_module_tls_vaddr)(DMN_Handle thread, DMN_Handle module, U64 *vaddr_out); -}; - -typedef struct D_DemonState D_DemonState; -struct D_DemonState -{ - D_DemonState *next; - D_DemonState *prev; - D_DemonID id; - D_DemonInterface *fn; - Arena *event_arena; - DMN_EventList events; -}; - -typedef struct D_DemonStateSlot D_DemonStateSlot; -struct D_DemonStateSlot -{ - D_DemonState *first; - D_DemonState *last; -}; - -typedef struct D_DemonCache D_DemonCache; -struct D_DemonCache -{ - U64 slots_count; - D_DemonStateSlot *slots; -}; - //////////////////////////////// //~ rjf: Main State Types diff --git a/src/dbg_server/dbg_server.c b/src/dbg_server/dbg_server.c index 9dce96f0..2922db8b 100644 --- a/src/dbg_server/dbg_server.c +++ b/src/dbg_server/dbg_server.c @@ -20,7 +20,7 @@ ds_msg_from_serialized(Arena *arena, String8 data) // rjf: read flat parts off += str8_deserial_read_struct(data, off, &msg.kind); off += str8_deserial_read_struct(data, off, &msg.flags); - off += str8_deserial_read_struct(data, off, &msg.id); + off += str8_deserial_read_struct(data, off, &msg.msg_id); off += str8_deserial_read_struct(data, off, &msg.vaddr_range); off += str8_deserial_read_struct(data, off, &msg.access_flags); off += str8_deserial_read_struct(data, off, &msg.entity); @@ -92,3 +92,17 @@ ds_serialized_from_msg(Arena *arena, DS_Msg *msg) String8 result = str8_list_join(arena, &srl, 0); return result; } + +internal DS_Response +ds_response_from_serialized(Arena *arena, String8 data) +{ + DS_Response result = {0}; + return result; +} + +internal String8 +ds_serialized_from_response(Arena *arena, DS_Response *response) +{ + String8 result = {0}; + return result; +} diff --git a/src/dbg_server/dbg_server.h b/src/dbg_server/dbg_server.h index 7f1520c0..a960511b 100644 --- a/src/dbg_server/dbg_server.h +++ b/src/dbg_server/dbg_server.h @@ -60,13 +60,14 @@ struct DS_Msg { DS_MsgKind kind; DS_MsgFlags flags; - U64 id; + U64 msg_id; //- rjf: general parameters Rng1U64 vaddr_range; AccessFlags access_flags; DMN_Handle entity; U64 pid; + U64 code; //- rjf: process launching parameters String8List command_line; @@ -78,41 +79,33 @@ struct DS_Msg 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; + U64 msg_id; String8 data; DMN_Handle entity; U64 pid; + B32 good; DMN_EventList events; }; +typedef struct DS_ResponseNode DS_ResponseNode; +struct DS_ResponseNode +{ + DS_ResponseNode *next; + DS_Response v; +}; + //////////////////////////////// -//~ rjf: Message Parsing +//~ rjf: Message/Response Parsing internal DS_Msg ds_msg_from_serialized(Arena *arena, String8 data); -internal String8 ds_serialized_from_msg(Arena *arena, DS_Msg msg); +internal String8 ds_serialized_from_msg(Arena *arena, DS_Msg *msg); +internal DS_Response ds_response_from_serialized(Arena *arena, String8 data); +internal String8 ds_serialized_from_response(Arena *arena, DS_Response *response); #endif // DBG_SERVER_H diff --git a/src/dbg_server/dbg_server_client.c b/src/dbg_server/dbg_server_client.c deleted file mode 100644 index 7d253777..00000000 --- a/src/dbg_server/dbg_server_client.c +++ /dev/null @@ -1,24 +0,0 @@ -// 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 deleted file mode 100644 index cffb3eca..00000000 --- a/src/dbg_server/dbg_server_client.h +++ /dev/null @@ -1,13 +0,0 @@ -// 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 deleted file mode 100644 index 4b9e5811..00000000 --- a/src/dbg_server/dbg_server_host.c +++ /dev/null @@ -1,28 +0,0 @@ -// 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 deleted file mode 100644 index 1e6a8e67..00000000 --- a/src/dbg_server/dbg_server_host.h +++ /dev/null @@ -1,15 +0,0 @@ -// 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 deleted file mode 100644 index ae447aab..00000000 --- a/src/dbg_server/dbg_server_remote.c +++ /dev/null @@ -1,2 +0,0 @@ -// 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 deleted file mode 100644 index 9cb853c2..00000000 --- a/src/dbg_server/dbg_server_remote.h +++ /dev/null @@ -1,7 +0,0 @@ -// 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_server/raddbg_server_main.c b/src/raddbg_server/raddbg_server_main.c index 430d2cce..9466c917 100644 --- a/src/raddbg_server/raddbg_server_main.c +++ b/src/raddbg_server/raddbg_server_main.c @@ -23,7 +23,7 @@ #include "gnu/gnu_parse.h" #include "elf/elf_parse.h" #include "demon/demon_inc.h" -#include "raddbg_server/raddbg_server.h" +#include "dbg_server/dbg_server.h" //- rjf: [c] #include "base/base_inc.c" @@ -38,7 +38,7 @@ #include "gnu/gnu_parse.c" #include "elf/elf_parse.c" #include "demon/demon_inc.c" -#include "raddbg_server/raddbg_server.c" +#include "dbg_server/dbg_server.c" //////////////////////////////// //~ rjf: Globals @@ -90,27 +90,72 @@ dmn_thread__entry_point(void *p) } //////////////////////////// - //- rjf: do messages + //- rjf: do messages, push responses // for(String8Node *msg_n = msgs.first; msg_n != 0; msg_n = msg_n->next) { - RDS_Msg msg = rds_msg_from_data(scratch.arena, msg_n->string); + //- rjf: unpack message + DS_Msg msg = ds_msg_from_serialized(scratch.arena, msg_n->string); + + //- rjf: do action, get response + DS_Response response = {0}; switch(msg.kind) { default:{}break; - //- rjf: debuggee attaching/detaching ops + //- 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); + } + response.pid = dmn_ctrl_launch(ctrl_ctx, ¶ms); + }break; - case RDS_MsgKind_Launch:{}break; - case RDS_MsgKind_Attach:{}break; - case RDS_MsgKind_Kill:{}break; - case RDS_MsgKind_Detach:{}break; + //- rjf: attaching + case DS_MsgKind_Attach: + { + response.good = dmn_ctrl_attach(ctrl_ctx, msg.pid); + }break; + + //- rjf: killing + case DS_MsgKind_Kill: + { + response.good = dmn_ctrl_kill(ctrl_ctx, msg.entity, (U32)msg.code); + }break; + + //- rjf: detaching + case DS_MsgKind_Detach: + { + response.good = dmn_ctrl_detach(ctrl_ctx, msg.entity); + }break; //- rjf: running ops - - case RDS_MsgKind_Run:{}break; - case RDS_MsgKind_SingleStep:{}break; + case DS_MsgKind_Run: + case DS_MsgKind_SingleStep: + { + DMN_RunCtrls ctrls = {0}; + { + ctrls.priority_thread = msg.entity; + ctrls.single_step_thread = (msg.kind == DS_MsgKind_SingleStep) ? msg.entity : dmn_handle_zero(); + ctrls.run_entities = msg.run_entities.handles; + ctrls.run_entity_count = msg.run_entities.count; + ctrls.traps = msg.traps; + ctrls.ignore_previous_exception = !!(msg.flags & DS_MsgFlag_IgnorePreviousException); + ctrls.run_entities_are_unfrozen = !!(msg.flags & DS_MsgFlag_RunEntitiesAreUnfrozen); + ctrls.run_entities_are_processes = !!(msg.flags & DS_MsgFlag_RunEntitiesAreProcesses); + }; + response.events = dmn_ctrl_run(scratch.arena, ctrl_ctx, &ctrls); + }break; } + + //- rjf: pack response & push + String8 data = ds_serialized_from_response(scratch.arena, &response); } scratch_end(scratch); @@ -176,17 +221,17 @@ entry_point(CmdLine *cmd_line) // attaching, detaching, and so on. other operations, like reading/writing // memory/registers, listing processes, and halting, we want to just do // on the main thread without interrupting the demon at all. - RDS_MsgKind peek_kind = RDS_MsgKind_Null; - if(magic_maybe == RDS_MSG_MAGIC) + DS_MsgKind peek_kind = DS_MsgKind_Null; + if(magic_maybe == DS_MSG_MAGIC) { str8_deserial_read_struct(data, 2, &peek_kind); - if(peek_kind < RDS_MsgKind_DemonThreadHandledFirst || RDS_MsgKind_DemonThreadHandledLast < peek_kind) + if(peek_kind < DS_MsgKind_Launch || DS_MsgKind_SingleStep < peek_kind) { - RDS_Msg msg = rds_msg_from_data(scratch.arena, data); + DS_Msg msg = ds_msg_from_serialized(scratch.arena, data); switch(msg.kind) { default:{}break; - case RDS_MsgKind_Halt: + case DS_MsgKind_Halt: { dmn_halt(0, 0); }break; @@ -195,7 +240,7 @@ entry_point(CmdLine *cmd_line) } //- rjf: not handled by main thread? -> okay, send to demon thread, if it's ready. - if(magic_maybe == RDS_MSG_MAGIC && !rds_state->demon_is_running && (RDS_MsgKind_DemonThreadHandledFirst <= peek_kind && peek_kind <= RDS_MsgKind_DemonThreadHandledLast)) + if(magic_maybe == DS_MSG_MAGIC && !rds_state->demon_is_running && (DS_MsgKind_Launch <= peek_kind && peek_kind <= DS_MsgKind_SingleStep)) { RWMutexScope(rds_state->c2d_rw_mutex, 1) {