mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-05 13:28:40 +00:00
demon/linux: thread resuming in dmn_ctrl_run
This commit is contained in:
@@ -505,7 +505,7 @@ dmn_init(void)
|
|||||||
dmn_lnx_state->deferred_events_arena = arena_alloc();
|
dmn_lnx_state->deferred_events_arena = arena_alloc();
|
||||||
dmn_lnx_state->entities_arena = arena_alloc(.reserve_size = GB(32), .commit_size = KB(64), .flags = ArenaFlag_NoChain);
|
dmn_lnx_state->entities_arena = arena_alloc(.reserve_size = GB(32), .commit_size = KB(64), .flags = ArenaFlag_NoChain);
|
||||||
dmn_lnx_state->entities_base = push_array(dmn_lnx_state->entities_arena, DMN_LNX_Entity, 0);
|
dmn_lnx_state->entities_base = push_array(dmn_lnx_state->entities_arena, DMN_LNX_Entity, 0);
|
||||||
dmn_lnx_state->root_entity = dmn_lnx_entity_alloc(&dmn_lnx_nil_entity, DMN_LNX_EntityKind_Root);
|
dmn_lnx_entity_alloc(&dmn_lnx_nil_entity, DMN_LNX_EntityKind_Root);
|
||||||
dmn_lnx_state->access_mutex = os_mutex_alloc();
|
dmn_lnx_state->access_mutex = os_mutex_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,7 +673,7 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params)
|
|||||||
DMN_LNX_Entity *main_thread = &dmn_lnx_nil_entity;
|
DMN_LNX_Entity *main_thread = &dmn_lnx_nil_entity;
|
||||||
{
|
{
|
||||||
// rjf: build process
|
// rjf: build process
|
||||||
process = dmn_lnx_entity_alloc(dmn_lnx_state->root_entity, DMN_LNX_EntityKind_Process);
|
process = dmn_lnx_entity_alloc(dmn_lnx_state->entities_base, DMN_LNX_EntityKind_Process);
|
||||||
process->arch = dmn_lnx_arch_from_pid(pid);
|
process->arch = dmn_lnx_arch_from_pid(pid);
|
||||||
process->id = pid;
|
process->id = pid;
|
||||||
process->fd = open((char*)str8f(scratch.arena, "/proc/%d/mem", pid).str, O_RDWR);
|
process->fd = open((char*)str8f(scratch.arena, "/proc/%d/mem", pid).str, O_RDWR);
|
||||||
@@ -787,6 +787,8 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
|||||||
{
|
{
|
||||||
DMN_EventList evts = {0};
|
DMN_EventList evts = {0};
|
||||||
{
|
{
|
||||||
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
//- rjf: push any deferred events
|
//- rjf: push any deferred events
|
||||||
//
|
//
|
||||||
@@ -801,6 +803,124 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
|||||||
MemoryZeroStruct(&dmn_lnx_state->deferred_events);
|
MemoryZeroStruct(&dmn_lnx_state->deferred_events);
|
||||||
arena_clear(dmn_lnx_state->deferred_events_arena);
|
arena_clear(dmn_lnx_state->deferred_events_arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
//- rjf: no processes, no output events -> not attached
|
||||||
|
//
|
||||||
|
if(evts.count == 0 && dmn_lnx_state->entities_base->first == &dmn_lnx_nil_entity)
|
||||||
|
{
|
||||||
|
DMN_Event *e = dmn_event_list_push(arena, &evts);
|
||||||
|
e->kind = DMN_EventKind_Error;
|
||||||
|
e->error_kind = DMN_ErrorKind_NotAttached;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
//- rjf: gather all threads which we should run
|
||||||
|
//
|
||||||
|
DMN_LNX_EntityNode *first_run_thread = 0;
|
||||||
|
DMN_LNX_EntityNode *last_run_thread = 0;
|
||||||
|
ProfScope("gather all threads which we should run")
|
||||||
|
{
|
||||||
|
//- rjf: scan all processes
|
||||||
|
for(DMN_LNX_Entity *process = dmn_lnx_state->entities_base->first;
|
||||||
|
process != &dmn_lnx_nil_entity;
|
||||||
|
process = process->next)
|
||||||
|
{
|
||||||
|
if(process->kind != DMN_LNX_EntityKind_Process) {continue;}
|
||||||
|
|
||||||
|
//- rjf: determine if this process is frozen
|
||||||
|
B32 process_is_frozen = 0;
|
||||||
|
if(ctrls->run_entities_are_processes)
|
||||||
|
{
|
||||||
|
for(U64 idx = 0; idx < ctrls->run_entity_count; idx += 1)
|
||||||
|
{
|
||||||
|
if(dmn_handle_match(ctrls->run_entities[idx], dmn_lnx_handle_from_entity(process)))
|
||||||
|
{
|
||||||
|
process_is_frozen = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- rjf: scan all threads in this process
|
||||||
|
for(DMN_LNX_Entity *thread = process->first;
|
||||||
|
thread != &dmn_lnx_nil_entity;
|
||||||
|
thread = thread->next)
|
||||||
|
{
|
||||||
|
if(thread->kind != DMN_LNX_EntityKind_Thread) {continue;}
|
||||||
|
|
||||||
|
//- rjf: determine if this thread is frozen
|
||||||
|
B32 is_frozen = 0;
|
||||||
|
{
|
||||||
|
// rjf: single-step? freeze if not the single-step thread.
|
||||||
|
if(!dmn_handle_match(dmn_handle_zero(), ctrls->single_step_thread))
|
||||||
|
{
|
||||||
|
is_frozen = !dmn_handle_match(dmn_lnx_handle_from_entity(thread), ctrls->single_step_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rjf: not single-stepping? determine based on run controls freezing info
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(ctrls->run_entities_are_processes)
|
||||||
|
{
|
||||||
|
is_frozen = process_is_frozen;
|
||||||
|
}
|
||||||
|
else for(U64 idx = 0; idx < ctrls->run_entity_count; idx += 1)
|
||||||
|
{
|
||||||
|
if(dmn_handle_match(ctrls->run_entities[idx], dmn_lnx_handle_from_entity(thread)))
|
||||||
|
{
|
||||||
|
is_frozen = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ctrls->run_entities_are_unfrozen)
|
||||||
|
{
|
||||||
|
is_frozen ^= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- rjf: disregard all other rules if this is the halter thread
|
||||||
|
// TODO(rjf): halting - here is what we do on windows...
|
||||||
|
#if 0
|
||||||
|
if(dmn_w32_shared->halter_tid == thread->id)
|
||||||
|
{
|
||||||
|
is_frozen = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//- rjf: add to list
|
||||||
|
if(!is_frozen)
|
||||||
|
{
|
||||||
|
DMN_LNX_EntityNode *n = push_array(scratch.arena, DMN_LNX_EntityNode, 1);
|
||||||
|
n->v = thread;
|
||||||
|
SLLQueuePush(first_run_thread, last_run_thread, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
//- rjf: resume all threads we need to run
|
||||||
|
//
|
||||||
|
DMN_LNX_EntityNode *first_ran_thread = 0;
|
||||||
|
DMN_LNX_EntityNode *last_ran_thread = 0;
|
||||||
|
for(DMN_LNX_EntityNode *n = first_run_thread; n != 0; n = n->next)
|
||||||
|
{
|
||||||
|
ptrace(PTRACE_CONT, (pid_t)n->v->id, 0, 0);
|
||||||
|
DMN_LNX_EntityNode *n2 = push_array_no_zero(scratch.arena, DMN_LNX_EntityNode, 1);
|
||||||
|
SLLQueuePush(first_ran_thread, last_ran_thread, n2);
|
||||||
|
n2->v = n->v;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
//- rjf: wait for next stop
|
||||||
|
//
|
||||||
|
int status = 0;
|
||||||
|
pid_t wait_id = waitpid(-1, &status, __WALL);
|
||||||
|
|
||||||
|
|
||||||
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
return evts;
|
return evts;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,13 @@ struct DMN_LNX_Entity
|
|||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct DMN_LNX_EntityNode DMN_LNX_EntityNode;
|
||||||
|
struct DMN_LNX_EntityNode
|
||||||
|
{
|
||||||
|
DMN_LNX_EntityNode *next;
|
||||||
|
DMN_LNX_Entity *v;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct DMN_LNX_State DMN_LNX_State;
|
typedef struct DMN_LNX_State DMN_LNX_State;
|
||||||
struct DMN_LNX_State
|
struct DMN_LNX_State
|
||||||
{
|
{
|
||||||
@@ -100,7 +107,6 @@ struct DMN_LNX_State
|
|||||||
Arena *entities_arena;
|
Arena *entities_arena;
|
||||||
DMN_LNX_Entity *entities_base;
|
DMN_LNX_Entity *entities_base;
|
||||||
U64 entities_count;
|
U64 entities_count;
|
||||||
DMN_LNX_Entity *root_entity;
|
|
||||||
DMN_LNX_Entity *free_entity;
|
DMN_LNX_Entity *free_entity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user