This section documents features that define some aspects of the Rust runtime.
The panic_handler
attribute can only be applied to a function with signature
fn(&PanicInfo) -> !
. The function marked with this attribute defines the behavior of panics. The
PanicInfo
struct contains information about the location of the panic. There must be a single
panic_handler
function in the dependency graph of a binary, dylib or cdylib crate.
Below is shown a panic_handler
function that logs the panic message and then halts the
thread.
#![no_std]
use core::fmt::{self, Write};
use core::panic::PanicInfo;
struct Sink {
// ..
# _0: (),
}
#
# impl Sink {
# fn new() -> Sink { Sink { _0: () }}
# }
#
# impl fmt::Write for Sink {
# fn write_str(&mut self, _: &str) -> fmt::Result { Ok(()) }
# }
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
let mut sink = Sink::new();
// logs "panicked at '$reason', src/main.rs:27:4" to some `sink`
let _ = writeln!(sink, "{}", info);
loop {}
}
The standard library provides an implementation of panic_handler
that
defaults to unwinding the stack but that can be changed to abort the
process. The standard library's panic behavior can be modified at
runtime with the set_hook function.
The global_allocator
attribute is used on a static item implementing the
GlobalAlloc
trait to set the global allocator.
The #[unix_sigpipe = "sig_dfl"]
attribute is used on main functions and
controls how the SIGPIPE
signal is configured on unix platforms before the
main function is invoked.
By default, the SIGPIPE
signal is configured to be ignored (SIG_IGN
) to
allow errors to be generated. By applying #[unix_sigpipe = "sig_dfl"]
on the
main function, the SIGPIPE
signal is instead configured to be handled in the
default way (SIG_DFL
), which means killing the process that receives
SIGPIPE
. Note that if the process is killed by SIGPIPE
, destructors will
not run.
The program
fn main() {
for _ in 1..10_000 {
println!("hello world");
}
}
will panic if its output is piped to head
, since println!
does not handle
the error that is generated when its stdout is closed by head
exiting:
$ ./main | head
hello world
thread 'main' panicked at library/std/src/io/stdio.rs:1030:9:
failed printing to stdout: Broken pipe (os error 32)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
If we apply #[unix_sigpipe = "sig_dfl"]
, SIGPIPE
will be configured to use
the SIG_DFL
handler and the program will be killed when receiving the
generated SIGPIPE
signal:
#[unix_sigpipe = "sig_dfl"]
fn main() {
for _ in 1..10_000 {
println!("hello world");
}
}
$ ./main | head
hello world
The windows_subsystem
attribute may be applied at the crate level to set
the subsystem when linking on a Windows target. It uses the
MetaNameValueStr syntax to specify the subsystem with a value of either
console
or windows
. This attribute is ignored on non-Windows targets, and
for non-bin
crate types.
The "console" subsystem is the default. If a console process is run from an existing console then it will be attached to that console, otherwise a new console window will be created.
The "windows" subsystem is commonly used by GUI applications that do not want to display a console window on startup. It will run detached from any existing console.
#![windows_subsystem = "windows"]