@@ -7,44 +7,41 @@ use crate::fmt;
7
7
use crate :: io;
8
8
use crate :: io:: prelude:: * ;
9
9
use crate :: path:: { self , Path , PathBuf } ;
10
- use crate :: sync:: { Mutex , PoisonError } ;
10
+ use crate :: sync:: { Mutex , MutexGuard , PoisonError } ;
11
11
12
12
/// Max number of frames to print.
13
13
const MAX_NB_FRAMES : usize = 100 ;
14
14
15
- pub fn lock ( ) -> impl Drop {
15
+ pub ( crate ) struct BacktraceLock < ' a > ( #[ allow( dead_code) ] MutexGuard < ' a , ( ) > ) ;
16
+
17
+ pub ( crate ) fn lock < ' a > ( ) -> BacktraceLock < ' a > {
16
18
static LOCK : Mutex < ( ) > = Mutex :: new ( ( ) ) ;
17
- LOCK . lock ( ) . unwrap_or_else ( PoisonError :: into_inner)
19
+ BacktraceLock ( LOCK . lock ( ) . unwrap_or_else ( PoisonError :: into_inner) )
18
20
}
19
21
20
- /// Prints the current backtrace.
21
- pub fn print ( w : & mut dyn Write , format : PrintFmt ) -> io:: Result < ( ) > {
22
- // There are issues currently linking libbacktrace into tests, and in
23
- // general during std's own unit tests we're not testing this path. In
24
- // test mode immediately return here to optimize away any references to the
25
- // libbacktrace symbols
26
- if cfg ! ( test) {
27
- return Ok ( ( ) ) ;
28
- }
29
-
30
- // Use a lock to prevent mixed output in multithreading context.
31
- // Some platforms also requires it, like `SymFromAddr` on Windows.
32
- unsafe {
33
- let _lock = lock ( ) ;
34
- _print ( w, format)
35
- }
36
- }
22
+ impl BacktraceLock < ' _ > {
23
+ /// Prints the current backtrace.
24
+ ///
25
+ /// NOTE: this function is not Sync. The caller must hold a mutex lock, or there must be only one thread in the program.
26
+ pub ( crate ) fn print ( & mut self , w : & mut dyn Write , format : PrintFmt ) -> io:: Result < ( ) > {
27
+ // There are issues currently linking libbacktrace into tests, and in
28
+ // general during std's own unit tests we're not testing this path. In
29
+ // test mode immediately return here to optimize away any references to the
30
+ // libbacktrace symbols
31
+ if cfg ! ( test) {
32
+ return Ok ( ( ) ) ;
33
+ }
37
34
38
- unsafe fn _print ( w : & mut dyn Write , format : PrintFmt ) -> io :: Result < ( ) > {
39
- struct DisplayBacktrace {
40
- format : PrintFmt ,
41
- }
42
- impl fmt:: Display for DisplayBacktrace {
43
- fn fmt ( & self , fmt : & mut fmt :: Formatter < ' _ > ) -> fmt :: Result {
44
- unsafe { _print_fmt ( fmt , self . format ) }
35
+ struct DisplayBacktrace {
36
+ format : PrintFmt ,
37
+ }
38
+ impl fmt :: Display for DisplayBacktrace {
39
+ fn fmt ( & self , fmt : & mut fmt :: Formatter < ' _ > ) -> fmt :: Result {
40
+ unsafe { _print_fmt ( fmt , self . format ) }
41
+ }
45
42
}
43
+ write ! ( w, "{}" , DisplayBacktrace { format } )
46
44
}
47
- write ! ( w, "{}" , DisplayBacktrace { format } )
48
45
}
49
46
50
47
unsafe fn _print_fmt ( fmt : & mut fmt:: Formatter < ' _ > , print_fmt : PrintFmt ) -> fmt:: Result {
0 commit comments