pete icon indicating copy to clipboard operation
pete copied to clipboard

tracee hang infinitly if it exec on not main thread

Open zhong-b opened this issue 1 year ago • 1 comments

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

zhong-b avatar Feb 05 '24 08:02 zhong-b

Thanks for reporting and including a tracee to test with. Investigating.

ranweiler avatar Feb 09 '24 16:02 ranweiler