mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-11-14 02:03:27 -08:00
dbg_server / dbg_engine: checkpoint on remote debug servers
This commit is contained in:
1 parent
6cfaae9a22
commit
41598aaf08
13 files changed
+301
-165
No files matched your search
@@ -104,6 +104,7 @@ d_init(void)
|
||||
Arena *arena = arena_alloc();
|
||||
d_ctrl_state = push_array(arena, D_CtrlState, 1);
|
||||
d_ctrl_state->arena = arena;
|
||||
d_ctrl_state->sock_session = sock_session_open(0, 0);
|
||||
for EachEnumVal(Arch, arch)
|
||||
{
|
||||
ARCH_Info *arch_info = arch_info_from_arch(arch);
|
||||
|
||||
@@ -22,7 +22,7 @@ struct D_Eval
|
||||
//~ rjf: ID Types
|
||||
|
||||
typedef U64 D_MsgID;
|
||||
typedef U32 D_DemonID;
|
||||
typedef U32 D_ServerID;
|
||||
typedef U32 D_ControllerKind;
|
||||
typedef enum D_ControllerKindEnum
|
||||
{
|
||||
@@ -31,7 +31,7 @@ typedef enum D_ControllerKindEnum
|
||||
}
|
||||
D_ControllerKindEnum;
|
||||
|
||||
#define D_DemonID_LocalHost (1)
|
||||
#define D_ServerID_LocalHost (1)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entity Handle Types
|
||||
@@ -39,7 +39,7 @@ D_ControllerKindEnum;
|
||||
typedef struct D_Handle D_Handle;
|
||||
struct D_Handle
|
||||
{
|
||||
D_DemonID demon_id;
|
||||
D_ServerID server_id;
|
||||
D_ControllerKind controller_kind;
|
||||
U64 entity_id;
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
internal U64
|
||||
d_hash_from_handle(D_Handle handle)
|
||||
{
|
||||
U64 buf[] = {handle.demon_id, handle.controller_kind, handle.entity_id};
|
||||
U64 buf[] = {handle.server_id, handle.controller_kind, handle.entity_id};
|
||||
U64 hash = u64_hash_from_str8(str8_struct(&handle));
|
||||
return hash;
|
||||
}
|
||||
@@ -182,7 +182,7 @@ d_handle_array_from_list(Arena *arena, D_HandleList *src)
|
||||
internal String8
|
||||
d_string_from_handle(Arena *arena, D_Handle handle)
|
||||
{
|
||||
String8 result = str8f(arena, "$%x$%x$%I64x", handle.demon_id, handle.controller_kind, handle.entity_id);
|
||||
String8 result = str8f(arena, "$%x$%x$%I64x", handle.server_id, handle.controller_kind, handle.entity_id);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -196,10 +196,10 @@ d_handle_from_string(String8 string)
|
||||
String8List parts = str8_split(scratch.arena, string, &split, 1, 0);
|
||||
if(parts.first && parts.first->next && parts.first->next->next)
|
||||
{
|
||||
D_DemonID demon_id = (U32)u64_from_str8(parts.first->string, 16);
|
||||
D_ServerID server_id = (U32)u64_from_str8(parts.first->string, 16);
|
||||
D_ControllerKind controller_kind = (U32)u64_from_str8(parts.first->next->string, 16);
|
||||
U64 entity_id = u64_from_str8(parts.first->next->next->string, 16);
|
||||
handle.demon_id = demon_id;
|
||||
handle.server_id = server_id;
|
||||
handle.controller_kind = controller_kind;
|
||||
handle.entity_id = entity_id;
|
||||
}
|
||||
@@ -220,11 +220,11 @@ d_dmn_from_handle(D_Handle handle)
|
||||
}
|
||||
|
||||
internal D_Handle
|
||||
d_handle_from_dmn(D_DemonID demon_id, DMN_Handle handle)
|
||||
d_handle_from_dmn(D_ServerID server_id, DMN_Handle handle)
|
||||
{
|
||||
D_Handle result = {0};
|
||||
{
|
||||
result.demon_id = demon_id;
|
||||
result.server_id = server_id;
|
||||
result.controller_kind = D_ControllerKind_Demon;
|
||||
result.entity_id = handle.u64[0];
|
||||
}
|
||||
@@ -232,11 +232,11 @@ d_handle_from_dmn(D_DemonID demon_id, DMN_Handle handle)
|
||||
}
|
||||
|
||||
internal D_Handle
|
||||
d_dump_handle_make(D_DemonID demon_id, U64 id)
|
||||
d_dump_handle_make(D_ServerID server_id, U64 id)
|
||||
{
|
||||
D_Handle result = {0};
|
||||
{
|
||||
result.demon_id = demon_id;
|
||||
result.server_id = server_id;
|
||||
result.controller_kind = D_ControllerKind_Dump;
|
||||
result.entity_id = id;
|
||||
}
|
||||
@@ -915,7 +915,7 @@ d_entity_ctx_rw_store_alloc(void)
|
||||
store->ctx.hash_slots_count = 1024;
|
||||
store->ctx.hash_slots = push_array(arena, D_EntityHashSlot, store->ctx.hash_slots_count);
|
||||
D_Entity *root = store->ctx.root = d_entity_alloc(store, &d_entity_nil, D_EntityKind_Root, Arch_Null, d_handle_zero(), 0);
|
||||
D_Entity *local_server = d_entity_alloc(store, root, D_EntityKind_Server, Arch_CURRENT, d_handle_from_dmn(D_DemonID_LocalHost, dmn_handle_zero()), 0);
|
||||
D_Entity *local_server = d_entity_alloc(store, root, D_EntityKind_Server, Arch_CURRENT, d_handle_from_dmn(D_ServerID_LocalHost, dmn_handle_zero()), 0);
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 local_server_name = str8f(scratch.arena, "Local (%S)", get_system_info()->machine_name);
|
||||
d_entity_equip_string(store, local_server, local_server_name);
|
||||
@@ -1306,7 +1306,7 @@ d_entity_store_apply_events(D_EntityCtxRWStore *store, D_EventList *list)
|
||||
//- rjf: processes
|
||||
case D_EventKind_NewProc:
|
||||
{
|
||||
D_Entity *machine = d_entity_from_handle(d_handle_from_dmn(event->entity.demon_id, dmn_handle_zero()));
|
||||
D_Entity *machine = d_entity_from_handle(d_handle_from_dmn(event->entity.server_id, dmn_handle_zero()));
|
||||
if(machine != &d_entity_nil)
|
||||
{
|
||||
D_Entity *process = d_entity_alloc(store, machine, D_EntityKind_Process, event->arch, event->entity, (U64)event->entity_id);
|
||||
@@ -1505,6 +1505,20 @@ d_entity_store_apply_events(D_EntityCtxRWStore *store, D_EventList *list)
|
||||
annotation->vaddr_range = event->vaddr_rng;
|
||||
d_entity_equip_string(store, annotation, event->string);
|
||||
}break;
|
||||
|
||||
//- rjf: remote server connections
|
||||
case D_EventKind_ServerConnect:
|
||||
{
|
||||
D_Handle handle = {0};
|
||||
handle.server_id = event->entity_id;
|
||||
D_Entity *server = d_entity_alloc(store, d_entity_ctx->root, D_EntityKind_Server, Arch_Null, handle, 0);
|
||||
d_entity_equip_string(store, server, event->string);
|
||||
}break;
|
||||
case D_EventKind_ServerDisconnect:
|
||||
{
|
||||
D_Entity *server = d_entity_from_handle(event->entity);
|
||||
d_entity_release(store, server);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2938,7 +2952,7 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
(spoof == 0 || ev->instruction_pointer != spoof->new_ip_value))
|
||||
{
|
||||
Access *access = access_open();
|
||||
D_Handle process_handle = d_handle_from_dmn(D_DemonID_LocalHost, ev->process);
|
||||
D_Handle process_handle = d_handle_from_dmn(D_ServerID_LocalHost, ev->process);
|
||||
D_Entity *process = d_entity_from_handle(process_handle);
|
||||
D_Entity *module = d_module_from_process_vaddr(process, ev->instruction_pointer);
|
||||
if(module != &d_entity_nil)
|
||||
@@ -3139,7 +3153,7 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
D_Event *out_evt = d_event_list_push(scratch.arena, &evts);
|
||||
out_evt->kind = D_EventKind_NewProc;
|
||||
out_evt->msg_id = msg_id;
|
||||
out_evt->entity = d_handle_from_dmn(D_DemonID_LocalHost, event->process);
|
||||
out_evt->entity = d_handle_from_dmn(D_ServerID_LocalHost, event->process);
|
||||
out_evt->arch = event->arch;
|
||||
out_evt->entity_id = event->code;
|
||||
out_evt->os = OperatingSystem_CURRENT; // TODO: operating system of the remote target machine
|
||||
@@ -3152,8 +3166,8 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
D_Event *out_evt = d_event_list_push(scratch.arena, &evts);
|
||||
out_evt->kind = D_EventKind_NewThread;
|
||||
out_evt->msg_id = msg->msg_id;
|
||||
out_evt->entity = d_handle_from_dmn(D_DemonID_LocalHost, event->thread);
|
||||
out_evt->parent = d_handle_from_dmn(D_DemonID_LocalHost, event->process);
|
||||
out_evt->entity = d_handle_from_dmn(D_ServerID_LocalHost, event->thread);
|
||||
out_evt->parent = d_handle_from_dmn(D_ServerID_LocalHost, event->process);
|
||||
out_evt->arch = event->arch;
|
||||
out_evt->entity_id = event->code;
|
||||
out_evt->stack_base = event->stack_pointer;
|
||||
@@ -3168,8 +3182,8 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
Temp scratch2 = scratch_begin(&scratch.arena, 1);
|
||||
|
||||
//- rjf: unpack module
|
||||
D_Handle process_handle = d_handle_from_dmn(D_DemonID_LocalHost, event->process);
|
||||
D_Handle module_handle = d_handle_from_dmn(D_DemonID_LocalHost, event->module);
|
||||
D_Handle process_handle = d_handle_from_dmn(D_ServerID_LocalHost, event->process);
|
||||
D_Handle module_handle = d_handle_from_dmn(D_ServerID_LocalHost, event->module);
|
||||
String8 module_path = path_normalized_from_string(scratch2.arena, event->string);
|
||||
U64 exe_timestamp = properties_from_file_path(module_path).modified;
|
||||
DMN_ModuleInfo *module_info = event->module_info;
|
||||
@@ -3334,7 +3348,7 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
D_Event *out_evt = d_event_list_push(scratch.arena, &evts);
|
||||
out_evt->kind = D_EventKind_EndProc;
|
||||
out_evt->msg_id = msg->msg_id;
|
||||
out_evt->entity = d_handle_from_dmn(D_DemonID_LocalHost, event->process);
|
||||
out_evt->entity = d_handle_from_dmn(D_ServerID_LocalHost, event->process);
|
||||
out_evt->u64_code = event->code;
|
||||
d_ctrl_state->process_counter -= 1;
|
||||
}break;
|
||||
@@ -3345,7 +3359,7 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
D_Event *out_evt = d_event_list_push(scratch.arena, &evts);
|
||||
out_evt->kind = D_EventKind_EndThread;
|
||||
out_evt->msg_id = msg->msg_id;
|
||||
out_evt->entity = d_handle_from_dmn(D_DemonID_LocalHost, event->thread);
|
||||
out_evt->entity = d_handle_from_dmn(D_ServerID_LocalHost, event->thread);
|
||||
out_evt->entity_id = event->code;
|
||||
}break;
|
||||
|
||||
@@ -3353,7 +3367,7 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
case DMN_EventKind_UnloadModule:
|
||||
{
|
||||
//- rjf: unpack module
|
||||
D_Handle module_handle = d_handle_from_dmn(D_DemonID_LocalHost, event->module);
|
||||
D_Handle module_handle = d_handle_from_dmn(D_ServerID_LocalHost, event->module);
|
||||
D_Entity *module_ent = d_entity_from_handle(module_handle);
|
||||
D_Entity *process_ent = d_process_from_entity(module_ent);
|
||||
String8 module_path = event->string;
|
||||
@@ -3390,8 +3404,8 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
D_Event *out_evt = d_event_list_push(scratch.arena, &evts);
|
||||
out_evt->kind = D_EventKind_DebugString;
|
||||
out_evt->msg_id = msg->msg_id;
|
||||
out_evt->entity = d_handle_from_dmn(D_DemonID_LocalHost, event->thread);
|
||||
out_evt->parent = d_handle_from_dmn(D_DemonID_LocalHost, event->process);
|
||||
out_evt->entity = d_handle_from_dmn(D_ServerID_LocalHost, event->thread);
|
||||
out_evt->parent = d_handle_from_dmn(D_ServerID_LocalHost, event->process);
|
||||
out_evt->string = str8_substr(event->string, r1u64(string_idx*d_ctrl_state->c2u_ring_max_string_size, (string_idx+1)*d_ctrl_state->c2u_ring_max_string_size));
|
||||
}
|
||||
}break;
|
||||
@@ -3402,8 +3416,8 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
D_Event *out_evt = d_event_list_push(scratch.arena, &evts);
|
||||
out_evt->kind = D_EventKind_ThreadName;
|
||||
out_evt->msg_id = msg->msg_id;
|
||||
out_evt->entity = d_handle_from_dmn(D_DemonID_LocalHost, event->thread);
|
||||
out_evt->parent = d_handle_from_dmn(D_DemonID_LocalHost, event->process);
|
||||
out_evt->entity = d_handle_from_dmn(D_ServerID_LocalHost, event->thread);
|
||||
out_evt->parent = d_handle_from_dmn(D_ServerID_LocalHost, event->process);
|
||||
out_evt->string = event->string;
|
||||
out_evt->entity_id = event->code;
|
||||
}break;
|
||||
@@ -3414,8 +3428,8 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
D_Event *out_evt = d_event_list_push(scratch.arena, &evts);
|
||||
out_evt->kind = D_EventKind_ThreadColor;
|
||||
out_evt->msg_id = msg->msg_id;
|
||||
out_evt->entity = d_handle_from_dmn(D_DemonID_LocalHost, event->thread);
|
||||
out_evt->parent = d_handle_from_dmn(D_DemonID_LocalHost, event->process);
|
||||
out_evt->entity = d_handle_from_dmn(D_ServerID_LocalHost, event->thread);
|
||||
out_evt->parent = d_handle_from_dmn(D_ServerID_LocalHost, event->process);
|
||||
out_evt->entity_id = event->code;
|
||||
out_evt->rgba = event->user_data;
|
||||
}break;
|
||||
@@ -3425,7 +3439,7 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
{
|
||||
D_Event *out_evt = d_event_list_push(scratch.arena, &evts);
|
||||
out_evt->kind = D_EventKind_SetVAddrRangeNote;
|
||||
out_evt->parent = d_handle_from_dmn(D_DemonID_LocalHost, event->process);
|
||||
out_evt->parent = d_handle_from_dmn(D_ServerID_LocalHost, event->process);
|
||||
out_evt->msg_id = msg->msg_id;
|
||||
out_evt->vaddr_rng = r1u64(event->address, event->address + event->size);
|
||||
out_evt->string = event->string;
|
||||
@@ -3436,8 +3450,8 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
{
|
||||
D_Event *out_evt = d_event_list_push(scratch.arena, &evts);
|
||||
out_evt->kind = D_EventKind_SetBreakpoint;
|
||||
out_evt->entity = d_handle_from_dmn(D_DemonID_LocalHost, event->thread);
|
||||
out_evt->parent = d_handle_from_dmn(D_DemonID_LocalHost, event->process);
|
||||
out_evt->entity = d_handle_from_dmn(D_ServerID_LocalHost, event->thread);
|
||||
out_evt->parent = d_handle_from_dmn(D_ServerID_LocalHost, event->process);
|
||||
out_evt->vaddr_rng = r1u64(event->address, event->address+event->size);
|
||||
out_evt->bp_flags = d_breakpoint_flags_from_dmn_trap_flags(event->flags);
|
||||
}break;
|
||||
@@ -3448,8 +3462,8 @@ d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, D
|
||||
// TODO(rjf): this needs to be reflected in the resolved trap list too!!!!!!!!
|
||||
D_Event *out_evt = d_event_list_push(scratch.arena, &evts);
|
||||
out_evt->kind = D_EventKind_UnsetBreakpoint;
|
||||
out_evt->entity = d_handle_from_dmn(D_DemonID_LocalHost, event->thread);
|
||||
out_evt->parent = d_handle_from_dmn(D_DemonID_LocalHost, event->process);
|
||||
out_evt->entity = d_handle_from_dmn(D_ServerID_LocalHost, event->thread);
|
||||
out_evt->parent = d_handle_from_dmn(D_ServerID_LocalHost, event->process);
|
||||
out_evt->vaddr_rng = r1u64(event->address, event->address+event->size);
|
||||
out_evt->bp_flags = d_breakpoint_flags_from_dmn_trap_flags(event->flags);
|
||||
}break;
|
||||
@@ -3813,13 +3827,52 @@ d_ctrl_thread__end_and_flush_log(void)
|
||||
internal void
|
||||
d_ctrl_thread__open_remote_server(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
{
|
||||
SOCK_Endpoint endpoint = sock_endpoint_from_string(msg->path);
|
||||
|
||||
//- rjf: handshake & get state
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DS_Msg msg = {0};
|
||||
{
|
||||
msg.kind = DS_MsgKind_Handshake;
|
||||
msg.msg_id = 1;
|
||||
}
|
||||
String8 msg_raw = ds_packet_from_msg(scratch.arena, &msg);
|
||||
DS_PacketHeader header =
|
||||
{
|
||||
.magic = DS_PACKET_MAGIC,
|
||||
.kind = DS_PacketKind_Msg,
|
||||
.version = DS_PACKET_VERSION,
|
||||
.payload_size = msg_raw.size,
|
||||
};
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
//- rjf: push connect event
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
D_EventList evts = {0};
|
||||
D_Event *evt = d_event_list_push(scratch.arena, &evts);
|
||||
d_ctrl_state->server_id_gen += 1;
|
||||
evt->kind = D_EventKind_ServerConnect;
|
||||
evt->entity_id = D_ServerID_LocalHost + d_ctrl_state->server_id_gen;
|
||||
evt->string = msg->path;
|
||||
d_c2u_push_events(&evts);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
d_ctrl_thread__close_remote_server(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
{
|
||||
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
D_Entity *machine = d_entity_from_handle(msg->entity);
|
||||
D_EventList evts = {0};
|
||||
D_Event *evt = d_event_list_push(scratch.arena, &evts);
|
||||
evt->kind = D_EventKind_ServerDisconnect;
|
||||
evt->entity_id = machine->handle.server_id;
|
||||
d_c2u_push_events(&evts);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
internal void
|
||||
@@ -4127,7 +4180,7 @@ d_ctrl_thread__open_crash_dump(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
|
||||
// rjf: create process handle
|
||||
d_ctrl_state->ctrl_thread_dump_handle_id_gen += 1;
|
||||
process = d_dump_handle_make(D_DemonID_LocalHost, d_ctrl_state->ctrl_thread_dump_handle_id_gen);
|
||||
process = d_dump_handle_make(D_ServerID_LocalHost, d_ctrl_state->ctrl_thread_dump_handle_id_gen);
|
||||
|
||||
// rjf: gather threads
|
||||
dump_threads_count = threads_count;
|
||||
@@ -4144,7 +4197,7 @@ d_ctrl_thread__open_crash_dump(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
{
|
||||
d_ctrl_state->ctrl_thread_dump_handle_id_gen += 1;
|
||||
MDMP_Thread *thread = &threads[idx];
|
||||
D_Handle thread_handle = d_dump_handle_make(D_DemonID_LocalHost, d_ctrl_state->ctrl_thread_dump_handle_id_gen);
|
||||
D_Handle thread_handle = d_dump_handle_make(D_ServerID_LocalHost, d_ctrl_state->ctrl_thread_dump_handle_id_gen);
|
||||
dump_threads[idx].thread_handle = thread_handle;
|
||||
dump_threads[idx].id = thread->id;
|
||||
dump_threads[idx].context_foff = thread->thread_context.foff;
|
||||
@@ -4249,7 +4302,7 @@ d_ctrl_thread__open_crash_dump(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
|
||||
// rjf: store
|
||||
d_ctrl_state->ctrl_thread_dump_handle_id_gen += 1;
|
||||
dump_modules[idx].module_handle = d_dump_handle_make(D_DemonID_LocalHost, d_ctrl_state->ctrl_thread_dump_handle_id_gen);
|
||||
dump_modules[idx].module_handle = d_dump_handle_make(D_ServerID_LocalHost, d_ctrl_state->ctrl_thread_dump_handle_id_gen);
|
||||
dump_modules[idx].vaddr_range = vaddr_range;
|
||||
dump_modules[idx].path = str8_copy(arena, module_name);
|
||||
dump_modules[idx].file = module_file;
|
||||
@@ -4605,7 +4658,7 @@ d_ctrl_thread__kill_all(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
default:{}break;
|
||||
case DMN_EventKind_CreateProcess:
|
||||
{
|
||||
D_Entity *new_process = d_entity_from_handle(d_handle_from_dmn(D_DemonID_LocalHost, event->process));
|
||||
D_Entity *new_process = d_entity_from_handle(d_handle_from_dmn(D_ServerID_LocalHost, event->process));
|
||||
Task *t = push_array(scratch.arena, Task, 1);
|
||||
t->process = new_process;
|
||||
DLLPushBack(first_task, last_task, t);
|
||||
@@ -4826,7 +4879,7 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
node != 0;
|
||||
node = node->next)
|
||||
{
|
||||
D_Handle thread = d_handle_from_dmn(D_DemonID_LocalHost, node->v);
|
||||
D_Handle thread = d_handle_from_dmn(D_ServerID_LocalHost, node->v);
|
||||
U64 thread_pre_rip = d_ip_from_thread(thread);
|
||||
U64 thread_post_rip = thread_pre_rip;
|
||||
for(B32 done = 0; !done;)
|
||||
@@ -4845,7 +4898,7 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
{
|
||||
default:{}break;
|
||||
case DMN_EventKind_ExitThread:
|
||||
if(d_handle_match(d_handle_from_dmn(D_DemonID_LocalHost, event->thread), thread))
|
||||
if(d_handle_match(d_handle_from_dmn(D_ServerID_LocalHost, event->thread), thread))
|
||||
{
|
||||
stop_cause = D_EventCause_Error;
|
||||
goto stop;
|
||||
@@ -5008,7 +5061,7 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
D_EvalScope *eval_scope = d_ctrl_thread__eval_scope_begin(scratch.arena, &msg->user_bps, &d_entity_nil);
|
||||
{
|
||||
DMN_TrapChunkList new_traps = {0};
|
||||
d_ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, eval_scope, d_handle_from_dmn(D_DemonID_LocalHost, event->process), &msg->user_bps, &new_traps);
|
||||
d_ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, eval_scope, d_handle_from_dmn(D_ServerID_LocalHost, event->process), &msg->user_bps, &new_traps);
|
||||
log_infof("step_rule: create_process -> resolve traps\n");
|
||||
log_infof("new_traps:\n{\n");
|
||||
for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next)
|
||||
@@ -5027,11 +5080,11 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
}break;
|
||||
case DMN_EventKind_LoadModule:
|
||||
{
|
||||
D_Entity *thread = d_entity_from_handle(d_handle_from_dmn(D_DemonID_LocalHost, event->thread));
|
||||
D_Entity *thread = d_entity_from_handle(d_handle_from_dmn(D_ServerID_LocalHost, event->thread));
|
||||
D_EvalScope *eval_scope = d_ctrl_thread__eval_scope_begin(scratch.arena, &msg->user_bps, thread);
|
||||
{
|
||||
DMN_TrapChunkList new_traps = {0};
|
||||
d_ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, eval_scope, d_handle_from_dmn(D_DemonID_LocalHost, event->process), d_handle_from_dmn(D_DemonID_LocalHost, event->module), &msg->user_bps, &new_traps);
|
||||
d_ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, eval_scope, d_handle_from_dmn(D_ServerID_LocalHost, event->process), d_handle_from_dmn(D_ServerID_LocalHost, event->module), &msg->user_bps, &new_traps);
|
||||
log_infof("step_rule: load_module -> resolve traps\n");
|
||||
log_infof("new_traps:\n{\n");
|
||||
for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next)
|
||||
@@ -5052,7 +5105,7 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
{
|
||||
D_Entity *bp = &d_entity_nil;
|
||||
{
|
||||
D_Entity *process = d_entity_from_handle(d_handle_from_dmn(D_DemonID_LocalHost, event->process));
|
||||
D_Entity *process = d_entity_from_handle(d_handle_from_dmn(D_ServerID_LocalHost, event->process));
|
||||
for(D_Entity *child = process->first; child != &d_entity_nil; child = child->next)
|
||||
{
|
||||
if(child->kind == D_EntityKind_Breakpoint &&
|
||||
@@ -5084,7 +5137,7 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
Access *access = access_open();
|
||||
|
||||
//- rjf: unpack process/module info
|
||||
D_Entity *process = d_entity_from_handle(d_handle_from_dmn(D_DemonID_LocalHost, event->process));
|
||||
D_Entity *process = d_entity_from_handle(d_handle_from_dmn(D_ServerID_LocalHost, event->process));
|
||||
D_Entity *module = d_entity_child_from_kind(process, D_EntityKind_Module);
|
||||
U64 module_base_vaddr = module->vaddr_range.min;
|
||||
DI_Key dbgi_key = d_dbgi_key_from_module(module);
|
||||
@@ -5310,8 +5363,8 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
//////////////////////////
|
||||
//- rjf: unpack info about thread attached to event
|
||||
//
|
||||
D_Entity *thread = d_entity_from_handle(d_handle_from_dmn(D_DemonID_LocalHost, event->thread));
|
||||
D_Entity *process = d_entity_from_handle(d_handle_from_dmn(D_DemonID_LocalHost, event->process));
|
||||
D_Entity *thread = d_entity_from_handle(d_handle_from_dmn(D_ServerID_LocalHost, event->thread));
|
||||
D_Entity *process = d_entity_from_handle(d_handle_from_dmn(D_ServerID_LocalHost, event->process));
|
||||
Arch arch = thread->arch;
|
||||
U64 thread_rip_vaddr = d_ip_from_thread(thread->handle);
|
||||
D_Entity *module = d_module_from_process_vaddr(process, thread_rip_vaddr);
|
||||
@@ -5499,7 +5552,7 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
D_EventCause cond_bp_single_step_stop_cause = D_EventCause_Null;
|
||||
if(hit_conditional_bp_but_filtered) LogInfoNamedBlockF("conditional_bp_hit_single_step")
|
||||
{
|
||||
D_Handle thread = d_handle_from_dmn(D_DemonID_LocalHost, event->thread);
|
||||
D_Handle thread = d_handle_from_dmn(D_ServerID_LocalHost, event->thread);
|
||||
U64 thread_pre_rip = d_ip_from_thread(thread);
|
||||
U64 thread_post_rip = thread_pre_rip;
|
||||
for(B32 single_step_done = 0; !single_step_done;)
|
||||
@@ -5529,7 +5582,7 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
}break;
|
||||
case DMN_EventKind_SingleStep:
|
||||
{
|
||||
single_step_done = d_handle_match(d_handle_from_dmn(D_DemonID_LocalHost, event->thread), thread);
|
||||
single_step_done = d_handle_match(d_handle_from_dmn(D_ServerID_LocalHost, event->thread), thread);
|
||||
cond_bp_single_step_stop_cause = d_event_cause_from_dmn_event_kind(event->kind);
|
||||
}break;
|
||||
}
|
||||
@@ -5690,7 +5743,7 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
D_EventCause step_past_trap_net_stop_cause = D_EventCause_Null;
|
||||
if(step_past_trap_net) LogInfoNamedBlockF("trap_net__single_step_past_trap_net")
|
||||
{
|
||||
D_Handle thread = d_handle_from_dmn(D_DemonID_LocalHost, event->thread);
|
||||
D_Handle thread = d_handle_from_dmn(D_ServerID_LocalHost, event->thread);
|
||||
U64 thread_pre_rip = d_ip_from_thread(thread);
|
||||
U64 thread_post_rip = thread_pre_rip;
|
||||
for(B32 single_step_done = 0; single_step_done == 0;)
|
||||
@@ -5719,7 +5772,7 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
}break;
|
||||
case DMN_EventKind_SingleStep:
|
||||
{
|
||||
single_step_done = d_handle_match(d_handle_from_dmn(D_DemonID_LocalHost, event->thread), thread);
|
||||
single_step_done = d_handle_match(d_handle_from_dmn(D_ServerID_LocalHost, event->thread), thread);
|
||||
step_past_trap_net_stop_cause = d_event_cause_from_dmn_event_kind(event->kind);
|
||||
}break;
|
||||
}
|
||||
@@ -5779,8 +5832,8 @@ d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
D_Event *event = d_event_list_push(scratch.arena, &evts);
|
||||
event->kind = D_EventKind_Stopped;
|
||||
event->cause = stop_cause;
|
||||
event->entity = d_handle_from_dmn(D_DemonID_LocalHost, stop_event->thread);
|
||||
event->parent = d_handle_from_dmn(D_DemonID_LocalHost, stop_event->process);
|
||||
event->entity = d_handle_from_dmn(D_ServerID_LocalHost, stop_event->thread);
|
||||
event->parent = d_handle_from_dmn(D_ServerID_LocalHost, stop_event->process);
|
||||
event->exception_code = stop_event->code;
|
||||
event->exception_kind = d_exception_kind_from_dmn(stop_event->exception_kind);
|
||||
event->vaddr_rng = r1u64(stop_event->address, stop_event->address);
|
||||
@@ -5863,8 +5916,8 @@ d_ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg)
|
||||
event->cause = stop_cause;
|
||||
if(stop_event != 0)
|
||||
{
|
||||
event->entity = d_handle_from_dmn(D_DemonID_LocalHost, stop_event->thread);
|
||||
event->parent = d_handle_from_dmn(D_DemonID_LocalHost, stop_event->process);
|
||||
event->entity = d_handle_from_dmn(D_ServerID_LocalHost, stop_event->thread);
|
||||
event->parent = d_handle_from_dmn(D_ServerID_LocalHost, stop_event->process);
|
||||
event->exception_code = stop_event->code;
|
||||
event->exception_kind = d_exception_kind_from_dmn(stop_event->exception_kind);
|
||||
event->vaddr_rng = r1u64(stop_event->address, stop_event->address);
|
||||
|
||||
@@ -321,6 +321,7 @@ struct D_CtrlState
|
||||
{
|
||||
Arena *arena;
|
||||
D_WakeupFunctionType *wakeup_hook;
|
||||
SOCK_Session sock_session;
|
||||
|
||||
// rjf: name -> register hash tables for eval
|
||||
E_String2NumMap arch_string2reg_tables[Arch_COUNT];
|
||||
@@ -371,6 +372,7 @@ struct D_CtrlState
|
||||
U64 exception_code_filters[(D_ExceptionCodeKind_COUNT+63)/64];
|
||||
B32 auto_download_debug_info;
|
||||
U64 process_counter;
|
||||
D_ServerID server_id_gen;
|
||||
Arena *dbg_dir_arena;
|
||||
D_DbgDirNode *dbg_dir_root;
|
||||
U64 module_req_cache_slots_count;
|
||||
@@ -426,8 +428,8 @@ internal D_HandleArray d_handle_array_from_list(Arena *arena, D_HandleList *src
|
||||
internal String8 d_string_from_handle(Arena *arena, D_Handle handle);
|
||||
internal D_Handle d_handle_from_string(String8 string);
|
||||
internal DMN_Handle d_dmn_from_handle(D_Handle handle);
|
||||
internal D_Handle d_handle_from_dmn(D_DemonID demon_id, DMN_Handle handle);
|
||||
internal D_Handle d_dump_handle_make(D_DemonID demon_id, U64 id);
|
||||
internal D_Handle d_handle_from_dmn(D_ServerID server_id, DMN_Handle handle);
|
||||
internal D_Handle d_dump_handle_make(D_ServerID server_id, U64 id);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Trap Type Functions
|
||||
|
||||
@@ -2104,13 +2104,13 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
|
||||
}break;
|
||||
case D_CmdKind_FreezeLocalServer:
|
||||
{
|
||||
D_DemonID demon_id = D_DemonID_LocalHost;
|
||||
d_cmd(D_CmdKind_FreezeServer, .entity = d_handle_from_dmn(demon_id, dmn_handle_zero()));
|
||||
D_ServerID server_id = D_ServerID_LocalHost;
|
||||
d_cmd(D_CmdKind_FreezeServer, .entity = d_handle_from_dmn(server_id, dmn_handle_zero()));
|
||||
}break;
|
||||
case D_CmdKind_ThawLocalServer:
|
||||
{
|
||||
D_DemonID demon_id = D_DemonID_LocalHost;
|
||||
d_cmd(D_CmdKind_ThawServer, .entity = d_handle_from_dmn(demon_id, dmn_handle_zero()));
|
||||
D_ServerID server_id = D_ServerID_LocalHost;
|
||||
d_cmd(D_CmdKind_ThawServer, .entity = d_handle_from_dmn(server_id, dmn_handle_zero()));
|
||||
}break;
|
||||
case D_CmdKind_FreezeEntity:
|
||||
case D_CmdKind_ThawEntity:
|
||||
|
||||
@@ -265,7 +265,11 @@ typedef enum D_EventKind
|
||||
D_EventKind_MemDecommit,
|
||||
D_EventKind_MemRelease,
|
||||
|
||||
//- rjf: remote connections
|
||||
//- rjf: remote server connections
|
||||
D_EventKind_ServerConnect,
|
||||
D_EventKind_ServerDisconnect,
|
||||
|
||||
//- rjf: remote controllers
|
||||
D_EventKind_RemoteControllerConnect,
|
||||
D_EventKind_RemoteControllerDisconnect,
|
||||
|
||||
|
||||
+139
-70
@@ -5,30 +5,41 @@
|
||||
//~ rjf: Message Parsing
|
||||
|
||||
internal DS_Msg
|
||||
ds_msg_from_serialized(Arena *arena, String8 data)
|
||||
ds_msg_from_packet(Arena *arena, String8 data)
|
||||
{
|
||||
//- rjf: read packet header
|
||||
DS_PacketHeader header = {0};
|
||||
{
|
||||
str8_deserial_read_struct(data, 0, &header);
|
||||
}
|
||||
|
||||
//- rjf: get message payload part
|
||||
String8 payload = str8_substr(data, r1u64(sizeof(header), sizeof(header)+header.payload_size));
|
||||
|
||||
//- rjf: read message
|
||||
DS_Msg msg = {0};
|
||||
if(header.magic == DS_PACKET_MAGIC && header.kind == DS_PacketKind_Msg && header.version == DS_PACKET_VERSION)
|
||||
{
|
||||
U64 off = 0;
|
||||
|
||||
// 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.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);
|
||||
off += str8_deserial_read_struct(data, off, &msg.pid);
|
||||
off += str8_deserial_read_struct(payload, off, &msg.kind);
|
||||
off += str8_deserial_read_struct(payload, off, &msg.flags);
|
||||
off += str8_deserial_read_struct(payload, off, &msg.msg_id);
|
||||
off += str8_deserial_read_struct(payload, off, &msg.vaddr_range);
|
||||
off += str8_deserial_read_struct(payload, off, &msg.access_flags);
|
||||
off += str8_deserial_read_struct(payload, off, &msg.entity);
|
||||
off += str8_deserial_read_struct(payload, off, &msg.pid);
|
||||
|
||||
// rjf: read command line strings
|
||||
{
|
||||
U64 cmd_line_string_count = 0;
|
||||
off += str8_deserial_read_struct(data, off, &cmd_line_string_count);
|
||||
off += str8_deserial_read_struct(payload, off, &cmd_line_string_count);
|
||||
for EachIndex(idx, cmd_line_string_count)
|
||||
{
|
||||
String8 string = {0};
|
||||
off += str8_deserial_read_struct(data, off, &string.size);
|
||||
string = str8_substr(data, r1u64(off, off+string.size));
|
||||
off += str8_deserial_read_struct(payload, off, &string.size);
|
||||
string = str8_substr(payload, r1u64(off, off+string.size));
|
||||
str8_list_push(arena, &msg.command_line, string);
|
||||
}
|
||||
}
|
||||
@@ -36,20 +47,20 @@ ds_msg_from_serialized(Arena *arena, String8 data)
|
||||
// rjf: read path
|
||||
{
|
||||
String8 string = {0};
|
||||
off += str8_deserial_read_struct(data, off, &string.size);
|
||||
string = str8_substr(data, r1u64(off, off+string.size));
|
||||
off += str8_deserial_read_struct(payload, off, &string.size);
|
||||
string = str8_substr(payload, r1u64(off, off+string.size));
|
||||
msg.path = string;
|
||||
}
|
||||
|
||||
// rjf: read environment strings
|
||||
{
|
||||
U64 env_string_count = 0;
|
||||
off += str8_deserial_read_struct(data, off, &env_string_count);
|
||||
off += str8_deserial_read_struct(payload, off, &env_string_count);
|
||||
for EachIndex(idx, env_string_count)
|
||||
{
|
||||
String8 string = {0};
|
||||
off += str8_deserial_read_struct(data, off, &string.size);
|
||||
string = str8_substr(data, r1u64(off, off+string.size));
|
||||
off += str8_deserial_read_struct(payload, off, &string.size);
|
||||
string = str8_substr(payload, r1u64(off, off+string.size));
|
||||
str8_list_push(arena, &msg.env, string);
|
||||
}
|
||||
}
|
||||
@@ -57,15 +68,15 @@ ds_msg_from_serialized(Arena *arena, String8 data)
|
||||
// rjf: read traps
|
||||
{
|
||||
U64 trap_count = 0;
|
||||
off += str8_deserial_read_struct(data, off, &trap_count);
|
||||
off += str8_deserial_read_struct(payload, off, &trap_count);
|
||||
for EachIndex(idx, trap_count)
|
||||
{
|
||||
DMN_Trap trap = {0};
|
||||
off += str8_deserial_read_struct(data, off, &trap.process);
|
||||
off += str8_deserial_read_struct(data, off, &trap.vaddr);
|
||||
off += str8_deserial_read_struct(data, off, &trap.id);
|
||||
off += str8_deserial_read_struct(data, off, &trap.flags);
|
||||
off += str8_deserial_read_struct(data, off, &trap.size);
|
||||
off += str8_deserial_read_struct(payload, off, &trap.process);
|
||||
off += str8_deserial_read_struct(payload, off, &trap.vaddr);
|
||||
off += str8_deserial_read_struct(payload, off, &trap.id);
|
||||
off += str8_deserial_read_struct(payload, off, &trap.flags);
|
||||
off += str8_deserial_read_struct(payload, off, &trap.size);
|
||||
dmn_trap_chunk_list_push(arena, &msg.traps, trap_count, &trap);
|
||||
}
|
||||
}
|
||||
@@ -74,12 +85,14 @@ ds_msg_from_serialized(Arena *arena, String8 data)
|
||||
}
|
||||
|
||||
internal String8
|
||||
ds_serialized_from_msg(Arena *arena, DS_Msg *msg)
|
||||
ds_packet_from_msg(Arena *arena, DS_Msg *msg)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
String8List srl = {0};
|
||||
str8_serial_begin(scratch.arena, &srl);
|
||||
{
|
||||
// NOTE(rjf): (header wrote to beginning of `srl` at end of path)
|
||||
|
||||
// rjf: write flat parts
|
||||
str8_serial_push_struct(scratch.arena, &srl, &msg->kind);
|
||||
str8_serial_push_struct(scratch.arena, &srl, &msg->flags);
|
||||
@@ -130,6 +143,16 @@ ds_serialized_from_msg(Arena *arena, DS_Msg *msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: push packet header (to front)
|
||||
DS_PacketHeader header =
|
||||
{
|
||||
.magic = DS_PACKET_MAGIC,
|
||||
.kind = DS_PacketKind_Msg,
|
||||
.version = DS_PACKET_VERSION,
|
||||
.payload_size = (U32)srl.total_size,
|
||||
};
|
||||
str8_list_push_front(scratch.arena, &srl, str8_copy(scratch.arena, str8_struct(&header)));
|
||||
}
|
||||
String8 result = str8_serial_end(arena, &srl);
|
||||
scratch_end(scratch);
|
||||
@@ -137,33 +160,46 @@ ds_serialized_from_msg(Arena *arena, DS_Msg *msg)
|
||||
}
|
||||
|
||||
internal DS_Response
|
||||
ds_response_from_serialized(Arena *arena, String8 data)
|
||||
ds_response_from_packet(Arena *arena, String8 data)
|
||||
{
|
||||
//- rjf: read packet header
|
||||
DS_PacketHeader header = {0};
|
||||
{
|
||||
str8_deserial_read_struct(data, 0, &header);
|
||||
}
|
||||
|
||||
//- rjf: get message payload part
|
||||
String8 payload = str8_substr(data, r1u64(sizeof(header), sizeof(header)+header.payload_size));
|
||||
|
||||
//- rjf: read response
|
||||
DS_Response result = {0};
|
||||
if(header.magic == DS_PACKET_MAGIC && header.kind == DS_PacketKind_Response && header.version == DS_PACKET_VERSION)
|
||||
{
|
||||
U64 off = 0;
|
||||
|
||||
// rjf: read flat parts
|
||||
off += str8_deserial_read_struct(data, off, &result.msg_id);
|
||||
off += str8_deserial_read_struct(data, off, &result.entity);
|
||||
off += str8_deserial_read_struct(data, off, &result.pid);
|
||||
off += str8_deserial_read_struct(data, off, &result.good);
|
||||
off += str8_deserial_read_struct(payload, off, &result.msg_id);
|
||||
off += str8_deserial_read_struct(payload, off, &result.entity);
|
||||
off += str8_deserial_read_struct(payload, off, &result.pid);
|
||||
off += str8_deserial_read_struct(payload, off, &result.good);
|
||||
|
||||
// rjf: read data payload
|
||||
off += str8_deserial_read_struct(data, off, &result.data.size);
|
||||
off += str8_deserial_read_struct(payload, off, &result.data.size);
|
||||
result.data.str = push_array(arena, U8, result.data.size);
|
||||
off += str8_deserial_read(data, off, result.data.str, result.data.size, result.data.size);
|
||||
off += str8_deserial_read(payload, off, result.data.str, result.data.size, result.data.size);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
ds_serialized_from_response(Arena *arena, DS_Response *response)
|
||||
ds_packet_from_response(Arena *arena, DS_Response *response)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
String8List srl = {0};
|
||||
str8_serial_begin(scratch.arena, &srl);
|
||||
{
|
||||
// NOTE(rjf): (header wrote to beginning of `srl` at end of path)
|
||||
|
||||
// rjf: write flat parts
|
||||
str8_serial_push_struct(scratch.arena, &srl, &response->msg_id);
|
||||
str8_serial_push_struct(scratch.arena, &srl, &response->entity);
|
||||
@@ -173,6 +209,16 @@ ds_serialized_from_response(Arena *arena, DS_Response *response)
|
||||
// rjf: write data payload
|
||||
str8_serial_push_struct(scratch.arena, &srl, &response->data.size);
|
||||
str8_serial_push_string(scratch.arena, &srl, response->data);
|
||||
|
||||
// rjf: push packet header (to front)
|
||||
DS_PacketHeader header =
|
||||
{
|
||||
.magic = DS_PACKET_MAGIC,
|
||||
.kind = DS_PacketKind_Response,
|
||||
.version = DS_PACKET_VERSION,
|
||||
.payload_size = (U32)srl.total_size,
|
||||
};
|
||||
str8_list_push_front(scratch.arena, &srl, str8_copy(scratch.arena, str8_struct(&header)));
|
||||
}
|
||||
String8 result = str8_serial_end(arena, &srl);
|
||||
scratch_end(scratch);
|
||||
@@ -180,44 +226,55 @@ ds_serialized_from_response(Arena *arena, DS_Response *response)
|
||||
}
|
||||
|
||||
internal DMN_EventList
|
||||
ds_dmn_events_from_serialized(Arena *arena, String8 data)
|
||||
ds_dmn_events_from_packet(Arena *arena, String8 data)
|
||||
{
|
||||
//- rjf: read packet header
|
||||
DS_PacketHeader header = {0};
|
||||
{
|
||||
str8_deserial_read_struct(data, 0, &header);
|
||||
}
|
||||
|
||||
//- rjf: get message payload part
|
||||
String8 payload = str8_substr(data, r1u64(sizeof(header), sizeof(header)+header.payload_size));
|
||||
|
||||
//- rjf: read events
|
||||
DMN_EventList evts = {0};
|
||||
if(header.magic == DS_PACKET_MAGIC && header.kind == DS_PacketKind_Event && header.version == DS_PACKET_VERSION)
|
||||
{
|
||||
U64 off = 0;
|
||||
U64 demon_event_count = 0;
|
||||
off += str8_deserial_read_struct(data, off, &demon_event_count);
|
||||
off += str8_deserial_read_struct(payload, off, &demon_event_count);
|
||||
for EachIndex(idx, demon_event_count)
|
||||
{
|
||||
DMN_Event *evt = dmn_event_list_push(arena, &evts);
|
||||
|
||||
// rjf: read flat parts
|
||||
off += str8_deserial_read_struct(data, off, &evt->kind);
|
||||
off += str8_deserial_read_struct(data, off, &evt->error_kind);
|
||||
off += str8_deserial_read_struct(data, off, &evt->memory_kind);
|
||||
off += str8_deserial_read_struct(data, off, &evt->exception_kind);
|
||||
off += str8_deserial_read_struct(data, off, &evt->process);
|
||||
off += str8_deserial_read_struct(data, off, &evt->thread);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module);
|
||||
off += str8_deserial_read_struct(data, off, &evt->arch);
|
||||
off += str8_deserial_read_struct(data, off, &evt->address);
|
||||
off += str8_deserial_read_struct(data, off, &evt->size);
|
||||
off += str8_deserial_read_struct(data, off, &evt->code);
|
||||
off += str8_deserial_read_struct(data, off, &evt->flags);
|
||||
off += str8_deserial_read_struct(data, off, &evt->instruction_pointer);
|
||||
off += str8_deserial_read_struct(data, off, &evt->stack_pointer);
|
||||
off += str8_deserial_read_struct(data, off, &evt->user_data);
|
||||
off += str8_deserial_read_struct(data, off, &evt->exception_repeated);
|
||||
off += str8_deserial_read_struct(data, off, &evt->tls_root_vaddr);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->kind);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->error_kind);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->memory_kind);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->exception_kind);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->process);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->thread);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->arch);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->address);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->size);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->code);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->flags);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->instruction_pointer);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->stack_pointer);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->user_data);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->exception_repeated);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->tls_root_vaddr);
|
||||
|
||||
// rjf: read string
|
||||
off += str8_deserial_read_struct(data, off, &evt->string.size);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->string.size);
|
||||
evt->string.str = push_array(arena, U8, evt->string.size);
|
||||
off += str8_deserial_read(data, off, evt->string.str, evt->string.size, 1);
|
||||
off += str8_deserial_read(payload, off, evt->string.str, evt->string.size, 1);
|
||||
|
||||
// rjf: read module info
|
||||
B8 has_module_info = 0;
|
||||
off += str8_deserial_read_struct(data, off, &has_module_info);
|
||||
off += str8_deserial_read_struct(payload, off, &has_module_info);
|
||||
if(!has_module_info)
|
||||
{
|
||||
evt->module_info = &dmn_module_info_nil;
|
||||
@@ -227,26 +284,26 @@ ds_dmn_events_from_serialized(Arena *arena, String8 data)
|
||||
evt->module_info = push_array(arena, DMN_ModuleInfo, 1);
|
||||
|
||||
// rjf: read flat parts
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->arch);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->vsize);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->entry_point_voff);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->debug_info_guid);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->debug_info_timestamp);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->debug_info_age);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->tls_index);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->tls_offset);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->pe_intel_pdatas_vaddr_range);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->eh_frame_header_vaddr_range);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->raddbg_info_voff_range);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->raddbg_is_attached_marker_voff);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->arch);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->vsize);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->entry_point_voff);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->debug_info_guid);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->debug_info_timestamp);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->debug_info_age);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->tls_index);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->tls_offset);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->pe_intel_pdatas_vaddr_range);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->eh_frame_header_vaddr_range);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->raddbg_info_voff_range);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->raddbg_is_attached_marker_voff);
|
||||
|
||||
// rjf: read paths
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->module_path.size);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->module_path.size);
|
||||
evt->module_info->module_path.str = push_array(arena, U8, evt->module_info->module_path.size);
|
||||
off += str8_deserial_read(data, off, evt->module_info->module_path.str, evt->module_info->module_path.size, 1);
|
||||
off += str8_deserial_read_struct(data, off, &evt->module_info->debug_info_path.size);
|
||||
off += str8_deserial_read(payload, off, evt->module_info->module_path.str, evt->module_info->module_path.size, 1);
|
||||
off += str8_deserial_read_struct(payload, off, &evt->module_info->debug_info_path.size);
|
||||
evt->module_info->debug_info_path.str = push_array(arena, U8, evt->module_info->debug_info_path.size);
|
||||
off += str8_deserial_read(data, off, evt->module_info->debug_info_path.str, evt->module_info->debug_info_path.size, 1);
|
||||
off += str8_deserial_read(payload, off, evt->module_info->debug_info_path.str, evt->module_info->debug_info_path.size, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,12 +311,14 @@ ds_dmn_events_from_serialized(Arena *arena, String8 data)
|
||||
}
|
||||
|
||||
internal String8
|
||||
ds_serialized_from_dmn_events(Arena *arena, DMN_EventList evts)
|
||||
ds_packet_from_dmn_events(Arena *arena, DMN_EventList evts)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
String8List srl = {0};
|
||||
str8_serial_begin(scratch.arena, &srl);
|
||||
{
|
||||
// NOTE(rjf): (header wrote to beginning of `srl` at end of path)
|
||||
|
||||
// rjf: write events
|
||||
str8_serial_push_struct(scratch.arena, &srl, &evts.count);
|
||||
for EachNode(n, DMN_EventNode, evts.first)
|
||||
@@ -313,6 +372,16 @@ ds_serialized_from_dmn_events(Arena *arena, DMN_EventList evts)
|
||||
str8_serial_push_string(scratch.arena, &srl, n->v.module_info->debug_info_path);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: push packet header (to front)
|
||||
DS_PacketHeader header =
|
||||
{
|
||||
.magic = DS_PACKET_MAGIC,
|
||||
.kind = DS_PacketKind_Event,
|
||||
.version = DS_PACKET_VERSION,
|
||||
.payload_size = (U32)srl.total_size,
|
||||
};
|
||||
str8_list_push_front(scratch.arena, &srl, str8_copy(scratch.arena, str8_struct(&header)));
|
||||
}
|
||||
String8 result = str8_serial_end(arena, &srl);
|
||||
scratch_end(scratch);
|
||||
|
||||
@@ -34,6 +34,9 @@ typedef enum DS_MsgKind
|
||||
{
|
||||
DS_MsgKind_Null,
|
||||
|
||||
//- rjf: connection handshake
|
||||
DS_MsgKind_Handshake,
|
||||
|
||||
//- rjf: debuggee attaching/detaching ops
|
||||
DS_MsgKind_Launch,
|
||||
DS_MsgKind_Attach,
|
||||
@@ -123,11 +126,11 @@ struct DS_ResponseNode
|
||||
////////////////////////////////
|
||||
//~ 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 DS_Response ds_response_from_serialized(Arena *arena, String8 data);
|
||||
internal String8 ds_serialized_from_response(Arena *arena, DS_Response *response);
|
||||
internal DMN_EventList ds_dmn_events_from_serialized(Arena *arena, String8 data);
|
||||
internal DS_Msg ds_msg_from_packet(Arena *arena, String8 data);
|
||||
internal String8 ds_packet_from_msg(Arena *arena, DS_Msg *msg);
|
||||
internal DS_Response ds_response_from_packet(Arena *arena, String8 data);
|
||||
internal String8 ds_packet_from_response(Arena *arena, DS_Response *response);
|
||||
internal DMN_EventList ds_dmn_events_from_packet(Arena *arena, String8 data);
|
||||
internal String8 ds_serialized_from_dmn_events(Arena *arena, DMN_EventList evts);
|
||||
|
||||
#endif // DBG_SERVER_H
|
||||
@@ -348,6 +348,7 @@ sock_session_open(U16 listener_port, SOCK_WakeupFunctionType *wakeup_hook)
|
||||
session->wakeup_hook = wakeup_hook;
|
||||
|
||||
//- rjf: set up listener
|
||||
if(listener_port != 0)
|
||||
{
|
||||
session->tcp_listen_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
U32 ipv6only = 0;
|
||||
|
||||
@@ -711,7 +711,7 @@ rd_ctrl_entity_from_eval_space(E_Space space)
|
||||
space.kind == RD_EvalSpaceKind_MetaUnattachedProcess)
|
||||
{
|
||||
D_Handle handle;
|
||||
handle.demon_id = (U32)((space.u64s[0] & 0xffffffff00000000ull) >> 32);
|
||||
handle.server_id = (U32)((space.u64s[0] & 0xffffffff00000000ull) >> 32);
|
||||
handle.controller_kind = (U32)((space.u64s[0] & 0x00000000ffffffffull) >> 0);
|
||||
handle.entity_id = space.u64s[1];
|
||||
entity = d_entity_from_handle(handle);
|
||||
@@ -726,7 +726,7 @@ rd_eval_space_from_ctrl_entity(D_Entity *entity, E_SpaceKind kind)
|
||||
if(entity != &d_entity_nil)
|
||||
{
|
||||
space = e_space_make(kind);
|
||||
space.u64s[0] = (((U64)entity->handle.demon_id) << 32) | (((U64)entity->handle.controller_kind) << 0);
|
||||
space.u64s[0] = (((U64)entity->handle.server_id) << 32) | (((U64)entity->handle.controller_kind) << 0);
|
||||
space.u64s[1] = entity->handle.entity_id;
|
||||
}
|
||||
return space;
|
||||
@@ -2828,7 +2828,7 @@ rd_view_ui(Rng2F32 rect)
|
||||
CFG_Node *locked = cfg_node_child_from_string_or_alloc(rd_state->cfg, cfg, s("locked"));
|
||||
cfg_node_release_all_children(rd_state->cfg, locked);
|
||||
CFG_Node *mid = cfg_node_new(rd_state->cfg, locked, s("mid"));
|
||||
cfg_node_newf(rd_state->cfg, mid, "%I64u", entity->handle.demon_id);
|
||||
cfg_node_newf(rd_state->cfg, mid, "%I64u", entity->handle.server_id);
|
||||
CFG_Node *pid = cfg_node_new(rd_state->cfg, locked, s("pid"));
|
||||
cfg_node_newf(rd_state->cfg, pid, "%I64u", entity->id);
|
||||
CFG_Node *addr = cfg_node_new(rd_state->cfg, locked, s("addr"));
|
||||
@@ -4631,7 +4631,7 @@ rd_view_ui(Rng2F32 rect)
|
||||
CFG_Node *locked = cfg_node_child_from_string_or_alloc(rd_state->cfg, cfg, s("locked"));
|
||||
cfg_node_release_all_children(rd_state->cfg, locked);
|
||||
CFG_Node *mid = cfg_node_new(rd_state->cfg, locked, s("mid"));
|
||||
cfg_node_newf(rd_state->cfg, mid, "%I64u", entity->handle.demon_id);
|
||||
cfg_node_newf(rd_state->cfg, mid, "%I64u", entity->handle.server_id);
|
||||
CFG_Node *pid = cfg_node_new(rd_state->cfg, locked, s("pid"));
|
||||
cfg_node_newf(rd_state->cfg, pid, "%I64u", entity->id);
|
||||
CFG_Node *addr = cfg_node_new(rd_state->cfg, locked, s("addr"));
|
||||
@@ -6367,7 +6367,7 @@ rd_window_frame(void)
|
||||
ID(panel);
|
||||
ID(view);
|
||||
#undef ID
|
||||
#define Handle(name) ui_labelf("%s: [0x%x, 0x%x, 0x%I64x]", #name, (regs->name).demon_id, (regs->name).controller_kind, (regs->name).entity_id)
|
||||
#define Handle(name) ui_labelf("%s: [0x%x, 0x%x, 0x%I64x]", #name, (regs->name).server_id, (regs->name).controller_kind, (regs->name).entity_id)
|
||||
Handle(server);
|
||||
Handle(process);
|
||||
Handle(module);
|
||||
@@ -12863,7 +12863,7 @@ rd_frame(void)
|
||||
{
|
||||
e_string2expr_map_insert(scratch.arena, macro_map, entity->string, expr);
|
||||
}
|
||||
if(kind == D_EntityKind_Server && entity->handle.demon_id == D_DemonID_LocalHost)
|
||||
if(kind == D_EntityKind_Server && entity->handle.server_id == D_ServerID_LocalHost)
|
||||
{
|
||||
e_string2expr_map_insert(scratch.arena, macro_map, str8_lit("local_server"), expr);
|
||||
}
|
||||
|
||||
+21
-19
@@ -463,6 +463,7 @@
|
||||
#include "disasm/disasm_inc.h"
|
||||
#include "stap/stap_parse.h"
|
||||
#include "demon/demon_inc.h"
|
||||
#include "dbg_server/dbg_server.h"
|
||||
#include "eval/eval_inc.h"
|
||||
#include "eval2/eval2.h"
|
||||
#include "dbg_engine/dbg_engine_inc.h"
|
||||
@@ -526,6 +527,7 @@
|
||||
#include "disasm/disasm_inc.c"
|
||||
#include "stap/stap_parse.c"
|
||||
#include "demon/demon_inc.c"
|
||||
#include "dbg_server/dbg_server.c"
|
||||
#include "eval/eval_inc.c"
|
||||
#include "eval2/eval2.c"
|
||||
#include "dbg_engine/dbg_engine_inc.c"
|
||||
@@ -892,25 +894,25 @@ entry_point(CmdLine *cmd_line)
|
||||
case ExecMode_Help:
|
||||
{
|
||||
sh_message(0,
|
||||
str8_lit("The RAD Debugger - Help"),
|
||||
str8_lit("The following options may be used when starting the RAD Debugger from the command line:\n\n"
|
||||
"--user:<path>\n"
|
||||
"Use to specify the location of a user file which should be used. User files are used to store settings for users, including window and panel setups, path mapping, and visual settings. If this file does not exist, it will be created as necessary. This file will be autosaved as user-related changes are made.\n\n"
|
||||
"--project:<path>\n"
|
||||
"Use to specify the location of a project file which should be used. Project files are used to store settings for users and projects. If this file does not exist, it will be created as necessary. This file will be autosaved as project-related changes are made.\n\n"
|
||||
"--auto_step\n"
|
||||
"This will step into all active targets after the debugger initially starts.\n\n"
|
||||
"--auto_run\n"
|
||||
"This will run all active targets after the debugger initially starts.\n\n"
|
||||
"--quit_after_success (or -q)\n"
|
||||
"This will close the debugger automatically after all processes exit, if they all exited successfully (with code 0), and ran with no interruptions.\n\n"
|
||||
"--ipc <command>\n"
|
||||
"This will launch the debugger in the non-graphical IPC mode, which is used to communicate with another running instance of the debugger. The debugger instance will launch, send the specified command, then immediately terminate. This may be used by editors or other programs to control the debugger.\n\n"
|
||||
"--gen_crash_dump\n"
|
||||
"Generate mini dump on crash.\n\n"
|
||||
"--logs:<path>\n"
|
||||
"Overrides default path to the folder with logs.\n"
|
||||
));
|
||||
s("The RAD Debugger - Help"),
|
||||
s("The following options may be used when starting the RAD Debugger from the command line:\n\n"
|
||||
"--user:<path>\n"
|
||||
"Use to specify the location of a user file which should be used. User files are used to store settings for users, including window and panel setups, path mapping, and visual settings. If this file does not exist, it will be created as necessary. This file will be autosaved as user-related changes are made.\n\n"
|
||||
"--project:<path>\n"
|
||||
"Use to specify the location of a project file which should be used. Project files are used to store settings for users and projects. If this file does not exist, it will be created as necessary. This file will be autosaved as project-related changes are made.\n\n"
|
||||
"--auto_step\n"
|
||||
"This will step into all active targets after the debugger initially starts.\n\n"
|
||||
"--auto_run\n"
|
||||
"This will run all active targets after the debugger initially starts.\n\n"
|
||||
"--quit_after_success (or -q)\n"
|
||||
"This will close the debugger automatically after all processes exit, if they all exited successfully (with code 0), and ran with no interruptions.\n\n"
|
||||
"--ipc <command>\n"
|
||||
"This will launch the debugger in the non-graphical IPC mode, which is used to communicate with another running instance of the debugger. The debugger instance will launch, send the specified command, then immediately terminate. This may be used by editors or other programs to control the debugger.\n\n"
|
||||
"--gen_crash_dump\n"
|
||||
"Generate mini dump on crash.\n\n"
|
||||
"--logs:<path>\n"
|
||||
"Overrides default path to the folder with logs.\n"
|
||||
));
|
||||
}break;
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ dmn_thread__entry_point(void *p)
|
||||
for(RDS_Msg *msg_n = msg_first; msg_n != 0; msg_n = msg_n->next)
|
||||
{
|
||||
//- rjf: unpack message
|
||||
DS_Msg msg = ds_msg_from_serialized(scratch.arena, msg_n->msg_raw);
|
||||
DS_Msg msg = ds_msg_from_packet(scratch.arena, msg_n->msg_raw);
|
||||
|
||||
//- rjf: do action, get response
|
||||
DS_Response response = {0};
|
||||
@@ -198,7 +198,7 @@ dmn_thread__entry_point(void *p)
|
||||
|
||||
//- rjf: pack response & send back to the originating endpoint of the message
|
||||
{
|
||||
String8 data = ds_serialized_from_response(scratch.arena, &response);
|
||||
String8 data = ds_packet_from_response(scratch.arena, &response);
|
||||
sock_send(rds_state->sock_session, SOCK_Protocol_TCP, msg_n->endpoint, data, max_U64);
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ entry_point(CmdLine *cmd_line)
|
||||
str8_deserial_read_struct(msg_raw, 2, &peek_kind);
|
||||
if(peek_kind < DS_MsgKind_Launch || DS_MsgKind_SingleStep < peek_kind)
|
||||
{
|
||||
DS_Msg msg = ds_msg_from_serialized(scratch.arena, data);
|
||||
DS_Msg msg = ds_msg_from_packet(scratch.arena, data);
|
||||
DS_Response response = {0};
|
||||
switch(msg.kind)
|
||||
{
|
||||
|
||||
@@ -368,6 +368,7 @@ sock_session_open(U16 listener_port, SOCK_WakeupFunctionType *wakeup_hook)
|
||||
session->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
|
||||
|
||||
//- rjf: set up listener(s)
|
||||
if(listener_port != 0)
|
||||
{
|
||||
session->tcp_listen_socket = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED);
|
||||
DWORD ipv6only = 0;
|
||||
|
||||
Reference in new issue
Block a user