@@ -29,12 +29,26 @@ use intrinsics;
2929use mem;
3030use ptr;
3131use raw;
32- use sys:: stdio:: { Stderr , stderr_prints_nothing } ;
32+ use sys:: stdio:: { Stderr , panic_output } ;
3333use sys_common:: rwlock:: RWLock ;
3434use sys_common:: thread_info;
3535use sys_common:: util;
3636use thread;
3737
38+ #[ derive( Clone , Copy ) ]
39+ #[ allow( dead_code) ]
40+ pub enum PanicOutput {
41+ StdErr ,
42+ }
43+
44+ impl PanicOutput {
45+ pub ( crate ) fn write < T , F : FnOnce ( & mut Write ) -> T > ( self , write : F ) {
46+ match self {
47+ PanicOutput :: StdErr => Stderr :: new ( ) . ok ( ) . map ( |mut w| write ( & mut w) ) ,
48+ } ;
49+ }
50+ }
51+
3852thread_local ! {
3953 pub static LOCAL_STDERR : RefCell <Option <Box <dyn Write + Send >>> = {
4054 RefCell :: new( None )
@@ -168,6 +182,11 @@ pub fn take_hook() -> Box<dyn Fn(&PanicInfo) + 'static + Sync + Send> {
168182}
169183
170184fn default_hook ( info : & PanicInfo ) {
185+ let out = match panic_output ( ) {
186+ Some ( out) => out,
187+ None => return
188+ } ;
189+
171190 #[ cfg( feature = "backtrace" ) ]
172191 use sys_common:: backtrace;
173192
@@ -193,7 +212,6 @@ fn default_hook(info: &PanicInfo) {
193212 None => "Box<Any>" ,
194213 }
195214 } ;
196- let mut err = Stderr :: new ( ) . ok ( ) ;
197215 let thread = thread_info:: current_thread ( ) ;
198216 let name = thread. as_ref ( ) . and_then ( |t| t. name ( ) ) . unwrap_or ( "<unnamed>" ) ;
199217
@@ -215,17 +233,14 @@ fn default_hook(info: &PanicInfo) {
215233 }
216234 } ;
217235
218- let prev = LOCAL_STDERR . with ( |s| s. borrow_mut ( ) . take ( ) ) ;
219- match ( prev, err. as_mut ( ) ) {
220- ( Some ( mut stderr) , _) => {
221- write ( & mut * stderr) ;
222- let mut s = Some ( stderr) ;
223- LOCAL_STDERR . with ( |slot| {
224- * slot. borrow_mut ( ) = s. take ( ) ;
225- } ) ;
226- }
227- ( None , Some ( ref mut err) ) => { write ( err) }
228- _ => { }
236+ if let Some ( mut local) = LOCAL_STDERR . with ( |s| s. borrow_mut ( ) . take ( ) ) {
237+ write ( & mut * local) ;
238+ let mut s = Some ( local) ;
239+ LOCAL_STDERR . with ( |slot| {
240+ * slot. borrow_mut ( ) = s. take ( ) ;
241+ } ) ;
242+ } else {
243+ out. write ( write) ;
229244 }
230245}
231246
@@ -466,20 +481,11 @@ fn rust_panic_with_hook(payload: &mut dyn BoxMeUp,
466481 Location :: internal_constructor ( file, line, col) ,
467482 ) ;
468483 HOOK_LOCK . read ( ) ;
484+ info. set_payload ( payload. get ( ) ) ;
469485 match HOOK {
470- // Some platforms know that printing to stderr won't ever actually
471- // print anything, and if that's the case we can skip the default
472- // hook.
473- Hook :: Default if stderr_prints_nothing ( ) => { }
474- Hook :: Default => {
475- info. set_payload ( payload. get ( ) ) ;
476- default_hook ( & info) ;
477- }
478- Hook :: Custom ( ptr) => {
479- info. set_payload ( payload. get ( ) ) ;
480- ( * ptr) ( & info) ;
481- }
482- }
486+ Hook :: Default => default_hook ( & info) ,
487+ Hook :: Custom ( ptr) => ( * ptr) ( & info) ,
488+ } ;
483489 HOOK_LOCK . read_unlock ( ) ;
484490 }
485491
0 commit comments