Description
I'm running into a segfault when calling some_iter.collect()
into a SmallVec. The problem happens when the smallvec spills and needs to allocate, eventually leading to a segfault in the realloc call.
I'll try and make a minimal reproducing test.
The problem shows up in both debug and release mode, running on the latest stable rust compiler (1.78.0).
Smallvec 1.x works fine.
Valgrind has the gory details. The first problem it spots is an invalid memmove:
==21584== Thread 2 list::op_iter:::
==21584== Invalid write of size 8
==21584== at 0x485293B: memmove (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==21584== by 0x3F41C2: write<diamond_types::list::operation::TextOperation> (mod.rs:1493)
==21584== by 0x3F41C2: write<diamond_types::list::operation::TextOperation> (mut_ptr.rs:1491)
==21584== by 0x3F41C2: smallvec::SmallVec<T,_>::push_heap (lib.rs:968)
==21584== by 0x3EA6EF: smallvec::SmallVec<T,_>::extend_impl (lib.rs:1519)
==21584== by 0x3E481F: <smallvec::SmallVec<T,_> as core::iter::traits::collect::FromIterator<T>>::from_iter (lib.rs:1838)
==21584== by 0x291CA3: core::iter::traits::iterator::Iterator::collect (iterator.rs:2003)
Full valgrind trace below.
running 1 test
==21584== Thread 2 list::op_iter:::
==21584== Invalid write of size 8
==21584== at 0x485293B: memmove (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==21584== by 0x3F41C2: write<diamond_types::list::operation::TextOperation> (mod.rs:1493)
==21584== by 0x3F41C2: write<diamond_types::list::operation::TextOperation> (mut_ptr.rs:1491)
==21584== by 0x3F41C2: smallvec::SmallVec<T,>::push_heap (lib.rs:968)
==21584== by 0x3EA6EF: smallvec::SmallVec<T,>::extend_impl (lib.rs:1519)
==21584== by 0x3E481F: <smallvec::SmallVec<T,> as core::iter::traits::collect::FromIterator>::from_iter (lib.rs:1838)
==21584== by 0x291CA3: core::iter::traits::iterator::Iterator::collect (iterator.rs:2003)
==21584== by 0x395258: diamond_types::list::op_iter::::as_chunked_operation_vec (op_iter.rs:290)
==21584== by 0x3AF4E1: diamond_types::list::op_iter::test::fix_cs (op_iter.rs:407)
==21584== by 0x20DB18: diamond_types::list::op_iter::test::fix_cs::{{closure}} (op_iter.rs:399)
==21584== by 0x21AEE7: core::ops::function::FnOnce::call_once (function.rs:250)
==21584== by 0x4C30FE: test::__rust_begin_short_backtrace (function.rs:250)
==21584== by 0x4C2782: test::run_test::{{closure}} (lib.rs:644)
==21584== by 0x48A162: std::sys_common::backtrace::__rust_begin_short_backtrace (lib.rs:595)
==21584== Address 0x4ea2360 is 0 bytes after a block of size 256 free'd
==21584== at 0x484DCD3: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==21584== by 0x2365B1: alloc::alloc::realloc (alloc.rs:138)
==21584== by 0x3F7B6C: smallvec::RawSmallVec<T,>::try_grow_raw (lib.rs:238)
==21584== by 0x3F35D3: smallvec::SmallVec<T,>::try_grow (lib.rs:1022)
==21584== by 0x3ED1B4: smallvec::SmallVec<T,>::grow (lib.rs:1008)
==21584== by 0x3EF6AA: smallvec::SmallVec<T,>::reserve (lib.rs:1062)
==21584== by 0x3F4162: smallvec::SmallVec<T,>::push_heap (lib.rs:966)
==21584== by 0x3EA6EF: smallvec::SmallVec<T,>::extend_impl (lib.rs:1519)
==21584== by 0x3E481F: <smallvec::SmallVec<T,> as core::iter::traits::collect::FromIterator>::from_iter (lib.rs:1838)
==21584== by 0x291CA3: core::iter::traits::iterator::Iterator::collect (iterator.rs:2003)
==21584== by 0x395258: diamond_types::list::op_iter::::as_chunked_operation_vec (op_iter.rs:290)
==21584== by 0x3AF4E1: diamond_types::list::op_iter::test::fix_cs (op_iter.rs:407)
==21584== Block was alloc'd at
==21584== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==21584== by 0x2361F1: alloc::alloc::alloc (alloc.rs:100)
==21584== by 0x3F7956: smallvec::RawSmallVec<T,>::try_grow_raw (lib.rs:220)
==21584== by 0x3F35D3: smallvec::SmallVec<T,>::try_grow (lib.rs:1022)
==21584== by 0x3ED1B4: smallvec::SmallVec<T,>::grow (lib.rs:1008)
==21584== by 0x3EF6AA: smallvec::SmallVec<T,>::reserve (lib.rs:1062)
==21584== by 0x3ED4F8: smallvec::SmallVec<T,>::push (lib.rs:949)
==21584== by 0x3EA664: smallvec::SmallVec<T,>::extend_impl (lib.rs:1508)
==21584== by 0x3E481F: <smallvec::SmallVec<T,> as core::iter::traits::collect::FromIterator>::from_iter (lib.rs:1838)
==21584== by 0x291CA3: core::iter::traits::iterator::Iterator::collect (iterator.rs:2003)
==21584== by 0x395258: diamond_types::list::op_iter::::as_chunked_operation_vec (op_iter.rs:290)
==21584== by 0x3AF4E1: diamond_types::list::op_iter::test::fix_cs (op_iter.rs:407)
==21584==
==21584== Invalid write of size 8
==21584== at 0x4852943: memmove (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==21584== by 0x3F41C2: write<diamond_types::list::operation::TextOperation> (mod.rs:1493)
==21584== by 0x3F41C2: write<diamond_types::list::operation::TextOperation> (mut_ptr.rs:1491)
==21584== by 0x3F41C2: smallvec::SmallVec<T,>::push_heap (lib.rs:968)
==21584== by 0x3EA6EF: smallvec::SmallVec<T,>::extend_impl (lib.rs:1519)
==21584== by 0x3E481F: <smallvec::SmallVec<T,> as core::iter::traits::collect::FromIterator>::from_iter (lib.rs:1838)
==21584== by 0x291CA3: core::iter::traits::iterator::Iterator::collect (iterator.rs:2003)
==21584== by 0x395258: diamond_types::list::op_iter::::as_chunked_operation_vec (op_iter.rs:290)
==21584== by 0x3AF4E1: diamond_types::list::op_iter::test::fix_cs (op_iter.rs:407)
==21584== by 0x20DB18: diamond_types::list::op_iter::test::fix_cs::{{closure}} (op_iter.rs:399)
==21584== by 0x21AEE7: core::ops::function::FnOnce::call_once (function.rs:250)
==21584== by 0x4C30FE: test::__rust_begin_short_backtrace (function.rs:250)
==21584== by 0x4C2782: test::run_test::{{closure}} (lib.rs:644)
==21584== by 0x48A162: std::sys_common::backtrace::__rust_begin_short_backtrace (lib.rs:595)
==21584== Address 0x4ea2368 is 8 bytes after a block of size 256 free'd
==21584== at 0x484DCD3: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==21584== by 0x2365B1: alloc::alloc::realloc (alloc.rs:138)
==21584== by 0x3F7B6C: smallvec::RawSmallVec<T,>::try_grow_raw (lib.rs:238)
==21584== by 0x3F35D3: smallvec::SmallVec<T,>::try_grow (lib.rs:1022)
==21584== by 0x3ED1B4: smallvec::SmallVec<T,>::grow (lib.rs:1008)
==21584== by 0x3EF6AA: smallvec::SmallVec<T,>::reserve (lib.rs:1062)
==21584== by 0x3F4162: smallvec::SmallVec<T,>::push_heap (lib.rs:966)
==21584== by 0x3EA6EF: smallvec::SmallVec<T,>::extend_impl (lib.rs:1519)
==21584== by 0x3E481F: <smallvec::SmallVec<T,> as core::iter::traits::collect::FromIterator>::from_iter (lib.rs:1838)
==21584== by 0x291CA3: core::iter::traits::iterator::Iterator::collect (iterator.rs:2003)
==21584== by 0x395258: diamond_types::list::op_iter::::as_chunked_operation_vec (op_iter.rs:290)
==21584== by 0x3AF4E1: diamond_types::list::op_iter::test::fix_cs (op_iter.rs:407)
==21584== Block was alloc'd at
==21584== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==21584== by 0x2361F1: alloc::alloc::alloc (alloc.rs:100)
==21584== by 0x3F7956: smallvec::RawSmallVec<T,>::try_grow_raw (lib.rs:220)
==21584== by 0x3F35D3: smallvec::SmallVec<T,>::try_grow (lib.rs:1022)
==21584== by 0x3ED1B4: smallvec::SmallVec<T,>::grow (lib.rs:1008)
==21584== by 0x3EF6AA: smallvec::SmallVec<T,>::reserve (lib.rs:1062)
==21584== by 0x3ED4F8: smallvec::SmallVec<T,>::push (lib.rs:949)
==21584== by 0x3EA664: smallvec::SmallVec<T,>::extend_impl (lib.rs:1508)
==21584== by 0x3E481F: <smallvec::SmallVec<T,> as core::iter::traits::collect::FromIterator>::from_iter (lib.rs:1838)
==21584== by 0x291CA3: core::iter::traits::iterator::Iterator::collect (iterator.rs:2003)
==21584== by 0x395258: diamond_types::list::op_iter::::as_chunked_operation_vec (op_iter.rs:290)
==21584== by 0x3AF4E1: diamond_types::list::op_iter::test::fix_cs (op_iter.rs:407)
==21584==
==21584== Invalid write of size 8
==21584== at 0x485294B: memmove (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==21584== by 0x3F41C2: write<diamond_types::list::operation::TextOperation> (mod.rs:1493)
==21584== by 0x3F41C2: write<diamond_types::list::operation::TextOperation> (mut_ptr.rs:1491)
==21584== by 0x3F41C2: smallvec::SmallVec<T,>::push_heap (lib.rs:968)
==21584== by 0x3EA6EF: smallvec::SmallVec<T,>::extend_impl (lib.rs:1519)
==21584== by 0x3E481F: <smallvec::SmallVec<T,> as core::iter::traits::collect::FromIterator>::from_iter (lib.rs:1838)
==21584== by 0x291CA3: core::iter::traits::iterator::Iterator::collect (iterator.rs:2003)
==21584== by 0x395258: diamond_types::list::op_iter::::as_chunked_operation_vec (op_iter.rs:290)
==21584== by 0x3AF4E1: diamond_types::list::op_iter::test::fix_cs (op_iter.rs:407)
==21584== by 0x20DB18: diamond_types::list::op_iter::test::fix_cs::{{closure}} (op_iter.rs:399)
==21584== by 0x21AEE7: core::ops::function::FnOnce::call_once (function.rs:250)
==21584== by 0x4C30FE: test::__rust_begin_short_backtrace (function.rs:250)
==21584== by 0x4C2782: test::run_test::{{closure}} (lib.rs:644)
==21584== by 0x48A162: std::sys_common::backtrace::__rust_begin_short_backtrace (lib.rs:595)
==21584== Address 0x4ea2370 is 16 bytes after a block of size 256 free'd
==21584== at 0x484DCD3: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==21584== by 0x2365B1: alloc::alloc::realloc (alloc.rs:138)
==21584== by 0x3F7B6C: smallvec::RawSmallVec<T,>::try_grow_raw (lib.rs:238)
==21584== by 0x3F35D3: smallvec::SmallVec<T,>::try_grow (lib.rs:1022)
==21584== by 0x3ED1B4: smallvec::SmallVec<T,>::grow (lib.rs:1008)
==21584== by 0x3EF6AA: smallvec::SmallVec<T,>::reserve (lib.rs:1062)
==21584== by 0x3F4162: smallvec::SmallVec<T,>::push_heap (lib.rs:966)
==21584== by 0x3EA6EF: smallvec::SmallVec<T,>::extend_impl (lib.rs:1519)
==21584== by 0x3E481F: <smallvec::SmallVec<T,> as core::iter::traits::collect::FromIterator>::from_iter (lib.rs:1838)
==21584== by 0x291CA3: core::iter::traits::iterator::Iterator::collect (iterator.rs:2003)
==21584== by 0x395258: diamond_types::list::op_iter::::as_chunked_operation_vec (op_iter.rs:290)
==21584== by 0x3AF4E1: diamond_types::list::op_iter::test::fix_cs (op_iter.rs:407)
==21584== Block was alloc'd at
==21584== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==21584== by 0x2361F1: alloc::alloc::alloc (alloc.rs:100)
==21584== by 0x3F7956: smallvec::RawSmallVec<T,>::try_grow_raw (lib.rs:220)
==21584== by 0x3F35D3: smallvec::SmallVec<T,>::try_grow (lib.rs:1022)
==21584== by 0x3ED1B4: smallvec::SmallVec<T,>::grow (lib.rs:1008)
==21584== by 0x3EF6AA: smallvec::SmallVec<T,>::reserve (lib.rs:1062)
==21584== by 0x3ED4F8: smallvec::SmallVec<T,>::push (lib.rs:949)
==21584== by 0x3EA664: smallvec::SmallVec<T,>::extend_impl (lib.rs:1508)
==21584== by 0x3E481F: <smallvec::SmallVec<T,> as core::iter::traits::collect::FromIterator>::from_iter (lib.rs:1838)
==21584== by 0x291CA3: core::iter::traits::iterator::Iterator::collect (iterator.rs:2003)
==21584== by 0x395258: diamond_types::list::op_iter::::as_chunked_operation_vec (op_iter.rs:290)
==21584== by 0x3AF4E1: diamond_types::list::op_iter::test::fix_cs (op_iter.rs:407)
==21584==
==21584== Invalid write of size 8
==21584== at 0x4852953: memmove (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==21584== by 0x3F41C2: write<diamond_types::list::operation::TextOperation> (mod.rs:1493)
==21584== by 0x3F41C2: write<diamond_types::list::operation::TextOperation> (mut_ptr.rs:1491)
==21584== by 0x3F41C2: smallvec::SmallVec<T,>::push_heap (lib.rs:968)
==21584== by 0x3EA6EF: smallvec::SmallVec<T,>::extend_impl (lib.rs:1519)
==21584== by 0x3E481F: <smallvec::SmallVec<T,> as core::iter::traits::collect::FromIterator>::from_iter (lib.rs:1838)
==21584== by 0x291CA3: core::iter::traits::iterator::Iterator::collect (iterator.rs:2003)
==21584== by 0x395258: diamond_types::list::op_iter::::as_chunked_operation_vec (op_iter.rs:290)
==21584== by 0x3AF4E1: diamond_types::list::op_iter::test::fix_cs (op_iter.rs:407)
==21584== by 0x20DB18: diamond_types::list::op_iter::test::fix_cs::{{closure}} (op_iter.rs:399)
==21584== by 0x21AEE7: core::ops::function::FnOnce::call_once (function.rs:250)
==21584== by 0x4C30FE: test::__rust_begin_short_backtrace (function.rs:250)
==21584== by 0x4C2782: test::run_test::{{closure}} (lib.rs:644)
==21584== by 0x48A162: std::sys_common::backtrace::__rust_begin_short_backtrace (lib.rs:595)
==21584== Address 0x4ea2378 is 24 bytes after a block of size 256 in arena "client"
==21584==
valgrind: m_mallocfree.c:303 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 7894, hi = 0.
This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata. If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away. Please try that before reporting this as a bug.
</details>