SIGSEGV when running tests, but works fine during debugging

You can find the relevant test with this link.

     // Zero-sized type for verifying zst handling.
     struct ZST;

	#[test]
	fn zst_iter() {
        // (signal: 11, SIGSEGV: invalid memory reference)
		let mut vec = super::ErasedVec::new(super::ErasedInfo::of::<Zst>());

        // segfault occurs before this executes.
        eprintln!("You are Here");

		vec.write(Zst);
		vec.write(Zst);
		vec.write(Zst);

		for ptr in vec.iter() {
			unsafe {
				assert_eq!(*ptr.cast::<Zst>(), Zst);
			}
		}
	}

I am implementing type erasure for a game engine, I've narrowed down the issue to be coming from this function:

impl ErasedVec {
	/// Create a new ErasedVec for elements of the specified type.
	pub fn new(info: ErasedInfo) -> Self {
		Self {
            // guaranteed to be well-aligned, but dangling.
            // created with NonNull::dangling::<T>(), for the 
            // type this erased vec stores.
			data: unsafe { ptr::NonNull::new_unchecked(info.dangling) },
			cap: if info.is_zero_sized() { usize::MAX } else { 0 },

			// By default, the offset is set to 'size_of_one', but this
			// may not be accurate for operating on the array, since
			// this default value will not include the padding between
			// elements.
			// 
			// This value will be updated when `grow` is called.
			offs: info.size_of_one(),
			info,
			len: 0,
		}
	}
}

I've also tested ErasedInfo::is_zero_sized() and ErasedInfo::size_of_one() and found no issues.

When running with the debugger, there is no error, so I don't have a good way to pinpoint the issue. I'm never dereferencing a pointer in new, so this shouldn't even happen (at least to my knowledge).

Full Error:

    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.05s
     Running unittests src/lib.rs (/home/wade/minecraft2/target/debug/deps/ecs-f1fd0862f572df9e)

running 1 test
error: test failed, to rerun pass `--lib`

Caused by:
  process didn't exit successfully: `/home/wade/minecraft2/target/debug/deps/ecs-f1fd0862f572df9e zst_iter` (signal: 11, SIGSEGV: invalid memory reference)

You should try to get a test case into a playground - surely it'd be less work than all the work you did preparing this, the code looks pretty self-contained. And that way anyone could poke around with it and help out.

I'm a little doubtful this is really crashing in new. Maybe in the destructor though. Dropping a dangling pointer?

1 Like

You were right, it was because of my drop destructor. Really thought i had my bases covered, but I guess not.

Thanks for the help. I'll be sure to make a playground next time.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.