Skip to content

Commit a812c8b

Browse files
committed
use RTLD_DEEPBIND for library loading on unix platform
- see [this](fedochet/rust-proc-macro-panic-inside-panic-expample#1) issue for the details - use nightly for tests
1 parent ed06c31 commit a812c8b

File tree

4 files changed

+31
-9
lines changed

4 files changed

+31
-9
lines changed

.travis.yml

+1-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ os:
66
- windows
77
language: rust
88
rust:
9-
- nightly-2019-04-01
10-
before_install:
11-
- rustup install stable
9+
- nightly
1210
deploy:
1311
provider: releases
1412
api_key:

azure-pipelines.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ steps:
2525
echo "##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin"
2626
displayName: Windows install rust
2727
condition: eq( variables['Agent.OS'], 'Windows_NT' )
28-
- script: rustup install nightly-2019-04-01
29-
displayName: Install nightly-2019-04-01
30-
- script: cargo +nightly-2019-04-01 build --all
28+
- script: rustup install nightly
29+
displayName: Install nightly
30+
- script: cargo +nightly build --all
3131
displayName: Cargo build
3232
env: { RUSTFLAGS: "--cfg procmacro2_semver_exempt" }
33-
- script: cargo +nightly-2019-04-01 test --all -- --nocapture
33+
- script: cargo +nightly test --all -- --nocapture
3434
displayName: Cargo test
3535
env: {
3636
RUSTFLAGS: "--cfg procmacro2_semver_exempt",

src/lib.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,30 @@ fn find_registrar_symbol(file: &Path) -> Option<String> {
8989
.map(|s| s.to_string())
9090
}
9191

92+
/// Loads dynamic library in platform dependent manner.
93+
///
94+
/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described
95+
/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample)
96+
/// and [here](https://github.com/rust-lang/rust/issues/60593).
97+
///
98+
/// Usage of RTLD_DEEPBIND is suggested by @edwin0cheng
99+
/// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1)
100+
///
101+
/// It seems that on Windows that behaviour is default, so we do nothing in that case.
102+
fn load_library(file: &Path) -> Result<Library, std::io::Error> {
103+
if cfg!(target_os = "windows") {
104+
Library::new(file)
105+
} else {
106+
use std::os::raw::c_int;
107+
use libloading::os::unix::Library as UnixLibrary;
108+
109+
const RTLD_NOW: c_int = 0x00002;
110+
const RTLD_DEEPBIND: c_int = 0x00008;
111+
112+
UnixLibrary::open(Some(file), RTLD_NOW | RTLD_DEEPBIND).map(|lib| lib.into())
113+
}
114+
}
115+
92116
struct ProcMacroLibraryLibloading {
93117
lib: Library,
94118
exported_macros: Vec<ProcMacro>,
@@ -99,7 +123,7 @@ impl ProcMacroLibraryLibloading {
99123
let symbol_name = find_registrar_symbol(file)
100124
.ok_or(format!("Cannot find registrar symbol in file {:?}", file))?;
101125

102-
let lib = Library::new(file).map_err(|e| e.to_string())?;
126+
let lib = load_library(file).map_err(|e| e.to_string())?;
103127

104128
let exported_macros = {
105129
let macros: libloading::Symbol<&&[ProcMacro]> = unsafe { lib.get(symbol_name.as_bytes()) }

tests/expansion_correctness_tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ static DYLIB_NAME_PREFIX: &str = "";
116116
fn compile_proc_macro(dir: &Path, proc_macro_name: &str) -> io::Result<PathBuf> {
117117
Command::new("cargo")
118118
.current_dir(dir)
119-
.arg("+stable")
119+
.arg("+nightly")
120120
.arg("build")
121121
.arg("-p").arg(proc_macro_name)
122122
.status()?;

0 commit comments

Comments
 (0)