Skip to content

Commit 18efef7

Browse files
authored
signal: add track_caller to public APIs (#4806)
Functions that may panic can be annotated with #[track_caller] so that in the event of a panic, the function where the user called the panicking function is shown instead of the file and line within Tokio source. This change adds #[track_caller] to the signal() function which is the only function in the signal public API which can panic. Documentation was added to this function to indicate that it may panic. Not all panic cases can have #[track_caller] applied fully as the callstack passes through a closure which isn't yet supported by the annotation (e.g. signal() called from outside a tokio runtime). Tests are included to cover the case where signal() is called from a runtime without IO enabled. Refs: #4413
1 parent d8cad13 commit 18efef7

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

tokio/src/signal/unix.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,12 @@ pub struct Signal {
384384
/// * If the previous initialization of this specific signal failed.
385385
/// * If the signal is one of
386386
/// [`signal_hook::FORBIDDEN`](fn@signal_hook_registry::register#panics)
387+
///
388+
/// # Panics
389+
///
390+
/// This function panics if there is no current reactor set, or if the `rt`
391+
/// feature flag is not enabled.
392+
#[track_caller]
387393
pub fn signal(kind: SignalKind) -> io::Result<Signal> {
388394
let rx = signal_with_handle(kind, &Handle::current())?;
389395

tokio/src/signal/unix/driver.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ cfg_rt! {
182182
/// # Panics
183183
///
184184
/// This function panics if there is no current signal driver set.
185+
#[track_caller]
185186
pub(super) fn current() -> Self {
186187
crate::runtime::context::signal_handle().expect(
187188
"there is no signal driver running, must be called from the context of Tokio runtime",
@@ -197,6 +198,7 @@ cfg_not_rt! {
197198
/// # Panics
198199
///
199200
/// This function panics if there is no current signal driver set.
201+
#[track_caller]
200202
pub(super) fn current() -> Self {
201203
panic!(
202204
"there is no signal driver running, must be called from the context of Tokio runtime or with\

tokio/tests/signal_panic.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#![warn(rust_2018_idioms)]
2+
#![cfg(feature = "full")]
3+
#![cfg(unix)]
4+
5+
use std::error::Error;
6+
use tokio::runtime::Builder;
7+
use tokio::signal::unix::{signal, SignalKind};
8+
9+
mod support {
10+
pub mod panic;
11+
}
12+
use support::panic::test_panic;
13+
14+
#[test]
15+
fn signal_panic_caller() -> Result<(), Box<dyn Error>> {
16+
let panic_location_file = test_panic(|| {
17+
let rt = Builder::new_current_thread().build().unwrap();
18+
19+
rt.block_on(async {
20+
let kind = SignalKind::from_raw(-1);
21+
let _ = signal(kind);
22+
});
23+
});
24+
25+
// The panic location should be in this file
26+
assert_eq!(&panic_location_file.unwrap(), file!());
27+
28+
Ok(())
29+
}

0 commit comments

Comments
 (0)