11//! 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+ }
420
521// perma(?)-unstable
6- #[ unstable( feature = "core_backtrace " , issue = "74465" ) ]
22+ #[ unstable( feature = "backtrace " , issue = "74465" ) ]
723///
8- pub trait RawBacktraceImpl : fmt:: Debug + fmt:: Display + ' static {
24+ pub trait RawBacktrace : fmt:: Debug + fmt:: Display + ' static {
925 ///
1026 unsafe fn drop_and_free ( self : * mut Self ) ;
1127}
1228
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" ) ]
1488///
1589pub 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+ }
17171}
18172
19- #[ unstable( feature = "core_backtrace " , issue = "74465" ) ]
173+ #[ unstable( feature = "backtrace " , issue = "74465" ) ]
20174unsafe impl Send for Backtrace { }
21175
22- #[ unstable( feature = "core_backtrace " , issue = "74465" ) ]
176+ #[ unstable( feature = "backtrace " , issue = "74465" ) ]
23177unsafe impl Sync for Backtrace { }
24178
25- #[ unstable( feature = "core_backtrace " , issue = "74465" ) ]
179+ #[ unstable( feature = "backtrace " , issue = "74465" ) ]
26180impl Drop for Backtrace {
27181 fn drop ( & mut self ) {
28- unsafe { RawBacktraceImpl :: drop_and_free ( self . inner ) }
182+ unsafe { RawBacktrace :: drop_and_free ( self . inner ) }
29183 }
30184}
31185
32- #[ unstable( feature = "core_backtrace " , issue = "74465" ) ]
186+ #[ unstable( feature = "backtrace " , issue = "74465" ) ]
33187impl fmt:: Debug for Backtrace {
34188 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 } ;
36190 fmt:: Debug :: fmt ( imp, fmt)
37191 }
38192}
39193
40- #[ unstable( feature = "core_backtrace " , issue = "74465" ) ]
194+ #[ unstable( feature = "backtrace " , issue = "74465" ) ]
41195impl fmt:: Display for Backtrace {
42196 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 } ;
44198 fmt:: Display :: fmt ( imp, fmt)
45199 }
46200}
0 commit comments