Skip to content

Misaligned pointer dereference #190

@aliddell

Description

@aliddell

One issue preventing using the Runtime as a module-level fixture in tests (or using it in loops in a script) is that, in Rust, raw pointers want to be aligned when dereferenced (see).

To reproduce this, it's enough to acquire with a frame size that's not divisible by 8 and iterate over the frames:

import acquire


def acquire_unaligned():
    runtime = acquire.Runtime()
    dm = runtime.device_manager()
    props = runtime.get_configuration()
    props.video[0].camera.identifier = dm.select(
        acquire.DeviceKind.Camera, ".*empty.*")

    # sizeof(VideoFrame) + 33 * 47 is not divisible by 8
    props.video[0].camera.settings.shape = (33, 47)
    props.video[0].storage.identifier = dm.select(
        acquire.DeviceKind.Storage, "trash")

    props.video[0].max_frame_count = 3
    runtime.set_configuration(props)

    nframes = 0
    runtime.start()
    while nframes < props.video[0].max_frame_count:
        with runtime.get_available_data(0) as packet:
            for i in range(packet.get_frame_count()):
                _ = next(packet.frames())
                nframes += 1
    runtime.stop()


if __name__ == "__main__":
    acquire_unaligned()

giving something like the following error:

thread '<unnamed>' panicked at src/runtime.rs:394:54:
misaligned pointer dereference: address must be a multiple of 0x8 but is 0x300000c7e
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused non-unwinding panic. aborting.

Process finished with exit code 134 (interrupted by signal 6:SIGABRT)

This is VideoFrameIterator::next():

fn next(&mut self) -> Option<Self::Item> {
        let mut cur = self.cur.lock();
        if (*self.store.lock()).is_some() && *cur < self.end {
            let out = VideoFrame {
                _store: self.store.clone(),
                cur: *cur,
            };

            let c = cur.as_ptr();
            let o = unsafe { (c as *const u8).offset((*c).bytes_of_frame as _) } // OFFENDING DEREFERENCE HERE
                as *mut capi::VideoFrame;
            *cur = unsafe { NonNull::new_unchecked(o) };

            Some(out)
        } else {
            None
        }
    }

We should consider padding video frames and making next aware of this.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Status

Complete

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions