]> git.proxmox.com Git - rustc.git/blame - src/libstd/rt/mod.rs
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / libstd / rt / mod.rs
CommitLineData
970d7e83
LB
1// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
1a4d82fc
JJ
11//! Runtime services
12//!
13//! The `rt` module provides a narrow set of runtime services,
14//! including the global heap (exported in `heap`) and unwinding and
15//! backtrace support. The APIs in this module are highly unstable,
16//! and should be considered as private implementation details for the
17//! time being.
18
62682a34
SL
19#![unstable(feature = "rt",
20 reason = "this public module should not exist and is highly likely \
21 to disappear")]
1a4d82fc
JJ
22#![allow(missing_docs)]
23
c34b1796 24use prelude::v1::*;
1a4d82fc 25use sys;
c34b1796 26use usize;
1a4d82fc
JJ
27
28// Reexport some of our utilities which are expected by other crates.
c1a9b12d 29pub use self::util::min_stack;
1a4d82fc
JJ
30pub use self::unwind::{begin_unwind, begin_unwind_fmt};
31
32// Reexport some functionality from liballoc.
33pub use alloc::heap;
34
35// Simple backtrace functionality (to print on panic)
36pub mod backtrace;
37
38// Internals
39#[macro_use]
40mod macros;
41
42// These should be refactored/moved/made private over time
43pub mod util;
44pub mod unwind;
45pub mod args;
46
47mod at_exit_imp;
48mod libunwind;
49
c1a9b12d
SL
50mod dwarf;
51
1a4d82fc
JJ
52/// The default error code of the rust runtime if the main thread panics instead
53/// of exiting cleanly.
c34b1796 54pub const DEFAULT_ERROR_CODE: isize = 101;
1a4d82fc
JJ
55
56#[cfg(any(windows, android))]
c34b1796 57const OS_DEFAULT_STACK_ESTIMATE: usize = 1 << 20;
1a4d82fc 58#[cfg(all(unix, not(android)))]
c34b1796 59const OS_DEFAULT_STACK_ESTIMATE: usize = 2 * (1 << 20);
1a4d82fc
JJ
60
61#[cfg(not(test))]
62#[lang = "start"]
c34b1796 63fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
1a4d82fc
JJ
64 use prelude::v1::*;
65
66 use mem;
85aaf69f 67 use env;
1a4d82fc
JJ
68 use rt;
69 use sys_common::thread_info::{self, NewThread};
70 use sys_common;
71 use thread::Thread;
72
73 let something_around_the_top_of_the_stack = 1;
c34b1796
AL
74 let addr = &something_around_the_top_of_the_stack as *const _ as *const isize;
75 let my_stack_top = addr as usize;
1a4d82fc
JJ
76
77 // FIXME #11359 we just assume that this thread has a stack of a
78 // certain size, and estimate that there's at most 20KB of stack
79 // frames above our current position.
c34b1796
AL
80 const TWENTY_KB: usize = 20000;
81
82 // saturating-add to sidestep overflow
83 let top_plus_spill = if usize::MAX - TWENTY_KB < my_stack_top {
84 usize::MAX
85 } else {
86 my_stack_top + TWENTY_KB
87 };
88 // saturating-sub to sidestep underflow
89 let my_stack_bottom = if top_plus_spill < OS_DEFAULT_STACK_ESTIMATE {
90 0
91 } else {
92 top_plus_spill - OS_DEFAULT_STACK_ESTIMATE
93 };
1a4d82fc
JJ
94
95 let failed = unsafe {
96 // First, make sure we don't trigger any __morestack overflow checks,
97 // and next set up our stack to have a guard page and run through our
98 // own fault handlers if we hit it.
99 sys_common::stack::record_os_managed_stack_bounds(my_stack_bottom,
100 my_stack_top);
c1a9b12d 101 let main_guard = sys::thread::guard::init();
1a4d82fc
JJ
102 sys::stack_overflow::init();
103
104 // Next, set up the current Thread with the guard information we just
105 // created. Note that this isn't necessary in general for new threads,
106 // but we just do this to name the main thread and to give it correct
107 // info about the stack bounds.
108 let thread: Thread = NewThread::new(Some("<main>".to_string()));
c1a9b12d 109 thread_info::set(main_guard, thread);
1a4d82fc
JJ
110
111 // By default, some platforms will send a *signal* when a EPIPE error
112 // would otherwise be delivered. This runtime doesn't install a SIGPIPE
113 // handler, causing it to kill the program, which isn't exactly what we
114 // want!
115 //
116 // Hence, we set SIGPIPE to ignore when the program starts up in order
117 // to prevent this problem.
118 #[cfg(windows)] fn ignore_sigpipe() {}
119 #[cfg(unix)] fn ignore_sigpipe() {
120 use libc;
121 use libc::funcs::posix01::signal::signal;
122 unsafe {
c34b1796 123 assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != !0);
970d7e83 124 }
970d7e83 125 }
1a4d82fc
JJ
126 ignore_sigpipe();
127
128 // Store our args if necessary in a squirreled away location
129 args::init(argc, argv);
130
131 // And finally, let's run some code!
132 let res = unwind::try(|| {
133 let main: fn() = mem::transmute(main);
134 main();
135 });
136 cleanup();
137 res.is_err()
138 };
139
140 // If the exit code wasn't set, then the try block must have panicked.
141 if failed {
142 rt::DEFAULT_ERROR_CODE
143 } else {
62682a34
SL
144 #[allow(deprecated)]
145 fn exit_status() -> isize { env::get_exit_status() as isize }
146 exit_status()
970d7e83 147 }
1a4d82fc 148}
970d7e83 149
c34b1796 150/// Enqueues a procedure to run when the main thread exits.
1a4d82fc 151///
c34b1796
AL
152/// Currently these closures are only run once the main *Rust* thread exits.
153/// Once the `at_exit` handlers begin running, more may be enqueued, but not
154/// infinitely so. Eventually a handler registration will be forced to fail.
1a4d82fc 155///
c34b1796
AL
156/// Returns `Ok` if the handler was successfully registered, meaning that the
157/// closure will be run once the main thread exits. Returns `Err` to indicate
158/// that the closure could not be registered, meaning that it is not scheduled
159/// to be rune.
160pub fn at_exit<F: FnOnce() + Send + 'static>(f: F) -> Result<(), ()> {
161 if at_exit_imp::push(Box::new(f)) {Ok(())} else {Err(())}
970d7e83
LB
162}
163
1a4d82fc
JJ
164/// One-time runtime cleanup.
165///
166/// This function is unsafe because it performs no checks to ensure that the
167/// runtime has completely ceased running. It is the responsibility of the
168/// caller to ensure that the runtime is entirely shut down and nothing will be
169/// poking around at the internal components.
170///
171/// Invoking cleanup while portions of the runtime are still in use may cause
172/// undefined behavior.
173pub unsafe fn cleanup() {
174 args::cleanup();
175 sys::stack_overflow::cleanup();
c34b1796 176 at_exit_imp::cleanup();
970d7e83 177}