Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6d717c9

Browse files
committed
Add ExitStatusExt::task_retcode for Fuchsia platform
The method task_retcode() method improves the ergonomics of determining if a Fuchsia process was killed by the kernel and for what reason.
1 parent 7e763af commit 6d717c9

File tree

9 files changed

+96
-24
lines changed

9 files changed

+96
-24
lines changed

‎library/std/src/os/fuchsia/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33
#![stable(feature = "raw_ext", since = "1.1.0")]
44

55
pub mod fs;
6+
#[unstable(feature = "fuchsia_exit_status", issue = "none")]
7+
pub mod process;
68
pub mod raw;

‎library/std/src/os/fuchsia/process.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//! Fuchsia-specific extensions to primitives in the [`std::process`] module.
2+
//!
3+
//! [`std::process`]: crate::process
4+
5+
use crate::process;
6+
use crate::sealed::Sealed;
7+
8+
#[unstable(feature = "fuchsia_exit_status", issue = "none")]
9+
pub type zx_status_t = i32;
10+
#[unstable(feature = "fuchsia_exit_status", issue = "none")]
11+
pub const ZX_TASK_RETCODE_SYSCALL_KILL: zx_status_t = -1024;
12+
#[unstable(feature = "fuchsia_exit_status", issue = "none")]
13+
pub const ZX_TASK_RETCODE_OOM_KILL: zx_status_t = -1025;
14+
#[unstable(feature = "fuchsia_exit_status", issue = "none")]
15+
pub const ZX_TASK_RETCODE_POLICY_KILL: zx_status_t = -1026;
16+
#[unstable(feature = "fuchsia_exit_status", issue = "none")]
17+
pub const ZX_TASK_RETCODE_VDSO_KILL: zx_status_t = -1027;
18+
/// On Zircon (the Fuchsia kernel), an abort from userspace calls the
19+
/// LLVM implementation of __builtin_trap(), e.g., ud2 on x86, which
20+
/// raises a kernel exception. If a userspace process does not
21+
/// otherwise arrange exception handling, the kernel kills the process
22+
/// with this return code.
23+
#[unstable(feature = "fuchsia_exit_status", issue = "none")]
24+
pub const ZX_TASK_RETCODE_EXCEPTION_KILL: zx_status_t = -1028;
25+
#[unstable(feature = "fuchsia_exit_status", issue = "none")]
26+
pub const ZX_TASK_RETCODE_CRITICAL_PROCESS_KILL: zx_status_t = -1029;
27+
28+
#[unstable(feature = "fuchsia_exit_status", issue = "none")]
29+
pub trait ExitStatusExt: Sealed {
30+
/// If the task was killed, returns the `ZX_TASK_RETCODE_*`.
31+
#[must_use]
32+
fn task_retcode(&self) -> Option<i32>;
33+
}
34+
35+
#[unstable(feature = "fuchsia_exit_status", issue = "none")]
36+
impl ExitStatusExt for process::ExitStatus {
37+
fn task_retcode(&self) -> Option<i32> {
38+
self.code().and_then(|code| {
39+
if code == ZX_TASK_RETCODE_SYSCALL_KILL
40+
|| code == ZX_TASK_RETCODE_OOM_KILL
41+
|| code == ZX_TASK_RETCODE_POLICY_KILL
42+
|| code == ZX_TASK_RETCODE_VDSO_KILL
43+
|| code == ZX_TASK_RETCODE_EXCEPTION_KILL
44+
|| code == ZX_TASK_RETCODE_CRITICAL_PROCESS_KILL
45+
{
46+
Some(code)
47+
} else {
48+
None
49+
}
50+
})
51+
}
52+
}

‎library/test/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#![feature(process_exitcode_internals)]
2424
#![feature(panic_can_unwind)]
2525
#![feature(test)]
26+
#![cfg_attr(target_os = "fuchsia", feature(fuchsia_exit_status))]
2627
#![allow(internal_features)]
2728

2829
// Public reexports

‎library/test/src/test_result.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use std::any::Any;
22
use std::process::ExitStatus;
33

4+
#[cfg(target_os = "fuchsia")]
5+
use std::os::fuchsia::process::{ExitStatusExt as _, ZX_TASK_RETCODE_EXCEPTION_KILL};
46
#[cfg(unix)]
5-
use std::os::unix::process::ExitStatusExt;
7+
use std::os::unix::process::ExitStatusExtas _;
68

79
use super::bench::BenchSamples;
810
use super::options::ShouldPanic;
@@ -21,14 +23,6 @@ pub const TR_OK: i32 = 50;
2123
#[cfg(windows)]
2224
const STATUS_FAIL_FAST_EXCEPTION: i32 = 0xC0000409u32 as i32;
2325

24-
// On Zircon (the Fuchsia kernel), an abort from userspace calls the
25-
// LLVM implementation of __builtin_trap(), e.g., ud2 on x86, which
26-
// raises a kernel exception. If a userspace process does not
27-
// otherwise arrange exception handling, the kernel kills the process
28-
// with this return code.
29-
#[cfg(target_os = "fuchsia")]
30-
const ZX_TASK_RETCODE_EXCEPTION_KILL: i32 = -1028;
31-
3226
#[derive(Debug, Clone, PartialEq)]
3327
pub enum TestResult {
3428
TrOk,
@@ -101,10 +95,28 @@ pub fn get_result_from_exit_code(
10195
time_opts: &Option<time::TestTimeOptions>,
10296
exec_time: &Option<time::TestExecTime>,
10397
) -> TestResult {
104-
let result = match status.code() {
98+
// Upon a panic, a Fuchsia process will trigger a kernel exception
99+
// that, if uncaught, will cause the kernel to kill the process with
100+
// ZX_TASK_RETCODE_EXCEPTION_KILL. Though unlikely, the same code could be
101+
// returned for other unhandled exceptions too. Even in those cases the test
102+
// should still fail and the printed stacktrace from the kernel should
103+
// sufficienly compensate for omitting this return code from test output.
104+
#[cfg(target_os = "fuchsia")]
105+
let result = match status.task_retcode() {
106+
Some(ZX_TASK_RETCODE_EXCEPTION_KILL) => Some(TestResult::TrFailed),
107+
_ => None,
108+
};
109+
#[cfg(not(target_os = "fuchsia"))]
110+
let result: Option<TestResult> = None;
111+
112+
let result = result.unwrap_or_else(|| match status.code() {
105113
Some(TR_OK) => TestResult::TrOk,
106114
#[cfg(windows)]
107115
Some(STATUS_FAIL_FAST_EXCEPTION) => TestResult::TrFailed,
116+
#[cfg(any(windows, unix))]
117+
Some(code) => TestResult::TrFailedMsg(format!("got unexpected return code {code}")),
118+
#[cfg(not(any(windows, unix)))]
119+
Some(_) => TestResult::TrFailed,
108120
#[cfg(unix)]
109121
None => match status.signal() {
110122
Some(libc::SIGABRT) => TestResult::TrFailed,
@@ -113,16 +125,9 @@ pub fn get_result_from_exit_code(
113125
}
114126
None => unreachable!("status.code() returned None but status.signal() was None"),
115127
},
116-
// Upon an abort, Fuchsia returns the status code ZX_TASK_RETCODE_EXCEPTION_KILL.
117-
#[cfg(target_os = "fuchsia")]
118-
Some(ZX_TASK_RETCODE_EXCEPTION_KILL) => TestResult::TrFailed,
119128
#[cfg(not(unix))]
120129
None => TestResult::TrFailedMsg(format!("unknown return code")),
121-
#[cfg(any(windows, unix))]
122-
Some(code) => TestResult::TrFailedMsg(format!("got unexpected return code {code}")),
123-
#[cfg(not(any(windows, unix)))]
124-
Some(_) => TestResult::TrFailed,
125-
};
130+
});
126131

127132
// If test is already failed (or allowed to fail), do not change the result.
128133
if result != TestResult::TrOk {

‎tests/ui/process/signal-exit-status.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,34 @@
22
//@ ignore-wasm32 no processes
33
//@ ignore-sgx no processes
44
//@ ignore-windows
5-
//@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#58590)
65

76
#![feature(core_intrinsics)]
7+
#![cfg_attr(target_os = "fuchsia", feature(fuchsia_exit_status))]
88

99
use std::env;
1010
use std::process::Command;
1111

12+
#[cfg(target_os = "fuchsia")]
13+
use std::os::fuchsia::process::{ExitStatusExt, ZX_TASK_RETCODE_EXCEPTION_KILL};
14+
1215
pub fn main() {
1316
let args: Vec<String> = env::args().collect();
1417
if args.len() >= 2 && args[1] == "signal" {
1518
// Raise an aborting signal without UB
1619
core::intrinsics::abort();
1720
} else {
21+
// Spawn a child process that will raise an aborting signal
1822
let status = Command::new(&args[0]).arg("signal").status().unwrap();
23+
24+
#[cfg(not(target_os = "fuchsia"))]
1925
assert!(status.code().is_none());
26+
27+
// Upon abort(), a Fuchsia process will trigger a kernel exception
28+
// that, if uncaught, will cause the kernel to kill the process with
29+
// ZX_TASK_RETCODE_EXCEPTION_KILL. The same code could be
30+
// returned for a different unhandled exception, but the simplicity of
31+
// the program under test makes such an exception unlikely.
32+
#[cfg(target_os = "fuchsia")]
33+
assert_eq!(Some(ZX_TASK_RETCODE_EXCEPTION_KILL), status.task_retcode());
2034
}
2135
}

‎tests/ui/test-attrs/test-panic-abort-nocapture.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//@ ignore-wasm no panic or subprocess support
1111
//@ ignore-emscripten no panic or subprocess support
1212
//@ ignore-sgx no subprocess support
13-
//@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#127539)
1413

1514
#![cfg(test)]
1615

‎tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:35:5:
1+
thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:34:5:
22
assertion `left == right` failed
33
left: 2
44
right: 4
55
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
6-
thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:29:5:
6+
thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:28:5:
77
assertion `left == right` failed
88
left: 2
99
right: 4

‎tests/ui/test-attrs/test-panic-abort.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//@ ignore-wasm no panic or subprocess support
1111
//@ ignore-emscripten no panic or subprocess support
1212
//@ ignore-sgx no subprocess support
13-
//@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#127539)
1413

1514
#![cfg(test)]
1615
#![feature(test)]

‎tests/ui/test-attrs/test-panic-abort.run.stdout

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ hello, world
1717
testing123
1818
---- it_fails stderr ----
1919
testing321
20-
thread 'main' panicked at $DIR/test-panic-abort.rs:40:5:
20+
thread 'main' panicked at $DIR/test-panic-abort.rs:39:5:
2121
assertion `left == right` failed
2222
left: 2
2323
right: 5

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /