pete
pete copied to clipboard
tracee hang infinitly if it exec on not main thread
tracee code
fn main() -> anyhow::Result<()> {
std::thread::spawn(|| unsafe {
libc::execl("/home/test/xxxx\0".as_ptr() as *const _, std::ptr::null());
})
.join()
.unwrap();
Ok(())
}
the tracer will got the main thread exit event and then remove it from tracees map. and the tracer will never wait its event via waipid
but as the ptrace man:
PTRACE_O_TRACEEXEC (since Linux 2.5.46)
Stop the tracee at the next [execve(2)](https://man7.org/linux/man-pages/man2/execve.2.html). A
[waitpid(2)](https://man7.org/linux/man-pages/man2/waitpid.2.html) by the tracer will return a status value
such that
status>>8 == (SIGTRAP | (PTRACE_EVENT_EXEC<<8))
If the execing thread is not a thread group leader,
the thread ID is reset to thread group leader's ID
before this stop. Since Linux 3.0, the former
thread ID can be retrieved with PTRACE_GETEVENTMSG.
pay attention to this section
If the execing thread is not a thread group leader, the thread ID is reset to thread group leader's ID before this stop.
as the man says, the exec event will still triggered on exited main thread rather than the execing thread, so ptracer.wait() will never recv the exec event due to the tracees map not contains the main thread
this seems a thorny problem, because it means you can not remove the exited tracee from tracees map. or you need recongnized the tgid while remove tracee when handle exit event
Thanks for reporting and including a tracee to test with. Investigating.