1
1
//! hi
2
- #![ unstable( feature = "core_backtrace" , issue = "74465" ) ]
3
- use crate :: fmt;
2
+ #![ unstable( feature = "backtrace" , issue = "74465" ) ]
3
+ use crate :: { fmt, ptr} ;
4
+
5
+ /// The current status of a backtrace, indicating whether it was captured or
6
+ /// whether it is empty for some other reason.
7
+ #[ non_exhaustive]
8
+ #[ derive( Debug , PartialEq , Eq ) ]
9
+ pub enum BacktraceStatus {
10
+ /// Capturing a backtrace is not supported, likely because it's not
11
+ /// implemented for the current platform.
12
+ Unsupported ,
13
+ /// Capturing a backtrace has been disabled through either the
14
+ /// `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` environment variables.
15
+ Disabled ,
16
+ /// A backtrace has been captured and the `Backtrace` should print
17
+ /// reasonable information when rendered.
18
+ Captured ,
19
+ }
4
20
5
21
// perma(?)-unstable
6
- #[ unstable( feature = "core_backtrace " , issue = "74465" ) ]
22
+ #[ unstable( feature = "backtrace " , issue = "74465" ) ]
7
23
///
8
- pub trait RawBacktraceImpl : fmt:: Debug + fmt:: Display + ' static {
24
+ pub trait RawBacktrace : fmt:: Debug + fmt:: Display + ' static {
9
25
///
10
26
unsafe fn drop_and_free ( self : * mut Self ) ;
11
27
}
12
28
13
- #[ unstable( feature = "core_backtrace" , issue = "74465" ) ]
29
+ struct UnsupportedBacktrace ;
30
+
31
+ impl UnsupportedBacktrace {
32
+ #[ allow( dead_code) ]
33
+ const fn create ( ) -> Backtrace {
34
+ // don't add members to Self
35
+ let _ = Self { } ;
36
+
37
+ Backtrace {
38
+ inner : ptr:: NonNull :: < Self > :: dangling ( ) . as_ptr ( ) ,
39
+ }
40
+ }
41
+ }
42
+
43
+ impl RawBacktrace for UnsupportedBacktrace {
44
+ unsafe fn drop_and_free ( self : * mut Self ) { }
45
+ }
46
+
47
+ impl fmt:: Display for UnsupportedBacktrace {
48
+ fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
49
+ fmt. write_str ( "unsupported backtrace" )
50
+ }
51
+ }
52
+
53
+ impl fmt:: Debug for UnsupportedBacktrace {
54
+ fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
55
+ fmt. write_str ( "<unsupported>" )
56
+ }
57
+ }
58
+ struct DisabledBacktrace ;
59
+
60
+ impl DisabledBacktrace {
61
+ const fn create ( ) -> Backtrace {
62
+ // don't add members to Self
63
+ let _ = Self { } ;
64
+
65
+ Backtrace {
66
+ inner : ptr:: NonNull :: < Self > :: dangling ( ) . as_ptr ( ) ,
67
+ }
68
+ }
69
+ }
70
+
71
+ impl RawBacktrace for DisabledBacktrace {
72
+ unsafe fn drop_and_free ( self : * mut Self ) { }
73
+ }
74
+
75
+ impl fmt:: Display for DisabledBacktrace {
76
+ fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
77
+ fmt. write_str ( "disabled backtrace" )
78
+ }
79
+ }
80
+
81
+ impl fmt:: Debug for DisabledBacktrace {
82
+ fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
83
+ fmt. write_str ( "<disabled>" )
84
+ }
85
+ }
86
+
87
+ #[ unstable( feature = "backtrace" , issue = "74465" ) ]
14
88
///
15
89
pub struct Backtrace {
16
- inner : * mut dyn RawBacktraceImpl ,
90
+ ///
91
+ inner : * mut dyn RawBacktrace ,
92
+ }
93
+
94
+ /// Global implementation of backtrace functionality. Called to create
95
+ /// `RawBacktrace` trait objects.
96
+ extern "Rust" {
97
+ #[ lang = "backtrace_create" ]
98
+ fn backtrace_create ( ip : usize ) -> * mut dyn RawBacktrace ;
99
+
100
+ #[ lang = "backtrace_enabled" ]
101
+ fn backtrace_enabled ( ) -> bool ;
102
+
103
+ #[ lang = "backtrace_status" ]
104
+ fn backtrace_status ( raw : * mut dyn RawBacktrace ) -> BacktraceStatus ;
105
+ }
106
+
107
+ impl Backtrace {
108
+ fn create ( ip : usize ) -> Backtrace {
109
+ let inner = unsafe { backtrace_create ( ip) } ;
110
+ Backtrace { inner }
111
+ }
112
+
113
+ /// Returns whether backtrace captures are enabled through environment
114
+ /// variables.
115
+ fn enabled ( ) -> bool {
116
+ unsafe { backtrace_enabled ( ) }
117
+ }
118
+
119
+ /// Capture a stack backtrace of the current thread.
120
+ ///
121
+ /// This function will capture a stack backtrace of the current OS thread of
122
+ /// execution, returning a `Backtrace` type which can be later used to print
123
+ /// the entire stack trace or render it to a string.
124
+ ///
125
+ /// This function will be a noop if the `RUST_BACKTRACE` or
126
+ /// `RUST_LIB_BACKTRACE` backtrace variables are both not set. If either
127
+ /// environment variable is set and enabled then this function will actually
128
+ /// capture a backtrace. Capturing a backtrace can be both memory intensive
129
+ /// and slow, so these environment variables allow liberally using
130
+ /// `Backtrace::capture` and only incurring a slowdown when the environment
131
+ /// variables are set.
132
+ ///
133
+ /// To forcibly capture a backtrace regardless of environment variables, use
134
+ /// the `Backtrace::force_capture` function.
135
+ #[ inline( never) ] // want to make sure there's a frame here to remove
136
+ pub fn capture ( ) -> Backtrace {
137
+ if !Backtrace :: enabled ( ) {
138
+ return Backtrace :: disabled ( ) ;
139
+ }
140
+
141
+ Self :: create ( Backtrace :: capture as usize )
142
+ }
143
+
144
+ /// Forcibly captures a full backtrace, regardless of environment variable
145
+ /// configuration.
146
+ ///
147
+ /// This function behaves the same as `capture` except that it ignores the
148
+ /// values of the `RUST_BACKTRACE` and `RUST_LIB_BACKTRACE` environment
149
+ /// variables, always capturing a backtrace.
150
+ ///
151
+ /// Note that capturing a backtrace can be an expensive operation on some
152
+ /// platforms, so this should be used with caution in performance-sensitive
153
+ /// parts of code.
154
+ #[ inline( never) ] // want to make sure there's a frame here to remove
155
+ pub fn force_capture ( ) -> Backtrace {
156
+ Self :: create ( Backtrace :: force_capture as usize )
157
+ }
158
+
159
+ /// Forcibly captures a disabled backtrace, regardless of environment
160
+ /// variable configuration.
161
+ pub const fn disabled ( ) -> Backtrace {
162
+ DisabledBacktrace :: create ( )
163
+ }
164
+
165
+ /// Returns the status of this backtrace, indicating whether this backtrace
166
+ /// request was unsupported, disabled, or a stack trace was actually
167
+ /// captured.
168
+ pub fn status ( & self ) -> BacktraceStatus {
169
+ unsafe { backtrace_status ( self . inner ) }
170
+ }
17
171
}
18
172
19
- #[ unstable( feature = "core_backtrace " , issue = "74465" ) ]
173
+ #[ unstable( feature = "backtrace " , issue = "74465" ) ]
20
174
unsafe impl Send for Backtrace { }
21
175
22
- #[ unstable( feature = "core_backtrace " , issue = "74465" ) ]
176
+ #[ unstable( feature = "backtrace " , issue = "74465" ) ]
23
177
unsafe impl Sync for Backtrace { }
24
178
25
- #[ unstable( feature = "core_backtrace " , issue = "74465" ) ]
179
+ #[ unstable( feature = "backtrace " , issue = "74465" ) ]
26
180
impl Drop for Backtrace {
27
181
fn drop ( & mut self ) {
28
- unsafe { RawBacktraceImpl :: drop_and_free ( self . inner ) }
182
+ unsafe { RawBacktrace :: drop_and_free ( self . inner ) }
29
183
}
30
184
}
31
185
32
- #[ unstable( feature = "core_backtrace " , issue = "74465" ) ]
186
+ #[ unstable( feature = "backtrace " , issue = "74465" ) ]
33
187
impl fmt:: Debug for Backtrace {
34
188
fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
35
- let imp: & dyn RawBacktraceImpl = unsafe { & * self . inner } ;
189
+ let imp: & dyn RawBacktrace = unsafe { & * self . inner } ;
36
190
fmt:: Debug :: fmt ( imp, fmt)
37
191
}
38
192
}
39
193
40
- #[ unstable( feature = "core_backtrace " , issue = "74465" ) ]
194
+ #[ unstable( feature = "backtrace " , issue = "74465" ) ]
41
195
impl fmt:: Display for Backtrace {
42
196
fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
43
- let imp: & dyn RawBacktraceImpl = unsafe { & * self . inner } ;
197
+ let imp: & dyn RawBacktrace = unsafe { & * self . inner } ;
44
198
fmt:: Display :: fmt ( imp, fmt)
45
199
}
46
200
}
0 commit comments