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 <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1444317
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Zach Reizner <zachr@chromium.org>
This commit is contained in:
Daniel Verkamp 2019-01-29 13:57:23 -08:00 committed by chrome-bot
parent d48445eae0
commit 186eb8b0db

View file

@ -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<libc::c_int> {
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);
}
}