From 41598aaf081b183805cc6ca867bc352f26d2a3e4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 12 Oct 2026 08:43:45 -0700 Subject: [PATCH] dbg_server / dbg_engine: checkpoint on remote debug servers --- src/dbg_engine/dbg_engine_core.c | 1 + src/dbg_engine/dbg_engine_core.h | 6 +- src/dbg_engine/dbg_engine_ctrl.c | 157 +++++++++++++------ src/dbg_engine/dbg_engine_ctrl.h | 6 +- src/dbg_engine/dbg_engine_user.c | 8 +- src/dbg_engine/dbg_engine_user.h | 6 +- src/dbg_server/dbg_server.c | 209 ++++++++++++++++--------- src/dbg_server/dbg_server.h | 13 +- src/linux/socket/linux_socket.c | 1 + src/raddbg/raddbg_core.c | 12 +- src/raddbg/raddbg_main.c | 40 ++--- src/raddbg_server/raddbg_server_main.c | 6 +- src/win32/socket/win32_socket.c | 1 + 13 files changed, 301 insertions(+), 165 deletions(-) diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index fe6cf195..7968a0c2 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -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); diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 7192ae36..8e789810 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -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; }; diff --git a/src/dbg_engine/dbg_engine_ctrl.c b/src/dbg_engine/dbg_engine_ctrl.c index 50631345..e8f50689 100644 --- a/src/dbg_engine/dbg_engine_ctrl.c +++ b/src/dbg_engine/dbg_engine_ctrl.c @@ -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); diff --git a/src/dbg_engine/dbg_engine_ctrl.h b/src/dbg_engine/dbg_engine_ctrl.h index 15c30306..cb6241d5 100644 --- a/src/dbg_engine/dbg_engine_ctrl.h +++ b/src/dbg_engine/dbg_engine_ctrl.h @@ -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 diff --git a/src/dbg_engine/dbg_engine_user.c b/src/dbg_engine/dbg_engine_user.c index 2a83fd5b..c0314859 100644 --- a/src/dbg_engine/dbg_engine_user.c +++ b/src/dbg_engine/dbg_engine_user.c @@ -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: diff --git a/src/dbg_engine/dbg_engine_user.h b/src/dbg_engine/dbg_engine_user.h index 953e41b8..3c02a872 100644 --- a/src/dbg_engine/dbg_engine_user.h +++ b/src/dbg_engine/dbg_engine_user.h @@ -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, diff --git a/src/dbg_server/dbg_server.c b/src/dbg_server/dbg_server.c index 1347addc..a6250862 100644 --- a/src/dbg_server/dbg_server.c +++ b/src/dbg_server/dbg_server.c @@ -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); diff --git a/src/dbg_server/dbg_server.h b/src/dbg_server/dbg_server.h index 7ae209ce..1c929482 100644 --- a/src/dbg_server/dbg_server.h +++ b/src/dbg_server/dbg_server.h @@ -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 diff --git a/src/linux/socket/linux_socket.c b/src/linux/socket/linux_socket.c index ed792d18..22d1d65b 100644 --- a/src/linux/socket/linux_socket.c +++ b/src/linux/socket/linux_socket.c @@ -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; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2234ff53..047510ad 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -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); } diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index a3f69200..d5af608e 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -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:\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:\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 \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:\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:\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:\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 \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:\n" + "Overrides default path to the folder with logs.\n" + )); }break; } diff --git a/src/raddbg_server/raddbg_server_main.c b/src/raddbg_server/raddbg_server_main.c index 194f1145..4374eee2 100644 --- a/src/raddbg_server/raddbg_server_main.c +++ b/src/raddbg_server/raddbg_server_main.c @@ -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) { diff --git a/src/win32/socket/win32_socket.c b/src/win32/socket/win32_socket.c index 169db89a..01c23e16 100644 --- a/src/win32/socket/win32_socket.c +++ b/src/win32/socket/win32_socket.c @@ -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;