Skip to content

run-pass tests (and possibly others) continue passing when terminated by signal on OSX #10062

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
miselin opened this issue Oct 25, 2013 · 4 comments · Fixed by #10109
Closed
Labels
A-testsuite Area: The testsuite used to check the correctness of rustc

Comments

@miselin
Copy link
Contributor

miselin commented Oct 25, 2013

On OSX (10.9), but the following is possible in a run-pass test, and will result in a "pass":

pub fn main() {
    unsafe { *(0 as *mut int) = 0; }
}

This should generally be fine as there is probably not much of an expectation that tests will segfault, but it's not ideal to be missing segfaults and other such exceptions (SIGFPE perhaps?) in the testsuite.

On an x86_64 Linux system (Ubuntu 12.04 LTS, git master), a segfault does fail the test.

@miselin
Copy link
Contributor Author

miselin commented Oct 25, 2013

Investigated a bit and found libuv calls the process exit callback with an exit status and termination signal if they are present, as expected from std::rt::uv::uvio (see https://github.com/joyent/libuv/blob/d170c915c98fec671f99db6f8d6c15aeacc5d754/src/unix/process.c#L105).

However, on OSX at least WIFEXITED returns false for a process terminated by signal. WIFSIGNALED returns true, so Rust's exit callback gets called with a zero exit_status but a non-zero term_signal.

I added an assertion to the exit callback to confirm, which asserted that term_signal was zero if the exit_status was zero, and hit an assertion failure in my test (as expected):

failed in non-task context at 'assertion failed: term_signal == 0', /path/to/rust/src/libstd/rt/uv/uvio.rs:781

A possible solution could be to modify uvio::RtioProcess::wait to check for a non-zero term_signal and return it if the exit status is zero, or to do a bitwise operation to make it easier to identify that it is a signal number rather than an exit status.

This same behaviour is exhibited on Linux systems, but the test ends up considered failed, as it should, somehow on Linux with an explicit failure at runtest.rs:805 (explicit fail!() caused by the code path stemming from runtest.rs:155 - ProcRes.status != 0). Not sure how that happens or at least why it's different on OSX.

@miselin
Copy link
Contributor Author

miselin commented Oct 25, 2013

Linux segfaults also fail a run-fail because of error: failure produced the wrong error code: 1 (as expected, as they are not returning the failure exit status), so somehow the Linux code path is getting a magical non-zero exit status on signal...

@alexcrichton
Copy link
Member

When I originally wrote the process bindings to libuv, I was dubious that I was doing the correct thing in propagating the child's error status, so it could very well be doing the wrong thing.

What we should be doing, however, is somehow exposing this information via the wait() call or possibly raising on the io_error condition.

@miselin
Copy link
Contributor Author

miselin commented Oct 25, 2013

It could be worth exposing term_signal as well as exit_status from the wait() call. There's also the error field in the exit callback, which is for errno returned by execve(2) if that fails.

I've had a hunt around on Linux and a segfaulted test takes a completely different code path to get that non-zero exit status - one that I haven't yet found... It doesn't pass up exit status via libuv's exit callback, or any of the task.death.on_exits that are set in uvio.

Might switch into hunting the other direction - starting at runtest and going deeper through the call stack rather than trying to find its deepest point first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-testsuite Area: The testsuite used to check the correctness of rustc
Projects
None yet
2 participants