From 725d944d5a0c7775bbcd0d62b0969cef42aed883 Mon Sep 17 00:00:00 2001 From: Sidharth Kshatriya Date: Mon, 25 Nov 2024 16:06:13 +0530 Subject: [PATCH] wait4 syscall should return pid (tgid) and not the tid to userspace This is what the kernel does. Fix emulation to do the same. In glibc waitpid() i.e. __waitpid() is implemented in terms of wait4() i.e. __wait4() which is a thin wrapper over the wait4 syscall. wait4 syscall returns the pid (tgid in kernel parlance) and not the thread id (tid). tid and pid will, of course, often be different in multithreaded situations. See also `man wait4` and `man waitpid`. This should fix the unexpected behavior of waitpid() in programs in which the return pid_t is checked against an expected value or used for further bookkeeping/comparisons. In such programs, the failure can be rare because due to thread sequencing, sometimes the tid happens to be numerically the pid that is expected and sometimes it is not. --- src/record_syscall.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/record_syscall.cc b/src/record_syscall.cc index c164b1caa0b..3c3a06e59b4 100644 --- a/src/record_syscall.cc +++ b/src/record_syscall.cc @@ -7104,7 +7104,7 @@ static void rec_process_syscall_arch(RecordTask* t, if (tracee) { // Finish emulation of ptrace result or stop-signal Registers r = t->regs(); - r.set_syscall_result(syscallno == Arch::waitid ? 0 : tracee->tid); + r.set_syscall_result(syscallno == Arch::waitid ? 0 : tracee->tgid()); t->set_regs(r); if (syscallno == Arch::waitid) { remote_ptr sip = r.arg3();