diff --git a/Cargo.toml b/Cargo.toml index 5ea2fec..b4d3b66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,11 @@ maintenance = { status = "actively-developed" } [dependencies] libc = "0.2" +log = "0.4" spin = "0.4" thread-id = "3.3" -qadapt-macro = { version = "0.7.0", path = "./qadapt-macro" } \ No newline at end of file +qadapt-macro = { version = "0.7.0", path = "./qadapt-macro" } + +[dev-dependencies] +env_logger = "0.6" \ No newline at end of file diff --git a/examples/release_mode.rs b/examples/release_mode.rs index 50bff3e..a184e07 100644 --- a/examples/release_mode.rs +++ b/examples/release_mode.rs @@ -14,6 +14,7 @@ fn does_allocate() -> Box { fn main() { // If you were to run `cargo run --example release_mode`, this program blows up. // If, however, you ran `cargo run --release --example release_mode`, - // nothing interesting will happen. + // nothing interesting will happen since panic-related code is stripped + // for release builds. does_allocate(); } diff --git a/examples/setup_warning.rs b/examples/setup_warning.rs new file mode 100644 index 0000000..e1684b1 --- /dev/null +++ b/examples/setup_warning.rs @@ -0,0 +1,21 @@ +extern crate env_logger; +extern crate qadapt; + +use qadapt::allocate_panic; + +// Note that we're missing the `#[global_allocator]` attribute + +#[allocate_panic] +fn does_allocate() -> Box { + Box::new(0) +} + +fn main() { + // This code will warn that QADAPT isn't being used, but won't trigger a panic. + // Run with `RUST_LOG=warn cargo run --example setup_warning` + env_logger::init(); + does_allocate(); + + // The warning will only trigger once though + does_allocate(); +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 4a2abad..b11062e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,8 @@ //! for some helper macros to make working with QADAPT a bit easier. #![deny(missing_docs)] extern crate libc; +#[macro_use] +extern crate log; extern crate qadapt_macro; extern crate spin; // thread_id is necessary because `std::thread::current()` panics if we have not yet @@ -45,6 +47,11 @@ pub fn enter_protected() { return; } + if *IS_ACTIVE.read() == false { + *IS_ACTIVE.write() = true; + warn!("QADAPT not initialized when using allocation guards; please verify `#[global_allocator]` is set!"); + } + PROTECTION_LEVEL .try_with(|v| { *v.write() += 1; @@ -76,6 +83,7 @@ pub fn exit_protected() { } } +static IS_ACTIVE: RwLock = RwLock::new(false); static INTERNAL_ALLOCATION: RwLock = RwLock::new(usize::max_value()); /// Get the current "protection level" in QADAPT: calls to enter_protected() - exit_protected() @@ -115,6 +123,10 @@ fn alloc_immediate() -> bool { unsafe impl GlobalAlloc for QADAPT { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + if *IS_ACTIVE.read() == false { + *IS_ACTIVE.write() = true; + } + // If we're attempting to allocate our PROTECTION_LEVEL thread local, // just allow it through if alloc_immediate() {