Giter Club home page Giter Club logo

rust_libloading's Introduction

libloading

Bindings around the platform's dynamic library loading primitives with greatly improved memory safety. The most important safety guarantee of this library is the prevention of dangling Symbols that may occur after a Library is unloaded.

Using this library allows the loading of dynamic libraries, also known as shared libraries, as well as the use of the functions and static variables that these libraries may contain.

libloading is available to use under ISC (MIT-like) license.

rust_libloading's People

Contributors

adamcrume avatar alexanderschuetz97 avatar bilelmoussaoui avatar bozaro avatar cuishuang avatar decathorpe avatar ecnelises avatar flba-eb avatar gabrielmajeri avatar haouvw avatar jamessan avatar johnthagen avatar kinetiknz avatar lilianmoraru avatar llogiq avatar mati865 avatar mbrubeck avatar nagisa avatar nightra avatar paolobarbolini avatar psumbera avatar return avatar skade avatar sthibaul avatar tyleo avatar vthib avatar w-henderson avatar waywardmonkeys avatar yalter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust_libloading's Issues

When running tests outside cargo libloading is not able to find shared object

Disclaimer up front, this is probably not a libloading issue but anyone trying to debug tests that use libloading would face the same issue.

I have a test that is loading shared objects and when run via cargo is able to find and load the module. But, when I try to run the test directly on the command line (or via gdb) the shared object is not found.

std::env is reporting that current_dir and current_exe are the same in both cases so I would expect the same module path passed to libloading would work.

Please advise, thanks!

C library aborts when locking the mutex during cross compile

This mozjs commit segfaults while running bindgen. I tracked this down to the loading of libclang in bindgen, which relies on libloading. pthread_mutex_lock returns EINVAL, which causes the C library to abort execution. When I force an older version of libloading to be used that does not include d870a38, bindgen is able to execute cleanly.

This only happens when building on macOS with an Android target. The non-cross macOS build works fine.

support opening existing library

Hello,

Currently you can do Library::new() which loads a library.
For my use case it would be create to have Library::open that opens an already existing library.

  • I'm trying to query optionally exported functions in preloaded shared library.

Implementation can be accomplished with the RTLD_NOLOAD flag for dlopen on most unixes and GetModuleHandleEx in windows.

I can write the code myself and submit a PR if that works for you.

Get the dll and function for SetWindowsHookExA

How do I get a HINSTANCE from the Library, and HOOKPROC from the Symbol?

I want to use them in a SetWindowsHookExA call.

HHOOK SetWindowsHookExA(
  int       idHook,
  HOOKPROC  lpfn,
  HINSTANCE hmod,
  DWORD     dwThreadId
);

File extension inconsistency

Currently, as per the docs, on Windows, the default behavior for Library::open(…) is to automatically concatenate the platform-specific .dll extension when no extension is provided (or just omit it when a . suffix is given.)

This behavior is inconsistent across platforms, for example:

use libloading::Library;

fn main() {
    let library = Library::new("libzeta_core").unwrap();
}

On Windows, this will, as expected, try to load libzeta_core.dll - however, on Linux, this will try to load libzeta_core which is not the expected shared library filename - it's expected to be libzeta_core.so.

I'd suggest that libloading provides a platform-specific load sequence:

  • If no extension is given, it should try to load the library with a platform-specific extension
    • On Linux, *BSD and macOS, this should be .so
    • On Windows, this should be .dll

In all cases, when a . suffix is given, it should just try to load the filename without any extension.

Cloning Dereferenced symbol may cause undefined behaviour.

Since adding the Clone functionality I have been experimenting with cloning Symbols. I noticed that it is possible to clone a dereferenced Symbol. This may cause undefined behavior. In particular this code is broken:

let func = {
    let library = Library::new("path_to_lib").unwrap();
    let func = library.get::<fn()>(b"symbol").unwrap();
    let func_ref = &func;
    func_ref.clone()
};
func();

This derefs func as fn() and calls the Clone implementation on fn() rather than on the Symbol object. Since the Symbol's Library has already gone out of scope, the call can fail. I am currently investigating ways to get around this.

To be clear, this problem is not caused by the new Clone functionality and it exists on earlier versions of the code. The problem seems to be with the Deref implementation:

impl<T> ::std::ops::Deref for Symbol<T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe {
            // Additional reference level for a dereference on `deref` return value.
            mem::transmute(&self.pointer)
        }
    }
}

In particular, the transmute drops lifetime information about the Symbol but allows it to be copied from the raw function pointer.

Include example that shows how to wrap library in struct

Hello.
First of all, thanks for this great library. I am pretty new to Rust and I need to call a few functions inside a Windows DLL from Rust. To keep things clean I want to stick the symbols into a struct and provide a safe interface. But I cannot figure out how to do this. So I thought it would be nice if the documentation had an example on how to provide a safe wrapper.

Error: cannot allocate memory in static TLS block

I'm seeing the following error on Linux only when loading a dynamic object:

cannot allocate memory in static TLS block

Is there a workaround within the Rust environment for this? Any guidance? Thanks!

Dropping and reloading a dylib on macOS returns the old version, but only if the dylib uses the stdlib

I'm attempting to get some sort of code hotswapping working by dynamically re-loading a crate at runtime when it changes.

I've noticed weirdly that it works if the dylib isn't using stdlib (no print!, no Strings, etc.) - but as soon as you add any reference to something from std in the dylib, it breaks the reloading until the program quits. Or rather, the Library reloads, but returns the outdated version (same handle as before).

I pushed a crate with a repo in it: https://github.com/mistodon/dlopen_issue - it's as concise as I could make a working example. But basically:

To reproduce, on macOS:

  1. Load a dylib
  2. Drop it
  3. Recompile it
  4. Load it again
  5. Observe that:
    a. If the dylib uses std, the new version has not been loaded
    b. If the dylib does not use std, the new version has been loaded

I'm not sure if this is a bug in libloading, or dylib, or if I'm doing something wrong. Or possibly this is intended behaviour and I'm not understanding something? But anyway I'm baffled and not sure where to look next.

Thanks for reading, and sorry it's a bit long-winded!

Potential double free issue with `os::windows::Library::close`

Hi!

I've been working together with someone on a PR to an FFI wrapper crate I maintain to make use of the new bindgen feature that generates libloading boilerplate, enabling us to load the library dynamically at runtime.

Everything is working well on both Windows and Linux except for the following:

error: test failed, to rerun pass '--lib'

Caused by:
  process didn't exit successfully: `C:\Users\cldfi\Desktop\programming\nvml-wrapper\target\debug\deps\nvml_wrapper-f40d6d390aa3bfdd.exe` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)

I'm getting a STATUS_ACCESS_VIOLATION on Windows when running the test suite locally in parallel (via cargo test --features test-local). I found that if I commented out this test function the test suite ran successfully. I also found that running the test suite with --test-threads 1 fixed the issue.

That test function is calling NVML::shutdown, defined as follows (with my local changes, this isn't in the repo atm):

    pub fn shutdown(mut self) -> Result<(), NvmlError> {
        let sym = nvml_sym(self.lib.nvmlShutdown.as_ref())?;

        unsafe {
            nvml_try(sym())?;
        }

        // SAFETY: we `mem::forget(self)` after this, so `self.lib` won't get
        // touched by our `Drop` impl
        let lib = unsafe { ManuallyDrop::take(&mut self.lib) };
        lib.__library.close()?;

        mem::forget(self);
        Ok(())
    }

Where NVML (self) is defined as:

pub struct NVML {
    lib: ManuallyDrop<NvmlLib>,
}

impl Drop for NVML {
    fn drop(&mut self) {
        unsafe {
            self.lib.nvmlShutdown();

            // SAFETY: called after the last usage of `self.lib`
            ManuallyDrop::drop(&mut self.lib);
        }
    }
}

and NvmlLib is the wrapper type bindgen has generated over top of libloading::Library.

I double-checked my implementation of NVML::shutdown, and as far as I can tell it looks good. So, I went and took a look at libloading::Library::close, which on Windows calls this function:

    pub fn close(self) -> Result<(), crate::Error> {
        with_get_last_error(|source| crate::Error::FreeLibrary { source }, || {
            if unsafe { libloaderapi::FreeLibrary(self.0) == 0 } {
                None
            } else {
                Some(())
            }
        }).map_err(|e| e.unwrap_or(crate::Error::FreeLibraryUnknown))
    }

immediately under which is this Drop impl:

impl Drop for Library {
    fn drop(&mut self) {
        unsafe { libloaderapi::FreeLibrary(self.0); }
    }
}

It looks to me as if there's a double free going on here; libloaderapi::FreeLibrary is going to get called twice when calling os::windows::Library::close because there's no mem::forget(self) involved. The equivalent function on the linux side does do a mem::forget(self) (and I didn't experience this issue on linux).

I tried putting together a small reproduction:

fn main() {
    for _ in 0..100 {
        std::thread::spawn(|| {
            let lib = libloading::Library::new("nvml.dll").unwrap();
            let _: libloading::Symbol<unsafe extern "C" fn() -> u32> = unsafe { lib.get(b"nvmlInit").unwrap() };
            lib.close().unwrap();
        });
    }
}

I wasn't able to get a STATUS_ACCESS_VIOLATION out of this, but it does return random quantities of errors when running it:

PS C:\Users\cldfi\Desktop\programming\rust_libloading> cargo run --release --example quick
    Finished release [optimized] target(s) in 0.01s
     Running `target\release\examples\quick.exe`
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: GetProcAddress { source: Os { code: 87, kind: InvalidInput, message: "The parameter is incorrect." } }', examples\quick.rs:5:102
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: GetProcAddress { source: Os { code: 87, kind: InvalidInput, message: "The parameter is incorrect." } }', examples\quick.rs:5:102
thread 'thread 'thread 'thread '<unnamed><unnamed><unnamed><unnamed>' panicked at '' panicked at '' panicked at '' panicked at 'called `Result::unwrap()` on an `Err` value: GetProcAddress { source: Os { code: 87, kind: InvalidInput, message: "The parameter is incorrect." 
} }called `Result::unwrap()` on an `Err` value: GetProcAddress { source: Os { code: 87, kind: InvalidInput, message: "The parameter is incorrect." } }called `Result::unwrap()` on an `Err` value: GetProcAddress { source: Os { code: 87, kind: InvalidInput, message: "The parameter is incorrect." } }called `Result::unwrap()` on an `Err` value: GetProcAddress { source: Os { code: 87, kind: InvalidInput, message: "The parameter is incorrect." } }', ', ', ', examples\quick.rsexamples\quick.rsexamples\quick.rsexamples\quick.rs::::5555::::102102102
PS C:\Users\cldfi\Desktop\programming\rust_libloading>

Adding a mem::forget(self) to the end of os::windows::Library::close seems to eliminate those errors for me:

PS C:\Users\cldfi\Desktop\programming\rust_libloading> cargo run --release --example quick
    Finished release [optimized] target(s) in 0.01s
     Running `target\release\examples\quick.exe`
PS C:\Users\cldfi\Desktop\programming\rust_libloading>

and it also fixed the STATUS_ACCESS_VIOLATION when running my crate's test suite in parallel.

tl;dr, am I doing something wrong or is there a missing mem::forget(self) in os::windows::Library::close?

Add illumos to link_libraries

Can we add "illumos" => {}" to fn link_libraries() so that the new illumos triple is recognized as a known target? I can open a PR if you would like.

Get inner handle

I was trying to use this library to build a frontend for Mupen64Plus.
However the Plugin API requires a void pointer to the core library.

The first thing I tried is giving it the pointer to the Library struct instead of the handle but it is doing some weird things. It seems like it can call the functions from the Core lib handle, but it can't do it properly, resulting in error return messages. Giving it a null pointer results in the same error message, so it cannot call the functions from the Library.

So I was modifying this library to expose the inner handle, so that I can pass it properly to Mupen64Plus and now it works. Is there any other way to get the inner handle?
Would you like me to send a PR for this?

linuxbrew ldd vs debian ldd. Easy way to override?

Hi,

I was having issues getting rocksdb crate to build. The issue that I was having was that libloading crate picking up the wrong shared libraries. This could be an libc issue as well.

The error I was getting was:

'Unable to find libclang: "the libclang shared library at /usr/lib/llvm-10/lib/libclang-10.so.1 could not be opened: libstdc++.so.6: cannot open shared object file: No such file or directory"

What was interesting was ldd was also returning the missing libraries. This is what I was getting with the linuxbrew ldd

ldd /usr/lib/llvm-10/lib/libclang-10.so.1
ldd: warning: you do not have execution permission for `/usr/lib/llvm-10/lib/libclang-10.so.1'
/usr/lib/llvm-10/lib/libclang-10.so.1: /home/silas/.linuxbrew/Cellar/glibc/2.23/lib/libm.so.6: version `GLIBC_2.27' not found (required by /usr/lib/llvm-10/lib/../lib/libLLVM-10.so.1)
	linux-vdso.so.1 (0x00007ffde8db7000)
	libdl.so.2 => /home/silas/.linuxbrew/Cellar/glibc/2.23/lib/libdl.so.2 (0x00007f188569c000)
	libLLVM-10.so.1 => /usr/lib/llvm-10/lib/../lib/libLLVM-10.so.1 (0x00007f1880b17000)
	libpthread.so.0 => /home/silas/.linuxbrew/Cellar/glibc/2.23/lib/libpthread.so.0 (0x00007f18808fa000)
	libstdc++.so.6 => not found
	libm.so.6 => /home/silas/.linuxbrew/Cellar/glibc/2.23/lib/libm.so.6 (0x00007f18805f4000)
	libgcc_s.so.1 => /home/silas/.linuxbrew/Cellar/glibc/2.23/lib/libgcc_s.so.1 (0x00007f18803dd000)
	libc.so.6 => /home/silas/.linuxbrew/Cellar/glibc/2.23/lib/libc.so.6 (0x00007f188003d000)
	/home/silas/.linuxbrew/Cellar/glibc/2.23/lib64/ld-linux-x86-64.so.2 (0x00007f188788d000)
	libffi.so.6 => not found
	libedit.so.2 => not found
	libz.so.1 => not found
	librt.so.1 => /home/silas/.linuxbrew/Cellar/glibc/2.23/lib/librt.so.1 (0x00007f187fe35000)
	libtinfo.so.6 => not found
	libstdc++.so.6 => not found

This is what I got with Debian ldd

/usr/bin/ldd /usr/lib/llvm-10/lib/libclang-10.so.1
	linux-vdso.so.1 (0x00007ffe9cbf4000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f08138d0000)
	libLLVM-10.so.1 => /usr/lib/llvm-10/lib/../lib/libLLVM-10.so.1 (0x00007f080ed4b000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f080ed2a000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f080eba6000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f080ea23000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f080ea09000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f080e846000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f08158d2000)
	libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007f080e83c000)
	libedit.so.2 => /usr/lib/x86_64-linux-gnu/libedit.so.2 (0x00007f080e805000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f080e5e7000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f080e5dd000)
	libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f080e5af000)
	libbsd.so.0 => /usr/lib/x86_64-linux-gnu/libbsd.so.0 (0x00007f080e593000)

The only way that I could fix this was to remove $HOME/.linuxbrew/bin from my PATH and then call cargo build. This is annoying and tricky to debug, but it worked. Is there a better way to solve this other than changing my PATH, maybe by forcing libloading or maybe libc crate to use an ldd that I specify?

Broken when cross compiling

build.rs uses cfg directives to determine the library to link to, which means that in a cross-compiling scenario the wrong flags (those appropriate for the host and not the build target) will be sent to the linker.

tests try to open .dll on linux

---- missing_symbol_fails stdout ----
	thread 'missing_symbol_fails' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Custom(Custom { kind: Other, error: StringError("/home/brain/rpmbuild/BUILD/libloading-0.4.2/target/release/build/libloading-4f12e18e49d5bef6/out/libtest_helpers.dll: cannot open shared object file: No such file or directory") }) }', src/libcore/result.rs:906:4

---- test_0_no_0 stdout ----
	thread 'test_0_no_0' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Custom(Custom { kind: Other, error: StringError("/home/brain/rpmbuild/BUILD/libloading-0.4.2/target/release/build/libloading-4f12e18e49d5bef6/out/libtest_helpers.dll: cannot open shared object file: No such file or directory") }) }', src/libcore/result.rs:906:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.

---- interior_null_fails stdout ----
	thread 'interior_null_fails' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Custom(Custom { kind: Other, error: StringError("/home/brain/rpmbuild/BUILD/libloading-0.4.2/target/release/build/libloading-4f12e18e49d5bef6/out/libtest_helpers.dll: cannot open shared object file: No such file or directory") }) }', src/libcore/result.rs:906:4

---- test_id_struct stdout ----
	thread 'test_id_struct' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Custom(Custom { kind: Other, error: StringError("/home/brain/rpmbuild/BUILD/libloading-0.4.2/target/release/build/libloading-4f12e18e49d5bef6/out/libtest_helpers.dll: cannot open shared object file: No such file or directory") }) }', src/libcore/result.rs:906:4

---- test_id_u32 stdout ----
	thread 'test_id_u32' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Custom(Custom { kind: Other, error: StringError("/home/brain/rpmbuild/BUILD/libloading-0.4.2/target/release/build/libloading-4f12e18e49d5bef6/out/libtest_helpers.dll: cannot open shared object file: No such file or directory") }) }', src/libcore/result.rs:906:4

Windows synchronization bugs

Hi!

I was writting my own library for loading dynamic link libraries and while analyzing your Windows code:
https://github.com/nagisa/rust_libloading/blob/master/src/os/windows/mod.rs
I think I found two bugs:

  1. Invalid behavior if SetThreadErrorMode() returns an error that is different from ERROR_CALL_NOT_IMPLEMENTED

    Your code basicly returns a guard with a random previous value in this case.

  2. Synchronization issue when several threads call SetErrorMode().

    Please notice that when several threads call SetErrorMode() at the same time, only the first one should actually call this function to set the "1" error mode and only the last should revert the previous value. Otherwise it may happen that thread 1 obtains current error mode, then thread 2 obtains error mode (in this case always 1), then thread 1 sets error mode to its original value, then thread 2 sets error mode to what it thinks was its previous value (but it's 1 actually).

I think I have fixed those bugs in my libary, you may want to check it:

https://github.com/szymonwieloch/rust-dlopen/blob/master/src/raw/windows.rs

Publish a new version

I need this to update target_build_utils in Servo to not build serde 0.8 anymore.

dylib function that returns custom type when retrieved produces Segmentation Fault on macOS

macOS Sierra: 10.12.6 (16G29)

This issue references the issue created for rust-json

Sample Code is as follows:

Code for the dynamic library function is as follows:

#[macro_use]
extern crate json;

use json::JsonValue;

#[no_mangle]
pub fn methods() -> JsonValue
{
	let rt = array![
		object!{
			"fn" => "method 1"
    		}
	];
	rt
}

Code for my main.rs file is as follows:

extern crate json;
extern crate libloading as lib;

use std::env;
use json::JsonValue;

unsafe fn call_dynamic(libname: &String) -> lib::Result<()> {
	let dylib = try!(lib::Library::new(libname));
	let findmethods: lib::Symbol<fn() -> JsonValue> = dylib.get(b"methods")?;
	let funcs = findmethods();
	println!("{:#}", funcs);
	Ok(())
}

fn main(){
	let args: Vec<String> = env::args().collect();
	unsafe {
		call_dynamic(&args[1]).unwrap();
	}
}

Safe `Library::new()` can call any unsafe global constructors

This is unsound. It should be an unsafe function instead.

For example, this on x86_64-unknown-linux-gnu:

Cargo.toml:

[workspace]
members = ["evil", "loader"]

evil/Cargo.toml:

[package]
name = "evil"
version = "0.0.0"
edition = "2018"

[lib]
crate-type = ["cdylib"]

evil/src/lib.rs:

unsafe extern "C" fn evil() -> ! {
    std::hint::unreachable_unchecked()
}

#[link_section = ".init_array"]
#[used]
static EVIL: unsafe extern "C" fn() -> ! = evil;

loader/Cargo.toml:

[package]
name = "loader"
version = "0.0.0"
edition = "2018"

[dependencies]
libloading.git = "https://github.com/nagisa/rust_libloading.git"

loader/src/main.rs:

#![forbid(unsafe_code)]

use libloading::Library;

fn main() {
    let mut path = std::env::current_exe().unwrap();
    assert!(path.pop());
    path.push("libevil.so");
    Library::new(path).unwrap();
}

Triggers SIGILL (in debug mode) because std::hint::unreachable_unchecked() is called.

Backtrace
#0  core::hint::unreachable_unchecked ()
#1  0x00007ffff7fc2119 in evil::evil ()
#2  0x00007ffff7fe0b8a in ?? () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7fe0c91 in ?? () from /lib64/ld-linux-x86-64.so.2
#4  0x00007ffff7edb915 in __GI__dl_catch_exception (exception=<optimized out>, operate=<optimized out>, args=<optimized out>)
#5  0x00007ffff7fe50bf in ?? () from /lib64/ld-linux-x86-64.so.2
#6  0x00007ffff7edb8b8 in __GI__dl_catch_exception (exception=<optimized out>, operate=<optimized out>, args=<optimized out>)
#7  0x00007ffff7fe45fa in ?? () from /lib64/ld-linux-x86-64.so.2
#8  0x00007ffff7fa934c in dlopen_doit (a=a@entry=0x7fffffffd380)
#9  0x00007ffff7edb8b8 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffd320, operate=<optimized out>, args=<optimized out>)
#10 0x00007ffff7edb983 in __GI__dl_catch_error (objname=0x5555555a3ca0, errstring=0x5555555a3ca8, mallocedp=0x5555555a3c98, operate=<optimized out>, args=<optimized out>)
#11 0x00007ffff7fa9b59 in _dlerror_run (operate=operate@entry=0x7ffff7fa92f0 <dlopen_doit>, args=args@entry=0x7fffffffd380)
#12 0x00007ffff7fa93da in __dlopen (file=<optimized out>, mode=<optimized out>)
#13 0x000055555555a7f4 in libloading::os::unix::Library::open::{{closure}} ()
#14 0x000055555555a276 in libloading::os::unix::with_dlerror (
    wrap=0x55555555b2a0 <core::ops::function::FnOnce::call_once>, closure=...)
#15 0x000055555555a64f in libloading::os::unix::Library::open (filename=..., flags=2)
#16 0x000055555555a402 in libloading::os::unix::Library::new (filename=...)
#17 0x000055555555b52c in libloading::Library::new (filename=...)
#18 0x000055555555b618 in loader::main ()

Similarly, Library::new() calls the unsafe DllMain() on Windows.

Document unsafety of functions with 'static-containing return types.

Return values from functions that contain 'static lifetimes are not reduced to the lifetime of the loaded library, and can outlive it.
Preventing this is probably impossible (especially when the 'static is hidden inside a type like Wrapper(&'static u32)), but the docs could warn about it.

Here's one example that segfaults:

Cargo.toml:

[package]
name = "unsafe_libloading"
version = "0.0.0"

[lib]
path = "lib.rs"
name = "loadee"
crate-type = ["dylib"]

[[bin]]
name = "loader"
path = "main.rs"

[dependencies]
libloading = "0.5"

lib.rs:

#[no_mangle]
pub fn get_str() -> &'static str {
    "Hello, world"
}

main.rs:

extern crate libloading;

fn main() -> libloading::Result<()> {
    let lib = libloading::Library::new("libloadee.so")?;
    let return_value: &'static str = {
        let fun: libloading::Symbol<extern fn()->&'static str> = unsafe{ lib.get(b"get_str") }?;
        fun()
    };
    drop(lib);
    println!("return value: {}", return_value);
    Ok(())
}

I assume this issue also applies to loaded global variables, but dereferencing those produced bogus values even without dropping lib:

lib.rs:

#[no_mangle]
pub static REF: &'static u16 = &19;

main.rs:

extern crate libloading;

fn main() -> libloading::Result<()> {
    let lib = libloading::Library::new("libloadee.so")?;
    let var: libloading::Symbol<&'static u16> = unsafe{ lib.get(b"REF") }?;
    let dereferenced: u16 = **ref;
    println!("variable: {} = 0x{:x}", dereferenced, dereferenced);
    Ok(())
}

prints "variable: 27312 = 0x6ab0"

Loaded functions cannot be marked unsafe

Using this example:

extern crate libloading;

use libloading::{Library, Symbol};

fn main() {
    let lib = Library::new("libm.so.6").unwrap();
    let sin: Symbol<unsafe extern fn(f64) -> f64> = unsafe {
        lib.get(b"sin\0").unwrap()
    };

    let _a = unsafe { sin(4.5) };
}

I get this compilation output

src/main.rs:9:14: 9:33 warning: unnecessary `unsafe` block, #[warn(unused_unsafe)] on by default
src/main.rs:9     let _a = unsafe { sin(4.5) };
                           ^~~~~~~~~~~~~~~~~~~

But, I loaded a symbol unsafe extern fn(_), so I would expect using it to require an unsafe block.

(This example is trivial, but some FFI functions involving void* and varargs are totally unsafe and should be marked as such...)

Support for Android

Under unix you have code that handles most platforms but no Android. Note that Android uses bionic instead of glibc.
"ios" is also a platform that should probably have the same code as any unix implementation.
Is this support planned?

List available symbols, functions

Could libloading provide a way to query a library to get the list of available symbols and functions? I’m working on a basic mage port to Rust, and it would help if I could reflect over library entries rather than hardcode them.

As a workaround, I’m thinking of having my libraries adhere to a specific Rust trait, which would itself offer methods for registering and querying symbols and functions. But it would be cooler to do this dynamically rather than impose a structure on the plugins I use.

Multithreading?

I'm trying to use a dynamic library in a multi threading application.

However, I get the following errors:

within `lib::Library`, the trait `std::marker::Sync` is not implemented for `*mut std::os::raw::c_void`
within `lib::Library`, the trait `std::marker::Send` is not implemented for `*mut std::os::raw::c_void`

I can fix the first one by wrapping Library into a Mutex<>, but that's certainly not desirable for a multi threading application.

If after the Library has been initialized all threads only get read-only access to the Library, it should be thread safe.

Ideas?

(initially reported here: emoon/dynamic_reload#10)

drop() not called automatically on FreeBSD/ HardenedBSD

Making a long story short:

Library::open(Some(DEFAULT_LIBKVMPRO_SHARED), RTLD_NOW)
            .and_then(|lib| {
                let function_from_symbol: Symbol<extern "C" fn(uid_t) -> kvmpro_t> = unsafe { lib.get(b"get_process_usage_t\0") }?;
                let object: kvmpro_t = function_from_symbol(uid);
                mem::forget(lib);
                Ok(
                   String::from_utf8(object.bytes[0..object.length].to_vec()).unwrap_or("[]".to_string())
                )
            })
            .map_err(|err| {
                error!("FAILURE: processes_of_uid_short(): Unable to load shared library! Error: {:?}", err);
            })
            .unwrap_or("[]".to_string())

This code without that additional "mem::forget(lib);" call, will cause lib to not call drop, and cause a memleak.

For future generations :)

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.

[Question] How `libloading` find the DLL file when just giving a name?

When I use genet, it complains that wpcap.dll can not be found so Winpcap should be installed. But in my computer, Npcap is installed instead of Winpcap, however, they can not coexist. So I try to copy the required DLLs (wpcap.dll, usually Packet.dll should also be included) in the installation directory of genet.

However, it still complains "wpcap.dll is not found". After I dig into the source code, I find that genet use libloading to load the DLL in Windows just like this:

let lib = libloading::Library::new("Wpcap.dll").map_err(|_| super::Error::DLLNotFound)?;

I have a question here, how libloading find the DLL file when just given a name? What sequence? Thanks!

Allow altering search path - add LoadLibraryExW on Windows

We've got a scenario where we want to alter the search path of LoadLibrary, which is done via the flags passed to LoadLibraryExW.

For example, we would like to avoid searching the user's PATH for the library, and only search the application directory - which is the flag LOAD_LIBRARY_SEARCH_APPLICATION_DIR.

So this means adding another new function to the windows-specific module, which calls LoadLibraryExW, and allows passing flags. (Note they may be combined, so we can use the bitflags crate for that)

Relevant issues:
rust-windowing/glutin#1292
feenkcom/gtoolkit#973

SetThreadErrorMode not found in WindowsXP

I tried to run my rust binary on WindowsXP however when I use libloading I get an Error which says "SetThreadErrorMode" not found in "Kernel32.dll". In the docs I read the following:

Thread-safety
The implementation strives to be as MT-safe as sanely possible, however due to certain error-handling related resources not always being safe, this library is not MT-safe either.
On Windows Vista and earlier error handling falls back to SetErrorMode, which is not MT-safe. MT-scenarios involving this function may cause a traditional data race;

So I was hoping that SetErrorMode is used which is available on WindowsXP as far as I know.
Is there something I can do to make it work?

If you need more info just tell me
Thanks!

Consider removing C dependency for popular platforms

From reading #32, my understanding is that this C code is only really needed on some obscure platforms. Notably, modern windows, linux and mac all use thread safe dlerrors, and hence don't need global_static.c (but I have very clouded understanding of the original problem here, so I might be talking nonsense here).

It would be cool if that C code wasn't needed in such cases, by either detecting the target platform in build.rs, or by providing an explicit feature flag for the user.

The reason why I care about absence of C deps is that in rust-analyzer we've implemented a blanket check that the build does not call a C compiler. This is not a super-strong requirement, but it's nice to, eg, know that you can do cross compilation without futzing with C compilers.

cross-compile to armv7-unknown-linux-gnueabihf fails

I'm kind of new to cross-compiling with rust, but I managed to set up a foreign rust-std, and also a gcc cross-compiler for linking. It's all in cargo's config:

$ cat >>~/.cargo/config

[target.armv7-unknown-linux-gnueabihf]
linker = "armv7a-unknown-linux-gnueabihf"

how to reproduce:

git clone https://github.com/nagisa/rust_libloading.git
cd rust_libloading
cargo build --target=armv7-unknown-linux-gnueabihf

    Updating crates.io index
   Compiling cc v1.0.31
   Compiling libloading v0.5.0 (/tmp/rust_libloading)                                                                                                                                   
error: failed to run custom build command for `libloading v0.5.0 (/tmp/rust_libloading)`                                                                                                
process didn't exit successfully: `/tmp/rust_libloading/target/debug/build/libloading-a41fce1a7453006f/build-script-build` (exit code: 101)
--- stdout
cargo:rustc-link-lib=dl
TARGET = Some("armv7-unknown-linux-gnueabihf")
OPT_LEVEL = Some("0")
HOST = Some("x86_64-unknown-linux-gnu")
CC_armv7-unknown-linux-gnueabihf = None
CC_armv7_unknown_linux_gnueabihf = None
TARGET_CC = None
CC = None
CROSS_COMPILE = None
CFLAGS_armv7-unknown-linux-gnueabihf = None
CFLAGS_armv7_unknown_linux_gnueabihf = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some("true")
CARGO_CFG_TARGET_FEATURE = None
running: "arm-linux-gnueabihf-gcc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-march=armv7-a" "-Wall" "-Wextra" "-o" "/tmp/rust_libloading/target/armv7-unknown-linux-gnueabihf/debug/build/libloading-b5a400997b94cd58/out/src/os/unix/global_static.o" "-c" "src/os/unix/global_static.c"

--- stderr
thread 'main' panicked at '

Internal error occurred: Failed to find tool. Is `arm-linux-gnueabihf-gcc` installed?

', /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/cc-1.0.31/src/lib.rs:2367:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Worth mentioning somewhere that dynamically loadable rust crate has to be cdylib?

Just spent some time investigating why my rust dll wont load, turned out that I mistakenly put dylib as crate-type instead of cdylib

so inside Cargo.toml of library I had:

crate-type=["dylib", "rlib"]

In order for a library to be loadable this should have been:

crate-type=["cdylib", "rlib"]

Error that I was getting On windows:

Os { code: 126, kind: Other, message: "The specified module could not be found." }'
println!("result is: {:?}", libloading::Library::new(dll_path.clone()));

If readme wont be updated, this issue should serve enough as enough of a documentation.
Similar issue in rust-lang: rust-lang-issue

Difference between dylib and cdylib can be found on rust documentation here, as a summary:

cdylib - A dynamic system library will be produced
dylib - A dynamic Rust library will be produced.

SEGFAULT sometimes occurs when testing libloading code

Operating system is Fedora 27.

uname -r
4.15.4-300.fc27.x86_64

When running cargo test multiple times, sometimes test fails raising a segmentation fault.

#[test]
fn libloading() {
    let lib = libloading::Library::new("libdltest.so").unwrap();
    unsafe {
        let test_fn: libloading::Symbol<unsafe extern fn(i32) -> i32> = lib.get(b"test").unwrap();
        assert!(test_fn(100) == 200);
    }
}
test test::libloading ... error: process didn't exit successfully: `/home/User/test_libloading/target/debug/deps/test_libloading-b3311c80df7834fd libloading` (signal: 11, SIGSEGV: invalid memory reference)

But when this code runs in an executable crate, It seems to run without the segfault even when I execute it multiple times.

fn main() {
    let lib = libloading::Library::new("libdltest.so").unwrap();
    unsafe {
        let test_fn: libloading::Symbol<unsafe extern fn(i32) -> i32> = lib.get(b"test").unwrap();
        assert!(test_fn(100) == 200);
    }
}

Add generic export of os symbols

I'm using libloading in a work-in-progress large project; there's a part of the project's design which necessitates returning a raw os symbol. Unfortunately your library currently forces me to write the following:

#[cfg(not(windows))]
use libloading::os::unix::Symbol as LibSymbol;
#[cfg(windows)]
use libloading::os::windows::Symbol as LibSymbol;

Which is messier than I'd like. Could you please add a generic export of os symbols (i.e. ::os::raw::*) to provide a cleaner import of the os symbols, just like std does. Thanks :)

Can't build 0.5.2 on Arch

Has anyone come across this error before?

error: failed to run custom build command for `libloading v0.5.2 (/home/andrew/.cargo/registry/src/github.com-1ecc6299db9ec823/libloading-0.5.2)`                                 
                                                                                                                                            
Caused by:                                                                                                                                  
  process didn't exit successfully: `/home/andrew/.cargo/registry/src/github.com-1ecc6299db9ec823/libloading-0.5.2/target/debug/build/libloading-85f35561f240ae27/build-script-build` (exit code: 1)
--- stdout                                                                                                                                  
cargo:rustc-link-lib=dl                                                                                                                     
TARGET = Some("x86_64-unknown-linux-gnu")                                                                                                                                                                                                                                                
OPT_LEVEL = Some("0")                                                                                                                       
HOST = Some("x86_64-unknown-linux-gnu")           
CC_x86_64-unknown-linux-gnu = None                                                                                                                                                                                                                                                       
CC_x86_64_unknown_linux_gnu = None                                                                                                          
HOST_CC = None                                                                                                                              
CC = None                                                                                                                                   
CFLAGS_x86_64-unknown-linux-gnu = None
CFLAGS_x86_64_unknown_linux_gnu = None
HOST_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some("true")                                                                                                                                                                                                                                                                     CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")                                                                                            
running: "cc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-o" "/home/andrew/.cargo/registry/src/github.com-1ecc6299db9ec823/libloading-0.5.2/target/debug/build/libloading-2c731cff8e31125d/out/src/os/unix/global_sta
tic.o" "-c" "src/os/unix/global_static.c"
cargo:warning=src/os/unix/global_static.c:4:1: warning: data definition has no type or storage class
cargo:warning=    4 | pthread_mutex_t __attribute__((weak)) rust_libloading_dlerror_mutex = PTHREAD_MUTEX_INITIALIZER;                                                                                                                                                                   
cargo:warning=      | ^~~~~~~~~~~~~~~
cargo:warning=src/os/unix/global_static.c:4:1: warning: type defaults to ‘int’ in declaration of ‘pthread_mutex_t’ [-Wimplicit-int]
cargo:warning=src/os/unix/global_static.c:4:39: error: expected ‘,’ or ‘;’ before ‘rust_libloading_dlerror_mutex’
cargo:warning=    4 | pthread_mutex_t __attribute__((weak)) rust_libloading_dlerror_mutex = PTHREAD_MUTEX_INITIALIZER;
cargo:warning=      |                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cargo:warning=src/os/unix/global_static.c: In function ‘rust_libloading_dlerror_mutex_lock’:
cargo:warning=src/os/unix/global_static.c:9:9: warning: implicit declaration of function ‘pthread_mutex_lock’ [-Wimplicit-function-declaration]
cargo:warning=    9 |     if (pthread_mutex_lock(&rust_libloading_dlerror_mutex) != 0) {
cargo:warning=      |         ^~~~~~~~~~~~~~~~~~
cargo:warning=src/os/unix/global_static.c:9:29: error: ‘rust_libloading_dlerror_mutex’ undeclared (first use in this function); did you mean ‘rust_libloading_dlerror_mutex_lock’?
cargo:warning=    9 |     if (pthread_mutex_lock(&rust_libloading_dlerror_mutex) != 0) {
cargo:warning=      |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cargo:warning=      |                             rust_libloading_dlerror_mutex_lock
cargo:warning=src/os/unix/global_static.c:9:29: note: each undeclared identifier is reported only once for each function it appears in
cargo:warning=src/os/unix/global_static.c: In function ‘rust_libloading_dlerror_mutex_unlock’:
cargo:warning=src/os/unix/global_static.c:17:9: warning: implicit declaration of function ‘pthread_mutex_unlock’ [-Wimplicit-function-declaration]
cargo:warning=   17 |     if (pthread_mutex_unlock(&rust_libloading_dlerror_mutex) != 0) {
cargo:warning=      |         ^~~~~~~~~~~~~~~~~~~~
cargo:warning=src/os/unix/global_static.c:17:31: error: ‘rust_libloading_dlerror_mutex’ undeclared (first use in this function); did you mean ‘rust_libloading_dlerror_mutex_lock’?
cargo:warning=   17 |     if (pthread_mutex_unlock(&rust_libloading_dlerror_mutex) != 0) {
cargo:warning=      |                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cargo:warning=      |                               rust_libloading_dlerror_mutex_lock
exit code: 1

--- stderr

I'm getting this error when trying to build the ggez package, and when I manually navigate into ~/cargo/registry/src/github.com-1ecc6299db9ec823/libloading-0.5.2 and run cargo build

Thanks!

Fails to build with the `asmjs-unknown-emscripten` target

cargo build --target asmjs-unknown-emscripten gave me the following output :

   Compiling libloading v0.3.4
error: failed to run custom build command for `libloading v0.3.4`
process didn't exit successfully: `/home/yoon/git/trust/fate-rs/target/debug/build/libloading-b2c9bb378ef0f558/build-script-build` (exit code: 252)
--- stderr
Building for an unknown target_os=`emscripten`!
Please report an issue 

Build failed, waiting for other jobs to finish...
error: build failed

Admittedly, loading dynamic libraries in Emscripten makes little to no sense, so this should be expected - I ran into this when trying to build my test project which depends on al-sys from alto.
I'm wondering what the desired behavior would be here. My gut feeling is that libloading should still compile, but produce no-ops, but on the other hand, the actual fix would probably to set libloading as an optional dependency of al-sys.

Build script error while cross-compiling for Android

Hi,

my crate has a dependency on rust_libloading 0.5.1 and when cross-compiling for Android, I get the following error:

error: failed to run custom build command for `libloading v0.5.1`
process didn't exit successfully: `/home/aston/rust-keylock-android/rust/target/release/build/libloading-c12fda81b5e744cc/build-script-build` (exit code: 1)

--- stdout
...
...
...
--- stderr
error occurred: Command "/home/aston/rust-keylock-android/android-toolchain/bin/arm-linux-androideabi-gcc" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-m64" "-Wall" "-Wextra" "-o" "/home/aston/rust-keylock-android/rust/target/release/build/libloading-7b0f9f5769dc954d/out/src/os/unix/global_static.o" "-c" "src/os/unix/global_static.c" with args "arm-linux-androideabi-gcc" did not execute successfully (status code exit code: 1).

Using the 0.4.3 release there is not an issue, since only after 0.50 there is building of global_static.

Do I need to do something special to build global_static for Android? Can I do something to correct/avoid this error?

Support for dlmopen

dlmopen allows users to specify a namespace for shared libraries. Maybe a new wrapper at os::unix::Library::dlmopen can be provided for this case.

Integration with rust-bindgen

I'm trying to integrate with a rust-bindgen lib defined types.

Basically, extracting types from a .h file and generating rust types.

My types are generated like:

pub type CK_C_Initialize =
    ::std::option::Option<unsafe extern "C" fn(init_args:
                                                   *mut ::std::os::raw::c_void)
                              -> ::std::os::raw::c_ulong>;

Which is nice but really unpractical to use with libloading because writing:

let initialize: Symbol<pkcs11_sys::CK_C_Initialize> = unsafe {
  try!(self.lib.get(b"C_Initialize"))
};
initialize();

does not really work because:

error: expected function, found `libloading::Symbol<'_, std::option::Option<unsafe extern "C" fn(*mut std::os::raw::c_void) -> u64>>`
  --> src/lib.rs:42:5
   |
42 |     initialize();
   |     ^^^^^^^^^^^^
   |

I'm not sure how to extract the Symbol<Option<T>> to get a more useful type (something like Option<Symbol<T>> at very least).
I'm looking for suggestions or things I'm missing. I'd be happy to provide a pull request for this, feel free to give directions :).

How to use libloading with actix-web, please

How to use libloading to load the following 3 functions?

use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder};

#[get("/")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}

#[post("/echo")]
async fn echo(req_body: String) -> impl Responder {
    HttpResponse::Ok().body(req_body)
}

async fn manual_hello() -> impl Responder {
    HttpResponse::Ok().body("Hey there!")
}

Error running custom build command on macOS

Received this error building both from source and as a dependency in another cargo project
running macOS 10.13.6

error: failed to run custom build command for `libloading v0.5.0`
process didn't exit successfully: `/Users/aklempner/Repos/myrepo/target/debug/build/libloading-a9f7dca34ffe58d1/build-script-build` (exit code: 101)
--- stdout
TARGET = Some("x86_64-apple-darwin")
OPT_LEVEL = Some("0")
TARGET = Some("x86_64-apple-darwin")
HOST = Some("x86_64-apple-darwin")
TARGET = Some("x86_64-apple-darwin")
TARGET = Some("x86_64-apple-darwin")
HOST = Some("x86_64-apple-darwin")
CC_x86_64-apple-darwin = None
CC_x86_64_apple_darwin = None
HOST_CC = None
CC = None
HOST = Some("x86_64-apple-darwin")
TARGET = Some("x86_64-apple-darwin")
HOST = Some("x86_64-apple-darwin")
CFLAGS_x86_64-apple-darwin = None
CFLAGS_x86_64_apple_darwin = None
HOST_CFLAGS = None
CFLAGS = None
DEBUG = Some("true")
running: "cc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-m64" "-Wall" "-Wextra" "-o" "/Users/aklempner/Repos/myrepo/target/debug/build/libloading-3b419941d75fe8e6/out/src/os/unix/global_static.o" "-c" "src/os/unix/global_static.c"
cargo:warning=In file included from src/os/unix/global_static.c:1:
cargo:warning=/usr/include/pthread.h:226:66: error: unknown type name 'size_t'
cargo:warning=int pthread_attr_getguardsize(const pthread_attr_t * __restrict, size_t * __restrict);
cargo:warning=                                                                 ^
cargo:warning=/usr/include/pthread.h:243:43: error: unknown type name 'size_t'
cargo:warning=                void * _Nullable * _Nonnull __restrict, size_t * __restrict);
cargo:warning=                                                        ^
cargo:warning=/usr/include/pthread.h:250:66: error: unknown type name 'size_t'
cargo:warning=int pthread_attr_getstacksize(const pthread_attr_t * __restrict, size_t * __restrict);
cargo:warning=                                                                 ^
cargo:warning=/usr/include/pthread.h:511:1: error: unknown type name 'size_t'
cargo:warning=size_t pthread_get_stacksize_np(pthread_t);
cargo:warning=^
cargo:warning=4 errors generated.
exit code: 1

--- stderr
thread 'main' panicked at '

Internal error occurred: Command "cc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-m64" "-Wall" "-Wextra" "-o" "/Users/aklempner/Repos/myrepo/target/debug/build/libloading-3b419941d75fe8e6/out/src/os/unix/global_static.o" "-c" "src/os/unix/global_static.c" with args "cc" did not execute successfully (status code exit code: 1).

', /Users/aklempner/.cargo/registry/src/github.com-1ecc6299db9ec823/cc-1.0.18/src/lib.rs:2181:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

warning: build failed, waiting for other jobs to finish...
error: build failed

Unwanted `println!` debug print?

I'm using glutin crate, and it depends indirectly on libloading.
cargo update updates libloading-0.3.2 to 0.3.3, and then 47 lines of "8" is printed to stdout...

screenshot-2017-03-25-154855 0900

The problem doesn't happen on libloading-0.3.2 and I think this change might be the cause.

Is this println! necessary?
I'm happy if this println would be removed, or moved inside of the following if block (with more verbose message and stderr destination).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.