From 186eb8b0db644892e8ffba8344efe3492bb2b823 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Tue, 29 Jan 2019 13:57:23 -0800 Subject: [PATCH] sys_util: wait on specific pid in panic_safe test The fork::tests::panic_safe unit test has been hanging intermittently in CQ runs. The root cause isn't understood yet, but the most likely explanation seems to be that the wait_process helper is hanging. There should be only two causes for that hang: either the cloned process is not exiting, or the wait() call in wait_process is not returning. The wait() should only hang if another thread has already reaped the cloned process. In order to help debug the issue, change the general wait() to a waitpid() on the specific cloned process ID. This will give us more information about what happens when the test fails - if the waitpid() returns ECHILD instead of hanging, this will indicate that something else is waiting on our child process and racing with our wait(). BUG=chromium:925725 TEST=cargo test --release -p sys_util panic_safe Change-Id: Ib25d88b35b16c75d4d8fe62fc779c9470303368a Signed-off-by: Daniel Verkamp Reviewed-on: https://chromium-review.googlesource.com/1444317 Tested-by: kokoro Reviewed-by: Zach Reizner --- sys_util/src/fork.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/sys_util/src/fork.rs b/sys_util/src/fork.rs index 2941c449dd..72ac4385b1 100644 --- a/sys_util/src/fork.rs +++ b/sys_util/src/fork.rs @@ -100,11 +100,14 @@ mod tests { use libc; use {getpid, EventFd}; - fn wait_process() -> libc::c_int { + fn wait_process(pid: libc::pid_t) -> ::Result { let mut status: libc::c_int = 0; unsafe { - libc::wait(&mut status as *mut libc::c_int); - libc::WEXITSTATUS(status) + if libc::waitpid(pid, &mut status as *mut libc::c_int, 0) < 0 { + errno_result() + } else { + Ok(libc::WEXITSTATUS(status)) + } } } @@ -130,7 +133,7 @@ mod tests { let pid = getpid(); assert_ne!(pid, 0); - clone_process(CloneNamespace::Inherit, || { + let clone_pid = clone_process(CloneNamespace::Inherit, || { assert!(false); }) .expect("failed to clone"); @@ -140,7 +143,7 @@ mod tests { process::exit(2); } - let status = wait_process(); + let status = wait_process(clone_pid).expect("wait_process failed"); assert!(status == 101 || status == 0); } }