rust_libloading: TLS destructors are not run on Library::drop resulting in illegal instruction on OS X
Hi, thanks for making this library, it’s really useful to me.
Unfortunately, when trying out a really simple use case, I get an Illegal Hardware Instruction error. The Rust code I’m using to load the dylib is:
extern crate libloading;
use libloading::{Library, Symbol};
fn main() {
let lib = Library::new("../test/target/release/libtest.dylib").unwrap();
let sym: Symbol<extern fn() -> ()> = unsafe {lib.get(b"testing")}.unwrap();
sym();
}
The dylib I’m loading contains a single function:
#[no_mangle]
pub fn testing() {
println!("YES!");
}
The dylib’s Cargo.toml file contains the needed crate-type = ["dylib"]
qualifier.
I wrote some equivalent C code (loading the exact same Rust library from above), which works perfectly fine (no errors):
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char *argv[]) {
void *lib = dlopen("../test/target/release/libtest.dylib", RTLD_LAZY);
void (*sym)(void) = dlsym(lib, "testing");
sym();
}
Any ideas why this might be happening? The illegal hardware instruction occurs after the main Rust function exits (I can place a print at the end of the main
function and it’ll be run, then the error will occur). I’m on OSX 10.11.2, using the most recent stable rust (rustc 1.5.0 (3d7cd77e4 2015-12-04)
).
I narrowed it down to the Drop function on the Library struct. If I comment its contents out, then the error doesn’t happen. I also replaced the Drop function with just a single call to dlclose
like so:
fn drop(&mut self) {
println!("{}", unsafe { dlclose(self.handle) });
}
Which prints 0 (meaning the close function didn’t return an error), which is weird.
About this issue
- Original URL
- State: open
- Created 9 years ago
- Comments: 21 (10 by maintainers)
Commits related to this issue
- https://github.com/nagisa/rust_libloading/issues/5 — committed to ubolonton/rust-dylib-issues by ubolonton 6 years ago
Since 0.3 you can specify arbitrary flags when opening a library. The
RTLD_NODELETE
(thanks for reminder @Np2x) essentially acts as implicitmem::forget
so you can now do something along the lines of:This should still work while liberating you from having to
mem::forget
your libraries 😃