-
Notifications
You must be signed in to change notification settings - Fork 480
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
Memory Leak in crossbeam-queue ArrayQueue? (Latest git only, ver0.2.3 is not effected) #539
Comments
Yes, I just realized that the changes in #500 are not correct in terms of equivalence compared to the original code behavior. The PR (#500) replaces: let mut v = Vec::<Slot<T>>::with_capacity(cap); with let mut v: Vec<Slot<T>> = (0..cap)
.map(|i| {
// Set the stamp to `{ lap: 0, mark: 0, index: i }`.
Slot {
stamp: AtomicUsize::new(i),
msg: UnsafeCell::new(MaybeUninit::uninit()),
}
})
.collect(); The latter does not exactly allocate [1]: crossbeam/crossbeam-queue/src/array_queue.rs Lines 426 to 429 in 5a68889
|
@caelunshun Ah I didn't see that PR.
The std doc says: "The vector will be able to hold exactly capacity elements without reallocating. If capacity is 0, the vector will not allocate.". Ährm, doesn't that kinda say that the capacity of the Vec will be exactly |
Ah, looks like I was mistaken there. You're right, then; this issue was introduced in #500. |
@caelunshun Mhh. Maybe a simpler fix for #500 would have been something like: // Instead of
let mut v = Vec::<Slot<T>>::with_capacity(cap);
// do this
let mut v = Vec::<MaybeUninit<Slot<T>>>::with_capacity(cap); So that the actual initialization loop can be preserved. |
Hi @cynecx, @caelunshun. Thank you for the quick response. I'll merge #533 into my fork and see if I can find more interesting issues. Thank you for the help! |
Impact The affected version of this crate's the bounded channel incorrectly assumes that Vec::from_iter has allocated capacity that same as the number of iterator elements. Vec::from_iter does not actually guarantee that and may allocate extra memory. The destructor of the bounded channel reconstructs Vec from the raw pointer based on the incorrect assumes described above. This is unsound and causing deallocation with the incorrect capacity when Vec::from_iter has allocated different sizes with the number of iterator elements. Patches This has been fixed in crossbeam-channel 0.4.4. We recommend users to upgrade to 0.4.4. References See crossbeam-rs/crossbeam#533, crossbeam-rs/crossbeam#539, and rustsec/advisory-db#425 for more details.
Impact The affected version of this crate's the bounded channel incorrectly assumes that Vec::from_iter has allocated capacity that same as the number of iterator elements. Vec::from_iter does not actually guarantee that and may allocate extra memory. The destructor of the bounded channel reconstructs Vec from the raw pointer based on the incorrect assumes described above. This is unsound and causing deallocation with the incorrect capacity when Vec::from_iter has allocated different sizes with the number of iterator elements. Patches This has been fixed in crossbeam-channel 0.4.4. We recommend users to upgrade to 0.4.4. References See crossbeam-rs/crossbeam#533, crossbeam-rs/crossbeam#539, and rustsec/advisory-db#425 for more details.
Impact The affected version of this crate's the bounded channel incorrectly assumes that Vec::from_iter has allocated capacity that same as the number of iterator elements. Vec::from_iter does not actually guarantee that and may allocate extra memory. The destructor of the bounded channel reconstructs Vec from the raw pointer based on the incorrect assumes described above. This is unsound and causing deallocation with the incorrect capacity when Vec::from_iter has allocated different sizes with the number of iterator elements. Patches This has been fixed in crossbeam-channel 0.4.4. We recommend users to upgrade to 0.4.4. References See crossbeam-rs/crossbeam#533, crossbeam-rs/crossbeam#539, and rustsec/advisory-db#425 for more details.
Impact The affected version of this crate's the bounded channel incorrectly assumes that Vec::from_iter has allocated capacity that same as the number of iterator elements. Vec::from_iter does not actually guarantee that and may allocate extra memory. The destructor of the bounded channel reconstructs Vec from the raw pointer based on the incorrect assumes described above. This is unsound and causing deallocation with the incorrect capacity when Vec::from_iter has allocated different sizes with the number of iterator elements. Patches This has been fixed in crossbeam-channel 0.4.4. We recommend users to upgrade to 0.4.4. References See crossbeam-rs/crossbeam#533, crossbeam-rs/crossbeam#539, and rustsec/advisory-db#425 for more details.
Hi.
I'm Yoshi, a PhD student at CMU. We are currently evaluating a project that aims to automatically synthesize test cases for Rust libraries.
We ran the synthesized test cases with Miri, and it reports what appears to be a memory leak. The minimum example is:
It looks like the drop destructor is not erasing enough memory.
You can also catch this with by running
cargo miri test
inside crossbeam-queue. One of your manually written test cases (capacity
) will induce the same behavior.The first commit to have this issue is 2180b820c846e5e6f2f11ccd1238198a5861dc08. You can confirm this by running
cargo miri test
on 1 commit before. It will not terminate because Miri is extremely slow, but you can see that it gets pastcapacity
test case.As for the root cause, I suspect that the drop function needs to be modified to match the changes to
new
, but I am yet to get a PR up.In case this is intended behavior, or you would prefer if I focused on other parts of the code, please let me know.
Thanks
~Yoshi
The text was updated successfully, but these errors were encountered: