Skip to content

Commit ae32ffc

Browse files
authored
Merge pull request #198 from rust-lang/leak-dbghelp
Leak `dbghelp.dll` like `CoreSymbolication` on OSX
2 parents dc7b283 + 4d38c4f commit ae32ffc

File tree

2 files changed

+11
-23
lines changed

2 files changed

+11
-23
lines changed

src/dbghelp.rs

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
//! be in the business of duplicating winapi, so we have a Cargo feature
1515
//! `verify-winapi` which asserts that all bindings match those in winapi and
1616
//! 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.
1723
1824
#![allow(non_snake_case)]
1925

@@ -104,8 +110,10 @@ macro_rules! dbghelp {
104110
/// error if `LoadLibraryW` fails.
105111
///
106112
/// 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+
}
109117
let lib = b"dbghelp.dll\0";
110118
unsafe {
111119
self.dll = LoadLibraryA(lib.as_ptr() as *const i8);
@@ -117,17 +125,6 @@ macro_rules! dbghelp {
117125
}
118126
}
119127

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-
131128
// Function for each method we'd like to use. When called it will
132129
// either read the cached function pointer or load it and return the
133130
// loaded value. Loads are asserted to succeed.
@@ -280,7 +277,7 @@ pub unsafe fn init() -> Result<Cleanup, ()> {
280277

281278
// Actually load `dbghelp.dll` into the process here, returning an error if
282279
// that fails.
283-
DBGHELP.open()?;
280+
DBGHELP.ensure_open()?;
284281

285282
OPTS_ORIG = DBGHELP.SymGetOptions().unwrap()();
286283

@@ -294,7 +291,6 @@ pub unsafe fn init() -> Result<Cleanup, ()> {
294291
// Symbols may have been initialized by another library or an
295292
// external debugger
296293
DBGHELP.SymSetOptions().unwrap()(OPTS_ORIG);
297-
DBGHELP.close();
298294
Err(())
299295
} else {
300296
COUNT += 1;
@@ -317,13 +313,6 @@ impl Drop for Cleanup {
317313
// backtrace is finished.
318314
DBGHELP.SymCleanup().unwrap()(GetCurrentProcess());
319315
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();
327316
}
328317
}
329318
}

src/windows.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,6 @@ ffi! {
340340
pub fn GetCurrentThread() -> HANDLE;
341341
pub fn RtlCaptureContext(ContextRecord: PCONTEXT) -> ();
342342
pub fn LoadLibraryA(a: *const i8) -> HMODULE;
343-
pub fn FreeLibrary(h: HMODULE) -> BOOL;
344343
pub fn GetProcAddress(h: HMODULE, name: *const i8) -> FARPROC;
345344
pub fn OpenProcess(
346345
dwDesiredAccess: DWORD,

0 commit comments

Comments
 (0)