mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-11-14 02:03:27 -08:00
raddbg_server: adjust split between main / demon thread - main thread can handle many things, like memory & regs reads/writes, but cannot handle ctrl-thread-only operations.
This commit is contained in:
1 parent
34a0ff4e80
commit
7da38c5f3b
3 files changed
+107
-112
No files matched your search
@@ -1,2 +1,81 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Message Parsing
|
||||
|
||||
internal RDS_Msg
|
||||
rds_msg_from_data(Arena *arena, String8 data)
|
||||
{
|
||||
//- rjf: unpack message
|
||||
U16 magic_maybe = 0;
|
||||
str8_deserial_read_struct(data, 0, &magic_maybe);
|
||||
|
||||
//- rjf: parse message
|
||||
RDS_Msg msg = {0};
|
||||
if(magic_maybe == RDS_MSG_MAGIC)
|
||||
{
|
||||
U64 off = sizeof(magic_maybe);
|
||||
|
||||
// rjf: read flat parts
|
||||
off += str8_deserial_read_struct(data, off, &msg.kind);
|
||||
off += str8_deserial_read_struct(data, off, &msg.flags);
|
||||
off += str8_deserial_read_struct(data, off, &msg.id);
|
||||
off += str8_deserial_read_struct(data, off, &msg.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);
|
||||
|
||||
// rjf: read command line strings
|
||||
{
|
||||
U64 cmd_line_string_count = 0;
|
||||
off += str8_deserial_read_struct(data, 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));
|
||||
str8_list_push(arena, &msg.command_line, string);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: read path
|
||||
{
|
||||
String8 string = {0};
|
||||
off += str8_deserial_read_struct(data, off, &string.size);
|
||||
string = str8_substr(data, 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);
|
||||
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));
|
||||
str8_list_push(arena, &msg.env, string);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: read traps
|
||||
{
|
||||
U64 trap_count = 0;
|
||||
off += str8_deserial_read_struct(data, 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);
|
||||
dmn_trap_chunk_list_push(arena, &msg.traps, trap_count, &trap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
@@ -14,14 +14,16 @@ typedef enum RDS_MsgKind
|
||||
RDS_MsgKind_Null,
|
||||
|
||||
//- rjf: debuggee attaching/detaching ops
|
||||
RDS_MsgKind_Launch,
|
||||
RDS_MsgKind_Launch, RDS_MsgKind_DemonThreadHandledFirst = RDS_MsgKind_Launch,
|
||||
RDS_MsgKind_Attach,
|
||||
RDS_MsgKind_Kill,
|
||||
RDS_MsgKind_Detach,
|
||||
|
||||
//- rjf: running ops
|
||||
RDS_MsgKind_Run,
|
||||
RDS_MsgKind_SingleStep,
|
||||
RDS_MsgKind_SingleStep, RDS_MsgKind_DemonThreadHandledLast = RDS_MsgKind_SingleStep,
|
||||
|
||||
//- rjf: halting
|
||||
RDS_MsgKind_Halt,
|
||||
|
||||
//- rjf: memory ops
|
||||
@@ -89,4 +91,9 @@ struct RDS_Response
|
||||
U64 demon_event_count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Message Parsing
|
||||
|
||||
internal RDS_Msg rds_msg_from_data(Arena *arena, String8 data);
|
||||
|
||||
#endif // RADDBG_SERVER_H
|
||||
@@ -94,84 +94,7 @@ dmn_thread__entry_point(void *p)
|
||||
//
|
||||
for(String8Node *msg_n = msgs.first; msg_n != 0; msg_n = msg_n->next)
|
||||
{
|
||||
//////////////////////////
|
||||
//- rjf: unpack message
|
||||
//
|
||||
String8 data = msg_n->string;
|
||||
U16 magic_maybe = 0;
|
||||
str8_deserial_read_struct(data, 0, &magic_maybe);
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: parse message
|
||||
//
|
||||
RDS_Msg msg = {0};
|
||||
if(magic_maybe == RDS_MSG_MAGIC)
|
||||
{
|
||||
U64 off = sizeof(magic_maybe);
|
||||
|
||||
// rjf: read flat parts
|
||||
off += str8_deserial_read_struct(data, off, &msg.kind);
|
||||
off += str8_deserial_read_struct(data, off, &msg.flags);
|
||||
off += str8_deserial_read_struct(data, off, &msg.id);
|
||||
off += str8_deserial_read_struct(data, off, &msg.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);
|
||||
|
||||
// rjf: read command line strings
|
||||
{
|
||||
U64 cmd_line_string_count = 0;
|
||||
off += str8_deserial_read_struct(data, 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));
|
||||
str8_list_push(scratch.arena, &msg.command_line, string);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: read path
|
||||
{
|
||||
String8 string = {0};
|
||||
off += str8_deserial_read_struct(data, off, &string.size);
|
||||
string = str8_substr(data, 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);
|
||||
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));
|
||||
str8_list_push(scratch.arena, &msg.env, string);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: read traps
|
||||
{
|
||||
U64 trap_count = 0;
|
||||
off += str8_deserial_read_struct(data, 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);
|
||||
dmn_trap_chunk_list_push(scratch.arena, &msg.traps, trap_count, &trap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: do message
|
||||
//
|
||||
RDS_Msg msg = rds_msg_from_data(scratch.arena, msg_n->string);
|
||||
switch(msg.kind)
|
||||
{
|
||||
default:{}break;
|
||||
@@ -187,30 +110,6 @@ dmn_thread__entry_point(void *p)
|
||||
|
||||
case RDS_MsgKind_Run:{}break;
|
||||
case RDS_MsgKind_SingleStep:{}break;
|
||||
case RDS_MsgKind_Halt:{}break;
|
||||
|
||||
//- rjf: memory ops
|
||||
|
||||
case RDS_MsgKind_MemoryReserve:{}break;
|
||||
case RDS_MsgKind_MemoryCommit:{}break;
|
||||
case RDS_MsgKind_MemoryDecommit:{}break;
|
||||
case RDS_MsgKind_MemoryRelease:{}break;
|
||||
case RDS_MsgKind_MemoryProtect:{}break;
|
||||
case RDS_MsgKind_MemoryRead:{}break;
|
||||
case RDS_MsgKind_MemoryWrite:{}break;
|
||||
|
||||
//- rjf: thread ops
|
||||
|
||||
case RDS_MsgKind_ThreadRegBlockRead:{}break;
|
||||
case RDS_MsgKind_ThreadRegBlockWrite:{}break;
|
||||
case RDS_MsgKind_ThreadGetModuleTLSVAddr:{}break;
|
||||
|
||||
//- rjf: system ops
|
||||
|
||||
case RDS_MsgKind_ListSystemProcesses:
|
||||
{
|
||||
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,22 +170,32 @@ entry_point(CmdLine *cmd_line)
|
||||
fprintf(stderr, " magic: 0x%x\n", (int)magic_maybe);
|
||||
}
|
||||
|
||||
//- rjf: the only kind of message we handle on the main thread is halting,
|
||||
// since we need to interrupt the actual controller. just look for that one
|
||||
// code here, and handle it - otherwise, all we need to do is send the message
|
||||
// blob to the demon thread.
|
||||
//- rjf: try to handle this message on the main thread, before sending to
|
||||
// demon. the demon thread trades runtimes with debuggees, and so it is
|
||||
// only able to handle messages when it is not running - e.g. launching,
|
||||
// attaching, detaching, and so on. other operations, like reading/writing
|
||||
// memory/registers, listing processes, and halting, we want to just do
|
||||
// on the main thread without interrupting the demon at all.
|
||||
RDS_MsgKind peek_kind = RDS_MsgKind_Null;
|
||||
if(magic_maybe == RDS_MSG_MAGIC)
|
||||
{
|
||||
str8_deserial_read_struct(data, 2, &peek_kind);
|
||||
if(peek_kind == RDS_MsgKind_Halt && rds_state->demon_is_running)
|
||||
if(peek_kind < RDS_MsgKind_DemonThreadHandledFirst || RDS_MsgKind_DemonThreadHandledLast < peek_kind)
|
||||
{
|
||||
dmn_halt(0, 0);
|
||||
RDS_Msg msg = rds_msg_from_data(scratch.arena, data);
|
||||
switch(msg.kind)
|
||||
{
|
||||
default:{}break;
|
||||
case RDS_MsgKind_Halt:
|
||||
{
|
||||
dmn_halt(0, 0);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: not halt? -> okay, send to demon thread, if it's ready.
|
||||
if(magic_maybe == RDS_MSG_MAGIC && peek_kind != RDS_MsgKind_Halt && !rds_state->demon_is_running)
|
||||
//- rjf: not handled by main thread? -> okay, send to demon thread, if it's ready.
|
||||
if(magic_maybe == RDS_MSG_MAGIC && !rds_state->demon_is_running && (RDS_MsgKind_DemonThreadHandledFirst <= peek_kind && peek_kind <= RDS_MsgKind_DemonThreadHandledLast))
|
||||
{
|
||||
RWMutexScope(rds_state->c2d_rw_mutex, 1)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user