Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Library test map::test_map::test_clone_from_memory_leaks errors with using uninitialized data under valgrind and miri #510

Closed
udoprog opened this issue Mar 7, 2024 · 0 comments · Fixed by #511

Comments

@udoprog
Copy link
Contributor

udoprog commented Mar 7, 2024

Steps to reproduce:

cargo test --lib

Find the resulting test binary and run it through valgrind:

valgrind target/debug/deps/hashbrown-e06c00d15197ef31 --exact map::test_map::test_clone_from_memory_leaks

This is what I get:

Valgrind error
==132117== Thread 9 map::test_map:::
==132117== Conditional jump or move depends on uninitialised value(s)
==132117==    at 0x139B47: alloc::raw_vec::RawVec<T,A>::current_memory (raw_vec.rs:256)
==132117==    by 0x1346DA: <alloc::raw_vec::RawVec<T,A> as core::ops::drop::Drop>::drop (raw_vec.rs:530)
==132117==    by 0x131AC9: core::ptr::drop_in_place<alloc::raw_vec::RawVec<i32>> (mod.rs:507)
==132117==    by 0x1318AA: core::ptr::drop_in_place<alloc::vec::Vec<i32>> (mod.rs:507)
==132117==    by 0x132749: core::ptr::drop_in_place<hashbrown::map::test_map::test_clone_from_memory_leaks::CheckedClone> (mod.rs:507)
==132117==    by 0x1302CD: core::ptr::drop_in_place<(i32,hashbrown::map::test_map::test_clone_from_memory_leaks::CheckedClone)> (mod.rs:507)
==132117==    by 0x178D4A: drop_in_place<(i32, hashbrown::map::test_map::test_clone_from_memory_leaks::CheckedClone)> (mut_ptr.rs:1469)
==132117==    by 0x178D4A: hashbrown::raw::Bucket<T>::drop (mod.rs:590)
==132117==    by 0x1CBE07: hashbrown::raw::RawTable<T,A>::clone_from_impl::{{closure}} (mod.rs:3587)
==132117==    by 0x135531: <hashbrown::scopeguard::ScopeGuard<T,F> as core::ops::drop::Drop>::drop (scopeguard.rs:70)
==132117==    by 0x1313D9: core::ptr::drop_in_place<hashbrown::scopeguard::ScopeGuard<(usize,&mut hashbrown::raw::RawTable<(i32,hashbrown::map::test_map::test_clone_from_memory_leaks::CheckedClone)>),hashbrown::raw::RawTable<(i32,hashbrown::map::test_map::test_clone_from_memory_leaks::CheckedClone)>::clone_from_impl::{{closure}}>> (mod.rs:507)
==132117==    by 0x1CB124: hashbrown::raw::RawTable<T,A>::clone_from_impl (mod.rs:3607)
==132117==    by 0x1D4532: <hashbrown::raw::RawTable<T,A> as hashbrown::raw::RawTableClone>::clone_from_spec (mod.rs:3545)
==132117== 

Miri also fails:

cargo +nightly miri test map::test_map::test_clone_from_memory_leaks
MIRI error
test map::test_map::test_clone_from_memory_leaks - should panic ... error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
    --> /home/udoprog/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/raw_vec.rs:235:9
     |
235  |         self.ptr.as_ptr()
     |         ^^^^^^^^ using uninitialized data, but this operation requires initialized memory
     |
     = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
     = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
     = note: BACKTRACE on thread `map::test_map::`:
     = note: inside `alloc::raw_vec::RawVec::<i32>::ptr` at /home/udoprog/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/raw_vec.rs:235:9: 235:17
     = note: inside `std::vec::Vec::<i32>::as_mut_ptr` at /home/udoprog/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:1331:9: 1331:23
     = note: inside `<std::vec::Vec<i32> as core::ops::Drop>::drop` at /home/udoprog/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:3171:62: 3171:79
     = note: inside `core::ptr::drop_in_place::<std::vec::Vec<i32>> - shim(Some(std::vec::Vec<i32>))` at /home/udoprog/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:515:1: 515:56
     = note: inside `core::ptr::drop_in_place::<map::test_map::test_clone_from_memory_leaks::CheckedClone> - shim(Some(map::test_map::test_clone_from_memory_leaks::CheckedClone))` at /home/udoprog/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:515:1: 515:56
     = note: inside `core::ptr::drop_in_place::<(i32, map::test_map::test_clone_from_memory_leaks::CheckedClone)> - shim(Some((i32, map::test_map::test_clone_from_memory_leaks::CheckedClone)))` at /home/udoprog/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:515:1: 515:56
     = note: inside `core::ptr::mut_ptr::<impl *mut (i32, map::test_map::test_clone_from_memory_leaks::CheckedClone)>::drop_in_place` at /home/udoprog/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mut_ptr.rs:1473:18: 1473:37
note: inside `raw::Bucket::<(i32, map::test_map::test_clone_from_memory_leaks::CheckedClone)>::drop`
    --> src/raw/mod.rs:590:9
     |
590  |         self.as_ptr().drop_in_place();
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside closure
    --> src/raw/mod.rs:3587:25
     |
3587 |                         self_.bucket(i).drop();
     |                         ^^^^^^^^^^^^^^^^^^^^^^
note: inside `<scopeguard::ScopeGuard<(usize, &mut raw::RawTable<(i32, map::test_map::test_clone_from_memory_leaks::CheckedClone)>), {closure@src/raw/mod.rs:3583:48: 3583:64}> as core::ops::Drop>::drop`
    --> src/scopeguard.rs:70:9
     |
70   |         (self.dropfn)(&mut self.value);
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     = note: inside `core::ptr::drop_in_place::<scopeguard::ScopeGuard<(usize, &mut raw::RawTable<(i32, map::test_map::test_clone_from_memory_leaks::CheckedClone)>), {closure@src/raw/mod.rs:3583:48: 3583:64}>> - shim(Some(scopeguard::ScopeGuard<(usize, &mut raw::RawTable<(i32, map::test_map::test_clone_from_memory_leaks::CheckedClone)>), {closure@src/raw/mod.rs:3583:48: 3583:64}>))` at /home/udoprog/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:515:1: 515:56
note: inside `raw::RawTable::<(i32, map::test_map::test_clone_from_memory_leaks::CheckedClone)>::clone_from_impl`
    --> src/raw/mod.rs:3607:5
     |
3607 |     }
     |     ^
note: inside `<raw::RawTable<(i32, map::test_map::test_clone_from_memory_leaks::CheckedClone)> as raw::RawTableClone>::clone_from_spec`
    --> src/raw/mod.rs:3545:13
     |
3545 |             self.clone_from_impl(source);
     |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `<raw::RawTable<(i32, map::test_map::test_clone_from_memory_leaks::CheckedClone)> as core::clone::Clone>::clone`
    --> src/raw/mod.rs:3464:17
     |
3464 |                 new_table.clone_from_spec(self);
     |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `<map::HashMap<i32, map::test_map::test_clone_from_memory_leaks::CheckedClone> as core::clone::Clone>::clone`
    --> src/map.rs:199:20
     |
199  |             table: self.table.clone(),
     |                    ^^^^^^^^^^^^^^^^^^
note: inside `map::test_map::test_clone_from_memory_leaks`
    --> src/map.rs:8566:21
     |
8566 |         let _map2 = map1.clone();
     |                     ^^^^^^^^^^^^
note: inside closure
    --> src/map.rs:8526:38
     |
8524 |     #[test]
     |     ------- in this procedural macro expansion
8525 |     #[should_panic = "panic in clone"]
8526 |     fn test_clone_from_memory_leaks() {
     |                                      ^
     = note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)

I've encountered memory corruption in tests of a fork of hashbrown which might or might not be related. While trying to track down the root cause I noted that the above was also present here. I've not investigated deeper but the test case itself is implemented without unsafe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant