14
14
//! be in the business of duplicating winapi, so we have a Cargo feature
15
15
//! `verify-winapi` which asserts that all bindings match those in winapi and
16
16
//! this feature is enabled on CI.
17
+ //!
18
+ //! Finally, you'll note here that the dll for `dbghelp.dll` is never unloaded,
19
+ //! and that's currently intentional. The thinking is that we can globally cache
20
+ //! it and use it between calls to the API, avoiding expensive loads/unloads. If
21
+ //! this is a problem for leak detectors or something like that we can cross the
22
+ //! bridge when we get there.
17
23
18
24
#![ allow( non_snake_case) ]
19
25
@@ -104,8 +110,10 @@ macro_rules! dbghelp {
104
110
/// error if `LoadLibraryW` fails.
105
111
///
106
112
/// Panics if library is already loaded.
107
- fn open( & mut self ) -> Result <( ) , ( ) > {
108
- assert!( self . dll. is_null( ) ) ;
113
+ fn ensure_open( & mut self ) -> Result <( ) , ( ) > {
114
+ if !self . dll. is_null( ) {
115
+ return Ok ( ( ) )
116
+ }
109
117
let lib = b"dbghelp.dll\0 " ;
110
118
unsafe {
111
119
self . dll = LoadLibraryA ( lib. as_ptr( ) as * const i8 ) ;
@@ -117,17 +125,6 @@ macro_rules! dbghelp {
117
125
}
118
126
}
119
127
120
- /// Unloads `dbghelp.dll`, resetting all function pointers to zero
121
- /// as well.
122
- fn close( & mut self ) {
123
- assert!( !self . dll. is_null( ) ) ;
124
- unsafe {
125
- $( self . $name = 0 ; ) *
126
- FreeLibrary ( self . dll) ;
127
- self . dll = ptr:: null_mut( ) ;
128
- }
129
- }
130
-
131
128
// Function for each method we'd like to use. When called it will
132
129
// either read the cached function pointer or load it and return the
133
130
// loaded value. Loads are asserted to succeed.
@@ -280,7 +277,7 @@ pub unsafe fn init() -> Result<Cleanup, ()> {
280
277
281
278
// Actually load `dbghelp.dll` into the process here, returning an error if
282
279
// that fails.
283
- DBGHELP . open ( ) ?;
280
+ DBGHELP . ensure_open ( ) ?;
284
281
285
282
OPTS_ORIG = DBGHELP . SymGetOptions ( ) . unwrap ( ) ( ) ;
286
283
@@ -294,7 +291,6 @@ pub unsafe fn init() -> Result<Cleanup, ()> {
294
291
// Symbols may have been initialized by another library or an
295
292
// external debugger
296
293
DBGHELP . SymSetOptions ( ) . unwrap ( ) ( OPTS_ORIG ) ;
297
- DBGHELP . close ( ) ;
298
294
Err ( ( ) )
299
295
} else {
300
296
COUNT += 1 ;
@@ -317,13 +313,6 @@ impl Drop for Cleanup {
317
313
// backtrace is finished.
318
314
DBGHELP . SymCleanup ( ) . unwrap ( ) ( GetCurrentProcess ( ) ) ;
319
315
DBGHELP . SymSetOptions ( ) . unwrap ( ) ( OPTS_ORIG ) ;
320
-
321
- // We can in theory leak this to stay in a global and we simply
322
- // always reuse it, but for now let's be tidy and release all our
323
- // resources. If we get bug reports the we could basically elide
324
- // this `close()` (and the one above) and then update `open` to be a
325
- // noop if it's already opened.
326
- DBGHELP . close ( ) ;
327
316
}
328
317
}
329
318
}
0 commit comments