//! Runtime services//!//! The `rt` module provides a narrow set of runtime services,//! including the global heap (exported in `heap`) and unwinding and//! backtrace support. The APIs in this module are highly unstable,//! and should be considered as private implementation details for the//! time being.#![unstable(feature = "rt",reason = "this public module should not exist and is highly likely \to disappear",issue = "none")]#![doc(hidden)]#![deny(unsafe_op_in_unsafe_fn)]#![allow(unused_macros)]use crate::ffi::CString;// Re-export some of our utilities which are expected by other crates.pub use crate::panicking::{begin_panic, panic_count};pub use core::panicking::{panic_display, panic_fmt};use crate::sync::Once;use crate::sys;use crate::sys_common::thread_info;use crate::thread::Thread;// Prints to the "panic output", depending on the platform this may be:// - the standard error output// - some dedicated platform specific output// - nothing (so this macro is a no-op)macro_rules! rtprintpanic {($($t:tt)*) => {if let Some(mut out) = crate::sys::stdio::panic_output() {let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*));}}}macro_rules! rtabort {($($t:tt)*) => {{rtprintpanic!("fatal runtime error: {}\n", format_args!($($t)*));crate::sys::abort_internal();}}}macro_rules! rtassert {($e:expr) => {if !$e {rtabort!(concat!("assertion failed: ", stringify!($e)));}};}macro_rules! rtunwrap {($ok:ident, $e:expr) => {match $e {$ok(v) => v,ref err => {let err = err.as_ref().map(drop); // map Ok/Some which might not be Debugrtabort!(concat!("unwrap failed: ", stringify!($e), " = {:?}"), err)}}};}// One-time runtime initialization.// Runs before `main`.// SAFETY: must be called only once during runtime initialization.// NOTE: this is not guaranteed to run, for example when Rust code is called externally.//// # The `sigpipe` parameter//// Since 2014, the Rust runtime on Unix has set the `SIGPIPE` handler to// `SIG_IGN`. Applications have good reasons to want a different behavior// though, so there is a `#[unix_sigpipe = "..."]` attribute on `fn main()` that// can be used to select how `SIGPIPE` shall be setup (if changed at all) before// `fn main()` is called. See <https://github.com/rust-lang/rust/issues/97889>// for more info.//// The `sigpipe` parameter to this function gets its value via the code that// rustc generates to invoke `fn lang_start()`. The reason we have `sigpipe` for// all platforms and not only Unix, is because std is not allowed to have `cfg`// directives as this high level. See the module docs in// `src/tools/tidy/src/pal.rs` for more info. On all other platforms, `sigpipe`// has a value, but its value is ignored.//// Even though it is an `u8`, it only ever has 4 values. These are documented in// `compiler/rustc_session/src/config/sigpipe.rs`.#[cfg_attr(test, allow(dead_code))]unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {unsafe {sys::init(argc, argv, sigpipe);let main_guard = sys::thread::guard::init();// Next, set up the current Thread with the guard information we just// created. Note that this isn't necessary in general for new threads,// but we just do this to name the main thread and to give it correct// info about the stack bounds.let thread = Thread::new(Some(rtunwrap!(Ok, CString::new("main"))));thread_info::set(main_guard, thread);}}// One-time runtime cleanup.// Runs after `main` or at program exit.// NOTE: this is not guaranteed to run, for example when the program aborts.pub(crate) fn cleanup() {static CLEANUP: Once = Once::new();CLEANUP.call_once(|| unsafe {// Flush stdout and disable buffering.crate::io::cleanup();// SAFETY: Only called once during runtime cleanup.sys::cleanup();});}// To reduce the generated code of the new `lang_start`, this function is doing// the real work.#[cfg(not(test))]fn lang_start_internal(main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindSafe),argc: isize,argv: *const *const u8,sigpipe: u8,) -> Result<isize, !> {use crate::{mem, panic};let rt_abort = move |e| {mem::forget(e);rtabort!("initialization or cleanup bug");};// Guard against the code called by this function from unwinding outside of the Rust-controlled// code, which is UB. This is a requirement imposed by a combination of how the// `#[lang="start"]` attribute is implemented as well as by the implementation of the panicking// mechanism itself.//// There are a couple of instances where unwinding can begin. First is inside of the// `rt::init`, `rt::cleanup` and similar functions controlled by bstd. In those instances a// panic is a std implementation bug. A quite likely one too, as there isn't any way to// prevent std from accidentally introducing a panic to these functions. Another is from// user code from `main` or, more nefariously, as described in e.g. issue #86030.// SAFETY: Only called once during runtime initialization.panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) }).map_err(rt_abort)?;let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize).map_err(move |e| {mem::forget(e);rtabort!("drop of the panic payload panicked");});panic::catch_unwind(cleanup).map_err(rt_abort)?;ret_code}#[cfg(not(test))]#[inline(never)]#[lang = "start"]fn lang_start<T: crate::process::Termination + 'static>(main: fn() -> T,argc: isize,argv: *const *const u8,sigpipe: u8,) -> isize {let Ok(v) = lang_start_internal(&move || crate::sys_common::backtrace::__rust_begin_short_backtrace(main).report().to_i32(),argc,argv,sigpipe,);v}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。