-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
[Merged by Bors] - fix some memory leaks detected by miri #4959
Conversation
Can we get that command added to somewhere in the docs? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM on the fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good eye. Nice to see miri catching these problems for us.
bors r+
remove `-Zmiri-ignore-leaks` from CI args and fix leaks that miri detects. The first leak: ```rust #[test] fn blob_vec_drop_empty_capacity() { let item_layout = Layout::new::<Foo>(); let drop = drop_ptr::<Foo>; let _ = unsafe { BlobVec::new(item_layout, Some(drop), 0) }; } ``` this is because we allocate the swap scratch in blobvec regardless of what the capacity is, but we only deallocate if capacity is > 0 The second leak: ```rust #[test] fn panic_while_overwriting_component() { let helper = DropTestHelper::new(); let res = panic::catch_unwind(|| { let mut world = World::new(); world .spawn() .insert(helper.make_component(true, 0)) .insert(helper.make_component(false, 1)); println!("Done inserting! Dropping world..."); }); let drop_log = helper.finish(res); assert_eq!( &*drop_log, [ DropLogItem::Create(0), DropLogItem::Create(1), DropLogItem::Drop(0), ] ); } ``` this is caused by us not running the drop impl on the to-be-inserted component if the drop impl of the overwritten component panics --- managed to figure out where the leaks were by using this 10/10 command ``` cargo --quiet test --lib -- --list | sed 's/: test$//' | MIRIFLAGS="-Zmiri-disable-isolation" xargs -n1 cargo miri test --lib -- --exact ``` which runs every test one by one rather than all at once which let miri actually tell me which test had the leak :upside_down_face:
Build failed: |
Looks like there's a warning that should be ignored? |
bors retry |
remove `-Zmiri-ignore-leaks` from CI args and fix leaks that miri detects. The first leak: ```rust #[test] fn blob_vec_drop_empty_capacity() { let item_layout = Layout::new::<Foo>(); let drop = drop_ptr::<Foo>; let _ = unsafe { BlobVec::new(item_layout, Some(drop), 0) }; } ``` this is because we allocate the swap scratch in blobvec regardless of what the capacity is, but we only deallocate if capacity is > 0 The second leak: ```rust #[test] fn panic_while_overwriting_component() { let helper = DropTestHelper::new(); let res = panic::catch_unwind(|| { let mut world = World::new(); world .spawn() .insert(helper.make_component(true, 0)) .insert(helper.make_component(false, 1)); println!("Done inserting! Dropping world..."); }); let drop_log = helper.finish(res); assert_eq!( &*drop_log, [ DropLogItem::Create(0), DropLogItem::Create(1), DropLogItem::Drop(0), ] ); } ``` this is caused by us not running the drop impl on the to-be-inserted component if the drop impl of the overwritten component panics --- managed to figure out where the leaks were by using this 10/10 command ``` cargo --quiet test --lib -- --list | sed 's/: test$//' | MIRIFLAGS="-Zmiri-disable-isolation" xargs -n1 cargo miri test --lib -- --exact ``` which runs every test one by one rather than all at once which let miri actually tell me which test had the leak :upside_down_face:
Build failed: |
22dcb40
to
960a7a8
Compare
-Zmiri-ignore-leaks
from miri CI job
bors r+ |
The first leak: ```rust #[test] fn blob_vec_drop_empty_capacity() { let item_layout = Layout::new::<Foo>(); let drop = drop_ptr::<Foo>; let _ = unsafe { BlobVec::new(item_layout, Some(drop), 0) }; } ``` this is because we allocate the swap scratch in blobvec regardless of what the capacity is, but we only deallocate if capacity is > 0 The second leak: ```rust #[test] fn panic_while_overwriting_component() { let helper = DropTestHelper::new(); let res = panic::catch_unwind(|| { let mut world = World::new(); world .spawn() .insert(helper.make_component(true, 0)) .insert(helper.make_component(false, 1)); println!("Done inserting! Dropping world..."); }); let drop_log = helper.finish(res); assert_eq!( &*drop_log, [ DropLogItem::Create(0), DropLogItem::Create(1), DropLogItem::Drop(0), ] ); } ``` this is caused by us not running the drop impl on the to-be-inserted component if the drop impl of the overwritten component panics --- managed to figure out where the leaks were by using this 10/10 command ``` cargo --quiet test --lib -- --list | sed 's/: test$//' | MIRIFLAGS="-Zmiri-disable-isolation" xargs -n1 cargo miri test --lib -- --exact ``` which runs every test one by one rather than all at once which let miri actually tell me which test had the leak :upside_down_face:
# Objective When `miri` runs in our build system to detect unsoundness, its output can be very unhelpful, as the tests are all run in parallel. ## Solution Add a comment documenting the extremely obvious 10/10 command used by @BoxyUwU in #4959. I've stuck this in the CI file, as it seems like the most obvious place to check when frustrated. I didn't put it in CONTRIBUTING.md because this is an eldritch abomination and will never be useful to new contributors.
The first leak: ```rust #[test] fn blob_vec_drop_empty_capacity() { let item_layout = Layout::new::<Foo>(); let drop = drop_ptr::<Foo>; let _ = unsafe { BlobVec::new(item_layout, Some(drop), 0) }; } ``` this is because we allocate the swap scratch in blobvec regardless of what the capacity is, but we only deallocate if capacity is > 0 The second leak: ```rust #[test] fn panic_while_overwriting_component() { let helper = DropTestHelper::new(); let res = panic::catch_unwind(|| { let mut world = World::new(); world .spawn() .insert(helper.make_component(true, 0)) .insert(helper.make_component(false, 1)); println!("Done inserting! Dropping world..."); }); let drop_log = helper.finish(res); assert_eq!( &*drop_log, [ DropLogItem::Create(0), DropLogItem::Create(1), DropLogItem::Drop(0), ] ); } ``` this is caused by us not running the drop impl on the to-be-inserted component if the drop impl of the overwritten component panics --- managed to figure out where the leaks were by using this 10/10 command ``` cargo --quiet test --lib -- --list | sed 's/: test$//' | MIRIFLAGS="-Zmiri-disable-isolation" xargs -n1 cargo miri test --lib -- --exact ``` which runs every test one by one rather than all at once which let miri actually tell me which test had the leak :upside_down_face:
# Objective When `miri` runs in our build system to detect unsoundness, its output can be very unhelpful, as the tests are all run in parallel. ## Solution Add a comment documenting the extremely obvious 10/10 command used by @BoxyUwU in bevyengine#4959. I've stuck this in the CI file, as it seems like the most obvious place to check when frustrated. I didn't put it in CONTRIBUTING.md because this is an eldritch abomination and will never be useful to new contributors.
The first leak: ```rust #[test] fn blob_vec_drop_empty_capacity() { let item_layout = Layout::new::<Foo>(); let drop = drop_ptr::<Foo>; let _ = unsafe { BlobVec::new(item_layout, Some(drop), 0) }; } ``` this is because we allocate the swap scratch in blobvec regardless of what the capacity is, but we only deallocate if capacity is > 0 The second leak: ```rust #[test] fn panic_while_overwriting_component() { let helper = DropTestHelper::new(); let res = panic::catch_unwind(|| { let mut world = World::new(); world .spawn() .insert(helper.make_component(true, 0)) .insert(helper.make_component(false, 1)); println!("Done inserting! Dropping world..."); }); let drop_log = helper.finish(res); assert_eq!( &*drop_log, [ DropLogItem::Create(0), DropLogItem::Create(1), DropLogItem::Drop(0), ] ); } ``` this is caused by us not running the drop impl on the to-be-inserted component if the drop impl of the overwritten component panics --- managed to figure out where the leaks were by using this 10/10 command ``` cargo --quiet test --lib -- --list | sed 's/: test$//' | MIRIFLAGS="-Zmiri-disable-isolation" xargs -n1 cargo miri test --lib -- --exact ``` which runs every test one by one rather than all at once which let miri actually tell me which test had the leak :upside_down_face:
# Objective When `miri` runs in our build system to detect unsoundness, its output can be very unhelpful, as the tests are all run in parallel. ## Solution Add a comment documenting the extremely obvious 10/10 command used by @BoxyUwU in bevyengine#4959. I've stuck this in the CI file, as it seems like the most obvious place to check when frustrated. I didn't put it in CONTRIBUTING.md because this is an eldritch abomination and will never be useful to new contributors.
The first leak: ```rust #[test] fn blob_vec_drop_empty_capacity() { let item_layout = Layout::new::<Foo>(); let drop = drop_ptr::<Foo>; let _ = unsafe { BlobVec::new(item_layout, Some(drop), 0) }; } ``` this is because we allocate the swap scratch in blobvec regardless of what the capacity is, but we only deallocate if capacity is > 0 The second leak: ```rust #[test] fn panic_while_overwriting_component() { let helper = DropTestHelper::new(); let res = panic::catch_unwind(|| { let mut world = World::new(); world .spawn() .insert(helper.make_component(true, 0)) .insert(helper.make_component(false, 1)); println!("Done inserting! Dropping world..."); }); let drop_log = helper.finish(res); assert_eq!( &*drop_log, [ DropLogItem::Create(0), DropLogItem::Create(1), DropLogItem::Drop(0), ] ); } ``` this is caused by us not running the drop impl on the to-be-inserted component if the drop impl of the overwritten component panics --- managed to figure out where the leaks were by using this 10/10 command ``` cargo --quiet test --lib -- --list | sed 's/: test$//' | MIRIFLAGS="-Zmiri-disable-isolation" xargs -n1 cargo miri test --lib -- --exact ``` which runs every test one by one rather than all at once which let miri actually tell me which test had the leak :upside_down_face:
# Objective When `miri` runs in our build system to detect unsoundness, its output can be very unhelpful, as the tests are all run in parallel. ## Solution Add a comment documenting the extremely obvious 10/10 command used by @BoxyUwU in bevyengine#4959. I've stuck this in the CI file, as it seems like the most obvious place to check when frustrated. I didn't put it in CONTRIBUTING.md because this is an eldritch abomination and will never be useful to new contributors.
The first leak:
this is because we allocate the swap scratch in blobvec regardless of what the capacity is, but we only deallocate if capacity is > 0
The second leak:
this is caused by us not running the drop impl on the to-be-inserted component if the drop impl of the overwritten component panics
managed to figure out where the leaks were by using this 10/10 command
which runs every test one by one rather than all at once which let miri actually tell me which test had the leak 🙃