in reverie-ptrace/src/task.rs [423:472]
fn forked(&self, child: Pid) -> Self {
let process_state = Arc::new(L::new(child, &self.global_state.cfg));
let thread_state =
process_state.init_thread_state(child, Some((self.tid, &self.thread_state)));
let (next_state, next_state_rx) = mpsc::channel(1);
let (daemonizer, daemonizer_rx) = mpsc::channel(1);
let (gdb_resume_tx, gdb_resume_rx) = mpsc::channel(1);
let (gdb_request_tx, gdb_request_rx) = mpsc::channel(1);
let (exit_suspend_tx, exit_suspend_rx) = mpsc::channel(16);
self.ntasks.fetch_add(1, Ordering::SeqCst);
Self {
tid: child,
pid: child,
ppid: Some(self.pid),
thread_state,
process_state,
global_state: self.global_state.clone(),
pending_syscall: None,
next_state,
next_state_rx: Some(next_state_rx),
timer: Timer::new(child, child),
notifier: Arc::new(Notify::new()),
pending_signal: None,
child_procs: Arc::new(Mutex::new(Children::new())),
child_threads: Arc::new(Mutex::new(Children::new())),
orphanage: self.orphanage.clone(),
daemon_kill_switch: self.daemon_kill_switch.clone(),
daemonizer,
daemonizer_rx: Some(daemonizer_rx),
ntasks: self.ntasks.clone(),
ndaemons: self.ndaemons.clone(),
// NB: if daemon forks, then its child's parent pid is no longer 1.
is_a_daemon: false,
gdbserver_start_tx: None,
gdb_stop_tx: None,
attached_by_gdb: self.attached_by_gdb,
resumed_by_gdb: None,
gdb_resume_tx: Some(gdb_resume_tx),
gdb_resume_rx: Some(gdb_resume_rx),
breakpoints: self.breakpoints.clone(),
suspended: Arc::new(AtomicBool::new(false)),
gdb_request_tx: Some(gdb_request_tx),
gdb_request_rx: Some(gdb_request_rx),
exit_suspend_tx: Some(exit_suspend_tx),
exit_suspend_rx: Some(exit_suspend_rx),
needs_step_over: Arc::new(Mutex::new(())),
suspended_tasks: BTreeMap::new(),
stack_checked_out: Arc::new(AtomicBool::new(false)),
}
}