From 547841a3e287c96e734532114bf5d7cfb7d4a29c Mon Sep 17 00:00:00 2001 From: Dan Burkert Date: Sat, 9 Sep 2017 10:52:17 -0700 Subject: [PATCH] Compile lmdb with opt level O2 LMDB segfaults reliably with newer GCC versions when compiled with O3. Regression test included. fixes #21 --- .travis.yml | 1 + Cargo.toml | 1 + lmdb-sys/Cargo.toml | 3 ++- lmdb-sys/build.rs | 16 ++++++---------- src/lib.rs | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2526a2c..d9212d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,4 +17,5 @@ script: - cargo build --verbose - if [[ $TRAVIS_RUST_VERSION = nightly* ]]; then env RUST_BACKTRACE=1 cargo test --all -v; + env RUST_BACKTRACE=1 cargo test --all -v --release; fi diff --git a/Cargo.toml b/Cargo.toml index 6d802aa..df3d8fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,3 +25,4 @@ lmdb-sys = { path = "lmdb-sys" } [dev-dependencies] rand = "0.3" tempdir = "0.3" +byteorder = "1.0" diff --git a/lmdb-sys/Cargo.toml b/lmdb-sys/Cargo.toml index 79300a1..5a8dd4e 100644 --- a/lmdb-sys/Cargo.toml +++ b/lmdb-sys/Cargo.toml @@ -20,4 +20,5 @@ libc = "0.2" [build-dependencies] pkg-config = "0.3" -gcc = "0.3" +# https://github.com/alexcrichton/gcc-rs/issues/240 +gcc = "=0.3.51" diff --git a/lmdb-sys/build.rs b/lmdb-sys/build.rs index 36332d5..fd9e98e 100644 --- a/lmdb-sys/build.rs +++ b/lmdb-sys/build.rs @@ -5,21 +5,17 @@ use std::env; use std::path::PathBuf; fn main() { - let mut lmdb: PathBuf = PathBuf::from(&env::var("CARGO_MANIFEST_DIR").unwrap()); lmdb.push("lmdb"); lmdb.push("libraries"); lmdb.push("liblmdb"); - let mut mdb: PathBuf = lmdb.clone(); - let mut midl: PathBuf = lmdb.clone(); - - mdb.push("mdb.c"); - midl.push("midl.c"); - if !pkg_config::find_library("liblmdb").is_ok() { - gcc::compile_library("liblmdb.a", - &[(*mdb).to_str().unwrap(), - (*midl).to_str().unwrap()]); + gcc::Config::new() + .file(lmdb.join("mdb.c")) + .file(lmdb.join("midl.c")) + // https://github.com/LMDB/lmdb/blob/LMDB_0.9.21/libraries/liblmdb/Makefile#L25 + .opt_level(2) + .compile("liblmdb.a") } } diff --git a/src/lib.rs b/src/lib.rs index 3fe40b4..e54d2dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,6 +62,9 @@ mod transaction; #[cfg(test)] mod test_utils { + extern crate byteorder; + + use self::byteorder::{ByteOrder, LittleEndian}; use tempdir::TempDir; use super::*; @@ -88,4 +91,33 @@ mod test_utils { } (dir, env) } + + /// Regression test for https://github.com/danburkert/lmdb-rs/issues/21. + /// This test reliably segfaults when run against lmbdb compiled with opt level -O3 and newer + /// GCC compilers. + #[test] + fn issue_21_regression() { + const HEIGHT_KEY: [u8; 1] = [0]; + + let dir = TempDir::new("test").unwrap(); + + let env = { + let mut builder = Environment::new(); + builder.set_max_dbs(2); + builder.set_map_size(1_000_000); + builder.open(dir.path()).expect("open lmdb env") + }; + let index = env.create_db(None, DUP_SORT).expect("open index db"); + + for height in 0..1000 { + let mut value = [0u8; 8]; + LittleEndian::write_u64(&mut value, height); + let mut tx = env.begin_rw_txn().expect("begin_rw_txn"); + tx.put(index, + &HEIGHT_KEY, + &value, + WriteFlags::empty()).expect("tx.put"); + tx.commit().expect("ts.commit") + } + } }