13
13
issue = "none"
14
14
) ]
15
15
#![ doc( hidden) ]
16
+ #![ deny( unsafe_op_in_unsafe_fn) ]
17
+ #![ allow( unused_macros) ]
18
+
19
+ use crate :: ffi:: CString ;
16
20
17
21
// Re-export some of our utilities which are expected by other crates.
18
22
pub use crate :: panicking:: { begin_panic, begin_panic_fmt, panic_count} ;
19
23
pub use core:: panicking:: panic_display;
20
24
25
+ use crate :: sync:: Once ;
26
+ use crate :: sys;
27
+ use crate :: sys_common:: thread_info;
28
+ use crate :: thread:: Thread ;
29
+
30
+ // Prints to the "panic output", depending on the platform this may be:
31
+ // - the standard error output
32
+ // - some dedicated platform specific output
33
+ // - nothing (so this macro is a no-op)
34
+ macro_rules! rtprintpanic {
35
+ ( $( $t: tt) * ) => {
36
+ if let Some ( mut out) = crate :: sys:: stdio:: panic_output( ) {
37
+ let _ = crate :: io:: Write :: write_fmt( & mut out, format_args!( $( $t) * ) ) ;
38
+ }
39
+ }
40
+ }
41
+
42
+ macro_rules! rtabort {
43
+ ( $( $t: tt) * ) => {
44
+ {
45
+ rtprintpanic!( "fatal runtime error: {}\n " , format_args!( $( $t) * ) ) ;
46
+ crate :: sys:: abort_internal( ) ;
47
+ }
48
+ }
49
+ }
50
+
51
+ macro_rules! rtassert {
52
+ ( $e: expr) => {
53
+ if !$e {
54
+ rtabort!( concat!( "assertion failed: " , stringify!( $e) ) ) ;
55
+ }
56
+ } ;
57
+ }
58
+
59
+ macro_rules! rtunwrap {
60
+ ( $ok: ident, $e: expr) => {
61
+ match $e {
62
+ $ok( v) => v,
63
+ ref err => {
64
+ let err = err. as_ref( ) . map( drop) ; // map Ok/Some which might not be Debug
65
+ rtabort!( concat!( "unwrap failed: " , stringify!( $e) , " = {:?}" ) , err)
66
+ }
67
+ }
68
+ } ;
69
+ }
70
+
71
+ // One-time runtime initialization.
72
+ // Runs before `main`.
73
+ // SAFETY: must be called only once during runtime initialization.
74
+ // NOTE: this is not guaranteed to run, for example when Rust code is called externally.
75
+ #[ cfg_attr( test, allow( dead_code) ) ]
76
+ unsafe fn init ( argc : isize , argv : * const * const u8 ) {
77
+ unsafe {
78
+ sys:: init ( argc, argv) ;
79
+
80
+ let main_guard = sys:: thread:: guard:: init ( ) ;
81
+ // Next, set up the current Thread with the guard information we just
82
+ // created. Note that this isn't necessary in general for new threads,
83
+ // but we just do this to name the main thread and to give it correct
84
+ // info about the stack bounds.
85
+ let thread = Thread :: new ( Some ( rtunwrap ! ( Ok , CString :: new( "main" ) ) ) ) ;
86
+ thread_info:: set ( main_guard, thread) ;
87
+ }
88
+ }
89
+
90
+ // One-time runtime cleanup.
91
+ // Runs after `main` or at program exit.
92
+ // NOTE: this is not guaranteed to run, for example when the program aborts.
93
+ pub ( crate ) fn cleanup ( ) {
94
+ static CLEANUP : Once = Once :: new ( ) ;
95
+ CLEANUP . call_once ( || unsafe {
96
+ // Flush stdout and disable buffering.
97
+ crate :: io:: cleanup ( ) ;
98
+ // SAFETY: Only called once during runtime cleanup.
99
+ sys:: cleanup ( ) ;
100
+ } ) ;
101
+ }
102
+
21
103
// To reduce the generated code of the new `lang_start`, this function is doing
22
104
// the real work.
23
105
#[ cfg( not( test) ) ]
@@ -26,7 +108,7 @@ fn lang_start_internal(
26
108
argc : isize ,
27
109
argv : * const * const u8 ,
28
110
) -> Result < isize , !> {
29
- use crate :: { mem, panic, sys , sys_common } ;
111
+ use crate :: { mem, panic} ;
30
112
let rt_abort = move |e| {
31
113
mem:: forget ( e) ;
32
114
rtabort ! ( "initialization or cleanup bug" ) ;
@@ -42,14 +124,14 @@ fn lang_start_internal(
42
124
// prevent libstd from accidentally introducing a panic to these functions. Another is from
43
125
// user code from `main` or, more nefariously, as described in e.g. issue #86030.
44
126
// SAFETY: Only called once during runtime initialization.
45
- panic:: catch_unwind ( move || unsafe { sys_common :: rt :: init ( argc, argv) } ) . map_err ( rt_abort) ?;
127
+ panic:: catch_unwind ( move || unsafe { init ( argc, argv) } ) . map_err ( rt_abort) ?;
46
128
let ret_code = panic:: catch_unwind ( move || panic:: catch_unwind ( main) . unwrap_or ( 101 ) as isize )
47
129
. map_err ( move |e| {
48
130
mem:: forget ( e) ;
49
131
rtprintpanic ! ( "drop of the panic payload panicked" ) ;
50
132
sys:: abort_internal ( )
51
133
} ) ;
52
- panic:: catch_unwind ( sys_common :: rt :: cleanup) . map_err ( rt_abort) ?;
134
+ panic:: catch_unwind ( cleanup) . map_err ( rt_abort) ?;
53
135
ret_code
54
136
}
55
137
0 commit comments