mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-11-14 02:03:27 -08:00
debug server checkpoint
This commit is contained in:
1 parent
b6d8c3fd9e
commit
c269823e15
12 files changed
+94
-220
No files matched your search
+1
-1
@@ -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, },
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
+15
-22
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user