mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
WIP improved signal handling in multi-threaded programs
This commit is contained in:
@@ -206,3 +206,15 @@ dmn_process_read_raw(Arena *arena, DMN_Handle process, Rng1U64 vrange)
|
|||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal String8
|
||||||
|
dmn_get_trap_inst(void)
|
||||||
|
{
|
||||||
|
#if ARCH_X64
|
||||||
|
local_persist U8 inst[] = { 0xcc };
|
||||||
|
#else
|
||||||
|
# error "trap instruction is not defined for this arch"
|
||||||
|
#endif
|
||||||
|
return str8_array_fixed(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ typedef struct DMN_ActiveTrap DMN_ActiveTrap;
|
|||||||
struct DMN_ActiveTrap
|
struct DMN_ActiveTrap
|
||||||
{
|
{
|
||||||
DMN_Trap *trap;
|
DMN_Trap *trap;
|
||||||
U8 swap_byte;
|
String8 swap_bytes;
|
||||||
DMN_ActiveTrap *next;
|
DMN_ActiveTrap *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -262,4 +262,7 @@ internal void dmn_process_iter_begin(DMN_ProcessIter *iter);
|
|||||||
internal B32 dmn_process_iter_next(Arena *arena, DMN_ProcessIter *iter, DMN_ProcessInfo *info_out);
|
internal B32 dmn_process_iter_next(Arena *arena, DMN_ProcessIter *iter, DMN_ProcessInfo *info_out);
|
||||||
internal void dmn_process_iter_end(DMN_ProcessIter *iter);
|
internal void dmn_process_iter_end(DMN_ProcessIter *iter);
|
||||||
|
|
||||||
|
//- arch trap
|
||||||
|
internal String8 dmn_get_trap_inst(void);
|
||||||
|
|
||||||
#endif // DEMON_CORE_H
|
#endif // DEMON_CORE_H
|
||||||
|
|||||||
+1259
-1236
File diff suppressed because it is too large
Load Diff
@@ -11,19 +11,6 @@
|
|||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
//~ SIGTRAP codes
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
DMN_LNX_SigTrapCode_Brkpt = 1,
|
|
||||||
DMN_LNX_SigTrapCode_Trace = 2,
|
|
||||||
DMN_LNX_SigTrapCode_Branch = 3,
|
|
||||||
DMN_LNX_SigTrapCode_HwBkpt = 4,
|
|
||||||
DMN_LNX_SigTrapCode_Unk = 5,
|
|
||||||
DMN_LNX_SigTrapCode_Perf = 6
|
|
||||||
} DMN_LNX_SigTrapCode;
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Register Layouts
|
//~ rjf: Register Layouts
|
||||||
//
|
//
|
||||||
@@ -143,7 +130,7 @@ typedef struct DMN_LNX_PhdrInfo DMN_LNX_PhdrInfo;
|
|||||||
struct DMN_LNX_PhdrInfo
|
struct DMN_LNX_PhdrInfo
|
||||||
{
|
{
|
||||||
Rng1U64 range;
|
Rng1U64 range;
|
||||||
U64 dynamic;
|
U64 dynamic;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct DMN_LNX_DynamicInfo DMN_LNX_DynamicInfo;
|
typedef struct DMN_LNX_DynamicInfo DMN_LNX_DynamicInfo;
|
||||||
@@ -171,39 +158,60 @@ typedef enum DMN_LNX_EntityKind
|
|||||||
}
|
}
|
||||||
DMN_LNX_EntityKind;
|
DMN_LNX_EntityKind;
|
||||||
|
|
||||||
|
typedef enum DMN_LNX_ThreadState
|
||||||
|
{
|
||||||
|
DMN_LNX_ThreadState_Null,
|
||||||
|
DMN_LNX_ThreadState_Running,
|
||||||
|
DMN_LNX_ThreadState_Stopped,
|
||||||
|
DMN_LNX_ThreadState_Exited,
|
||||||
|
DMN_LNX_ThreadState_WaitForVFrok,
|
||||||
|
} DMN_LNX_ThreadState;
|
||||||
|
|
||||||
typedef struct DMN_LNX_Entity DMN_LNX_Entity;
|
typedef struct DMN_LNX_Entity DMN_LNX_Entity;
|
||||||
struct DMN_LNX_Entity
|
struct DMN_LNX_Entity
|
||||||
{
|
{
|
||||||
|
// entity hierarchy
|
||||||
DMN_LNX_Entity *first;
|
DMN_LNX_Entity *first;
|
||||||
DMN_LNX_Entity *last;
|
DMN_LNX_Entity *last;
|
||||||
DMN_LNX_Entity *next;
|
DMN_LNX_Entity *next;
|
||||||
DMN_LNX_Entity *prev;
|
DMN_LNX_Entity *prev;
|
||||||
DMN_LNX_Entity *parent;
|
DMN_LNX_Entity *parent;
|
||||||
|
|
||||||
|
// common
|
||||||
DMN_LNX_EntityKind kind;
|
DMN_LNX_EntityKind kind;
|
||||||
U32 gen;
|
U32 gen;
|
||||||
Arch arch;
|
Arch arch;
|
||||||
U64 id;
|
U64 id;
|
||||||
|
|
||||||
// process
|
// process
|
||||||
Arena *arena;
|
Arena *arena;
|
||||||
int fd;
|
int fd;
|
||||||
pid_t tracer_tid;
|
pid_t tracer_tid;
|
||||||
B32 expect_rdebug_data_breakpoint;
|
B32 debug_subprocesses;
|
||||||
U64 rdebug_vaddr;
|
B32 expect_user_interrupt;
|
||||||
U64 rdebug_brk_vaddr;
|
B32 expect_rdebug_data_breakpoint;
|
||||||
ELF_Class dl_class;
|
U64 rdebug_vaddr;
|
||||||
HashTable *loaded_modules_ht;
|
U64 rdebug_brk_vaddr;
|
||||||
|
ELF_Class dl_class;
|
||||||
|
HashTable *loaded_modules_ht;
|
||||||
DMN_LNX_Probe **probes;
|
DMN_LNX_Probe **probes;
|
||||||
U64 probe_vaddrs[DMN_LNX_ProbeType_Count];
|
U64 probe_vaddrs[DMN_LNX_ProbeType_Count];
|
||||||
|
U64 main_thread_exit_code;
|
||||||
|
U64 thread_count;
|
||||||
|
|
||||||
// process x64
|
// process x64
|
||||||
U64 xcr0;
|
U64 xcr0;
|
||||||
U64 xsave_size;
|
U64 xsave_size;
|
||||||
X64_XSaveLayout xsave_layout;
|
X64_XSaveLayout xsave_layout;
|
||||||
|
|
||||||
// thread
|
// thread
|
||||||
B32 expecting_dummy_sigstop;
|
void *reg_block;
|
||||||
void *reg_block;
|
B32 expecting_dummy_sigstop;
|
||||||
|
B32 is_main_thread;
|
||||||
|
B32 is_reg_block_dirty;
|
||||||
|
B32 pass_through_signal;
|
||||||
|
U64 pass_through_signo;
|
||||||
|
DMN_LNX_ThreadState thread_state;
|
||||||
|
|
||||||
// module
|
// module
|
||||||
U64 base_vaddr;
|
U64 base_vaddr;
|
||||||
@@ -217,13 +225,13 @@ typedef struct DMN_LNX_EntityNode DMN_LNX_EntityNode;
|
|||||||
struct DMN_LNX_EntityNode
|
struct DMN_LNX_EntityNode
|
||||||
{
|
{
|
||||||
DMN_LNX_EntityNode *next;
|
DMN_LNX_EntityNode *next;
|
||||||
DMN_LNX_Entity *v;
|
DMN_LNX_Entity *v;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct DMN_LNX_EntityList DMN_LNX_EntityList;
|
typedef struct DMN_LNX_EntityList DMN_LNX_EntityList;
|
||||||
struct DMN_LNX_EntityList
|
struct DMN_LNX_EntityList
|
||||||
{
|
{
|
||||||
U64 count;
|
U64 count;
|
||||||
DMN_LNX_EntityNode *first;
|
DMN_LNX_EntityNode *first;
|
||||||
DMN_LNX_EntityNode *last;
|
DMN_LNX_EntityNode *last;
|
||||||
};
|
};
|
||||||
@@ -231,38 +239,69 @@ struct DMN_LNX_EntityList
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Main State Bundle
|
//~ rjf: Main State Bundle
|
||||||
|
|
||||||
|
typedef struct DMN_LNX_ProcessLaunch DMN_LNX_ProcessLaunch;
|
||||||
|
struct DMN_LNX_ProcessLaunch
|
||||||
|
{
|
||||||
|
B32 debug_subprocesses;
|
||||||
|
pid_t pid;
|
||||||
|
DMN_LNX_ProcessLaunch *next;
|
||||||
|
DMN_LNX_ProcessLaunch *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct DMN_LNX_ProcessLaunchList DMN_LNX_ProcessLaunchList;
|
||||||
|
struct DMN_LNX_ProcessLaunchList
|
||||||
|
{
|
||||||
|
U64 count;
|
||||||
|
DMN_LNX_ProcessLaunch *first;
|
||||||
|
DMN_LNX_ProcessLaunch *last;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct DMN_LNX_Halt
|
||||||
|
{
|
||||||
|
pid_t halter_pid;
|
||||||
|
} DMN_LNX_Halt;
|
||||||
|
|
||||||
typedef struct DMN_LNX_State DMN_LNX_State;
|
typedef struct DMN_LNX_State DMN_LNX_State;
|
||||||
struct DMN_LNX_State
|
struct DMN_LNX_State
|
||||||
{
|
{
|
||||||
Arena *arena;
|
Arena *arena;
|
||||||
|
|
||||||
|
pid_t tracer_tid;
|
||||||
|
|
||||||
// rjf: access locking mechanism
|
// rjf: access locking mechanism
|
||||||
Mutex access_mutex;
|
Mutex access_mutex;
|
||||||
B32 access_run_state;
|
B32 access_run_state;
|
||||||
|
|
||||||
// rjf: deferred events
|
|
||||||
Arena *deferred_events_arena;
|
|
||||||
DMN_EventList deferred_events;
|
|
||||||
|
|
||||||
// rjf: entity storage
|
// rjf: entity storage
|
||||||
Arena *entities_arena;
|
Arena *entities_arena;
|
||||||
DMN_LNX_Entity *entities_base;
|
DMN_LNX_Entity *entities_base;
|
||||||
U64 entities_count;
|
|
||||||
DMN_LNX_Entity *free_entity;
|
DMN_LNX_Entity *free_entity;
|
||||||
|
U64 entities_count;
|
||||||
|
HashTable *tid_ht; // thread id -> thread entity
|
||||||
|
HashTable *pid_ht; // process id -> process entity
|
||||||
|
|
||||||
// rjf: halting mechanism
|
// pid tracking
|
||||||
B32 has_halt_injection;
|
U64 active_process_count;
|
||||||
U64 halt_code;
|
DMN_LNX_ProcessLaunchList pending_stopsig;
|
||||||
U64 halt_user_data;
|
DMN_LNX_ProcessLaunchList pending_creation;
|
||||||
|
DMN_LNX_ProcessLaunchList active_pids;
|
||||||
|
DMN_LNX_ProcessLaunchList free_pids;
|
||||||
|
|
||||||
DMN_EventKind last_event_kind;
|
// halter
|
||||||
pid_t last_stop_pid;
|
pid_t halter_tid;
|
||||||
int last_sig_code;
|
U64 halt_code;
|
||||||
|
U64 halt_user_data;
|
||||||
|
B32 is_halting;
|
||||||
};
|
};
|
||||||
|
|
||||||
read_only global DMN_LNX_Entity dmn_lnx_nil_entity = {&dmn_lnx_nil_entity, &dmn_lnx_nil_entity, &dmn_lnx_nil_entity, &dmn_lnx_nil_entity, &dmn_lnx_nil_entity};
|
////////////////////////////////
|
||||||
global DMN_LNX_State *dmn_lnx_state = 0;
|
//~ Globals
|
||||||
thread_static B32 dmn_lnx_ctrl_thread = 0;
|
|
||||||
|
global DMN_LNX_State *dmn_lnx_state = 0;
|
||||||
|
thread_static B32 dmn_lnx_ctrl_thread = 0;
|
||||||
|
|
||||||
|
read_only global DMN_LNX_Entity dmn_lnx_nil_entity_ = {&dmn_lnx_nil_entity_, &dmn_lnx_nil_entity_, &dmn_lnx_nil_entity_, &dmn_lnx_nil_entity_, &dmn_lnx_nil_entity_};
|
||||||
|
read_only global DMN_LNX_Entity *dmn_lnx_nil_entity = &dmn_lnx_nil_entity_;
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Helpers
|
//~ rjf: Helpers
|
||||||
@@ -298,6 +337,8 @@ internal DMN_LNX_PhdrInfo dmn_lnx_phdr_info_from_memory(int memory_fd, ELF
|
|||||||
internal DMN_LNX_DynamicInfo dmn_lnx_dynamic_info_from_memory(int memory_fd, ELF_Class elf_Class, U64 rebase, U64 dynamic_vaddr);
|
internal DMN_LNX_DynamicInfo dmn_lnx_dynamic_info_from_memory(int memory_fd, ELF_Class elf_Class, U64 rebase, U64 dynamic_vaddr);
|
||||||
internal U64 dmn_lnx_rdebug_vaddr_from_memory(int memory_fd, U64 loader_vaddr);
|
internal U64 dmn_lnx_rdebug_vaddr_from_memory(int memory_fd, U64 loader_vaddr);
|
||||||
|
|
||||||
|
internal String8 dmn_lnx_dl_path_from_pid(Arena *arena, pid_t pid, U64 auxv_base);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Entity Functions
|
//~ rjf: Entity Functions
|
||||||
|
|
||||||
@@ -309,10 +350,10 @@ internal DMN_LNX_Entity *dmn_lnx_thread_from_pid(pid_t pid);
|
|||||||
|
|
||||||
internal U64 dmn_lnx_thread_read_ip(DMN_LNX_Entity *thread);
|
internal U64 dmn_lnx_thread_read_ip(DMN_LNX_Entity *thread);
|
||||||
internal U64 dmn_lnx_thread_read_sp(DMN_LNX_Entity *thread);
|
internal U64 dmn_lnx_thread_read_sp(DMN_LNX_Entity *thread);
|
||||||
internal B32 dmn_lnx_thread_write_ip(DMN_LNX_Entity *thread, U64 ip);
|
internal void dmn_lnx_thread_write_ip(DMN_LNX_Entity *thread, U64 ip);
|
||||||
internal B32 dmn_lnx_thread_write_sp(DMN_LNX_Entity *thread, U64 sp);
|
internal void dmn_lnx_thread_write_sp(DMN_LNX_Entity *thread, U64 sp);
|
||||||
internal B32 dmn_lnx_thread_read_reg_block(DMN_LNX_Entity *thread, void *reg_block);
|
internal B32 dmn_lnx_thread_read_reg_block(DMN_LNX_Entity *thread);
|
||||||
internal B32 dmn_lnx_thread_write_reg_block(DMN_LNX_Entity *thread, void *reg_block);
|
internal B32 dmn_lnx_thread_write_reg_block(DMN_LNX_Entity *thread);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user