Skip to content
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

Segfault when attempting to start stream #10

Open
Noah-Kennedy opened this issue Sep 29, 2020 · 15 comments
Open

Segfault when attempting to start stream #10

Noah-Kennedy opened this issue Sep 29, 2020 · 15 comments

Comments

@Noah-Kennedy
Copy link

Noah-Kennedy commented Sep 29, 2020

When attempting to start a stream (I am trying to stream video from a Logitech C920), the program segfaults.

Code:

let ctx = uvc::Context::new().unwrap();
let dev = ctx.find_device(None, None, None).unwrap();

let handle = dev.open().unwrap();

let format = uvc::StreamFormat {
    width: WIDTH,
    height: HEIGHT,
    fps: FPS,
    format: FrameFormat::MJPEG
};

let mut stream_handle = handle.get_stream_handle_with_format(format).unwrap();

let (mjpeg_sender, mut mjpeg_receiver) = watch::channel(Vec::new());

let _stream = stream_handle.start_stream(
    |frame, sender| {
        let frame_vec = frame.to_bytes().to_vec();
        // not sure if safe to panic
        let _ = sender.broadcast(frame_vec);
    },
    mjpeg_sender,
).unwrap();

// use channel at this point

When running it, I get:

unsupported descriptor subtype VS_COLORFORMAT
unsupported descriptor subtype VS_COLORFORMAT
attempt to claim already-claimed interface 1

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

Some other program is must be using my camera for some reason, which probably should be causing either a panic or causing a function to return an error, but should probably not be causing a segfault from safe Rust.

If you'd like, I can try and debug this from my machine, and I can try and potentially pull request a fix in.

@mulimoen
Copy link
Collaborator

If you have a backtrace that would be very helpful!

BTW: You are allowed to panic in the stream, the current behaviour is to catch at the FFI behaviour and ignore

@mulimoen
Copy link
Collaborator

@Noah-Kennedy I pushed the latest version to 'crates.io` which should fix a double free if your function should crash mid-stream.

@mulimoen
Copy link
Collaborator

@Noah-Kennedy Have you managed to get somewhere on the debugging?

@theunkn0wn1
Copy link

theunkn0wn1 commented Dec 18, 2020

@mulimoen Have same issue with a different camera (UHM 350)

Ubuntu 18.04 64 bit

$ cargo run --example mirror          
    Finished dev [unoptimized + debuginfo] target(s) in 0.05s
     Running `target/debug/examples/mirror`
Found device: Bus 001 Device 004 : ID 04f2:3501 UHM350 (Micro )
unsupported descriptor subtype VS_COLORFORMAT
[1]    30303 segmentation fault (core dumped)  cargo run --example mirror

Rust doesn't provide the option to expose the stacktrace it seems.

EDIT: obtained stacktrace via debugger

gef➤  r
Starting program: /home/orion/projects/skool/rover/experiments/libuvc-rs/target/debug/examples/mirror 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff6550700 (LWP 911)]
Found device: Bus 001 Device 004 : ID 04f2:3501 UHM350 (Micro )
unsupported descriptor subtype VS_COLORFORMAT
[New Thread 0x7ffff5d4f700 (LWP 913)]

Thread 1 "mirror" received signal SIGSEGV, Segmentation fault.

[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x0               
$rbx   : 0x00005555556250a0  →  <<alloc::string::String+0> sub rsp, 0x38
$rcx   : 0x0               
$rdx   : 0x1               
$rsp   : 0x00007fffffffaba0  →  0x000055555603e9c0  →  0x0000555556030920  →  0x0000555556036490  →  0x000055555603feb0  →  0x000055555603c720  →  0xc000010401ea0209
$rbp   : 0x7fffff7ff000    
$rsi   : 0x0               
$rdi   : 0x0               
$rip   : 0x00005555556f206d  →  <uvc::device::FrameDescriptor::intervals+77> mov ecx, DWORD PTR [rax]
$r8    : 0x0               
$r9    : 0x00007ffff5d4f700  →  0x00007ffff5d4f700  →  [loop detected]
$r10   : 0x00007ffff5d4f9d0  →  0x0000000000000391
$r11   : 0x202             
$r12   : 0x00007fffffffade0  →  0x0000000000000006
$r13   : 0x00007fffffffd9e8  →  0x0000000000000000
$r14   : 0x00007fffffffb318  →  0x000055555601a240  →  0x0000030e02000b08
$r15   : 0x00005555556250a0  →  <<alloc::string::String+0> sub rsp, 0x38
$eflags: [zero carry parity adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffaba0│+0x0000: 0x000055555603e9c0  →  0x0000555556030920  →  0x0000555556036490  →  0x000055555603feb0  →  0x000055555603c720  →  0xc000010401ea0209	 ← $rsp
0x00007fffffffaba8│+0x0008: 0x000055555603e9c0  →  0x0000555556030920  →  0x0000555556036490  →  0x000055555603feb0  →  0x000055555603c720  →  0xc000010401ea0209
0x00007fffffffabb0│+0x0010: 0x000055555603e9c0  →  0x0000555556030920  →  0x0000555556036490  →  0x000055555603feb0  →  0x000055555603c720  →  0xc000010401ea0209
0x00007fffffffabb8│+0x0018: 0x00005555556f210a  →  <<uvc::device::FrameDescriptors+0> mov QWORD PTR [rsp+0x18], rax
0x00007fffffffabc0│+0x0020: 0x0000000000000000
0x00007fffffffabc8│+0x0028: 0x0000000000000000
0x00007fffffffabd0│+0x0030: 0x000055555603e9c0  →  0x0000555556030920  →  0x0000555556036490  →  0x000055555603feb0  →  0x000055555603c720  →  0xc000010401ea0209
0x00007fffffffabd8│+0x0038: 0x0000000000000000
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0x5555556f205d <uvc::device::FrameDescriptor::intervals+61> call   QWORD PTR [rip+0x90dda5]        # 0x555555fffe08
   0x5555556f2063 <uvc::device::FrameDescriptor::intervals+67> mov    QWORD PTR [rsp+0x20], rax
   0x5555556f2068 <uvc::device::FrameDescriptor::intervals+72> mov    rax, QWORD PTR [rsp+0x20]
 → 0x5555556f206d <uvc::device::FrameDescriptor::intervals+77> mov    ecx, DWORD PTR [rax]
   0x5555556f206f <uvc::device::FrameDescriptor::intervals+79> mov    DWORD PTR [rsp+0x54], ecx
   0x5555556f2073 <uvc::device::FrameDescriptor::intervals+83> cmp    ecx, 0x0
   0x5555556f2076 <uvc::device::FrameDescriptor::intervals+86> je     0x5555556f2092 <uvc::device::FrameDescriptor::intervals+114>
   0x5555556f2078 <uvc::device::FrameDescriptor::intervals+88> mov    rax, QWORD PTR [rsp+0x38]
   0x5555556f207d <uvc::device::FrameDescriptor::intervals+93> add    rax, 0x1
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:src/device.rs+406 ────
    401	     pub fn intervals(&self) -> &[u32] {
    402	         unsafe {
    403	             let intervals = (*self.frame_desc.as_ptr()).intervals;
    404	             let mut len = 0;
    405	             loop {
                         // len=0x0, intervals=0x00007fffffffabe8  →  0x0000000000000000
 →  406	                 let x = *intervals.add(len);
    407	                 if x == 0 {
    408	                     return slice::from_raw_parts::<'a>(intervals, len);
    409	                 }
    410	                 len += 1;
    411	             }
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "mirror", stopped 0x5555556f206d in uvc::device::FrameDescriptor::intervals (), reason: SIGSEGV
[#1] Id 2, Name: "mirror", stopped 0x7ffff74c8cb9 in __GI___poll (), reason: SIGSEGV
[#2] Id 3, Name: "mirror", stopped 0x7ffff74c8cb9 in __GI___poll (), reason: SIGSEGV
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x5555556f206d → uvc::device::FrameDescriptor::intervals(self=0x7ffffffface8)
[#1] 0x5555555e9525 → uvc::device::DeviceHandle::get_preferred_format(self=0x7fffffffb358, f=mirror::main::closure-0)
[#2] 0x555555652f0c → mirror::main()
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
0x00005555556f206d in uvc::device::FrameDescriptor::intervals (self=0x7ffffffface8) at src/device.rs:406
406	                let x = *intervals.add(len);

@mulimoen
Copy link
Collaborator

I'm not familiar with the output from gef, is intervals a pointer with the value 0x00007fffffffabe8 pointing to zero? I don't quite get why that would SEGFAULT

@theunkn0wn1
Copy link

theunkn0wn1 commented Dec 19, 2020

Gef is an extension of GDB geared towards binary analysis.

Its got multiple sections to it,

  1. State of the registers.
  2. State of the Stack.
  3. Disassembly view.
  4. Code view
  5. Stop reasons(would need to look this up, im not immediately familiar with this section)
  6. call stack
  7. offending line

My x86 assembly is quite weak, but looks like its trying to dereference rax, which is NULL. This naturally should segfault.

 → 0x5555556f206d <uvc::device::FrameDescriptor::intervals+77> mov    ecx, DWORD PTR [rax]
$rax   : 0x0         

@theunkn0wn1
Copy link

Poking the crash a bit, it appears intervals is null going into line 406 of uvc::device::FrameDescriptor::intervals

gef➤  info locals
len = 0x0
intervals = 0x0

@mulimoen
Copy link
Collaborator

I've made a bugfix in #18, please check if this solves your problem

@theunkn0wn1
Copy link

It doesn't segfault now, but it does still panic.

$ RUST_BACKTRACE=full cargo debug -- --example mirror
args: ["/home/orion/.cargo/bin/cargo-debug", "debug", "--", "--example", "mirror"]
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
00:41:48 [INFO] selected binary: "/home/orion/projects/skool/rover/experiments/libuvc-rs/target/debug/examples/mirror"
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
GEF for linux ready, type `gef' to start, `gef config' to configure
75 commands loaded for GDB 8.1.0.20180409-git using Python engine 3.6
[*] 5 commands could not be loaded, run `gef missing` to know why.
Reading symbols from /home/orion/projects/skool/rover/experiments/libuvc-rs/target/debug/examples/mirror...done.
warning: Missing auto-load script at offset 0 in section .debug_gdb_scripts
of file /home/orion/projects/skool/rover/experiments/libuvc-rs/target/debug/examples/mirror.
Use `info auto-load python-scripts [REGEXP]' to list them.
gef➤  r
Starting program: /home/orion/projects/skool/rover/experiments/libuvc-rs/target/debug/examples/mirror 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff6550700 (LWP 14202)]
Found device: Bus 001 Device 004 : ID 04f2:3501 UHM350 (Micro )
unsupported descriptor subtype VS_COLORFORMAT
[New Thread 0x7ffff5d4f700 (LWP 14210)]
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', examples/mirror.rs:70:10
stack backtrace:
   0:     0x555555c057f0 - std::backtrace_rs::backtrace::libunwind::trace::h72c2fb8038f1bbee
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/../../backtrace/src/backtrace/libunwind.rs:96
   1:     0x555555c057f0 - std::backtrace_rs::backtrace::trace_unsynchronized::h1e3b084883f1e78c
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/../../backtrace/src/backtrace/mod.rs:66
   2:     0x555555c057f0 - std::sys_common::backtrace::_print_fmt::h3bf6a7ebf7f0394a
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/sys_common/backtrace.rs:79
   3:     0x555555c057f0 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h2e8cb764b7fe02e7
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/sys_common/backtrace.rs:58
   4:     0x555555c2716c - core::fmt::write::h7a1184eaee6a8644
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/fmt/mod.rs:1080
   5:     0x555555c023c2 - std::io::Write::write_fmt::haeeb374d93a67eac
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/io/mod.rs:1516
   6:     0x555555c07bfd - std::sys_common::backtrace::_print::h1d14a7f6ad632dc8
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/sys_common/backtrace.rs:61
   7:     0x555555c07bfd - std::sys_common::backtrace::print::h301abac8bb2e3e81
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/sys_common/backtrace.rs:48
   8:     0x555555c07bfd - std::panicking::default_hook::{{closure}}::hde0cb80358a6920a
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/panicking.rs:208
   9:     0x555555c078a8 - std::panicking::default_hook::h9b1a691049a0ec8f
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/panicking.rs:227
  10:     0x555555c082e1 - std::panicking::rust_panic_with_hook::h2bdec87b60580584
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/panicking.rs:577
  11:     0x555555c07e89 - std::panicking::begin_panic_handler::{{closure}}::h101ca09d9df5db47
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/panicking.rs:484
  12:     0x555555c05c5c - std::sys_common::backtrace::__rust_end_short_backtrace::h3bb85654c20113ca
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/sys_common/backtrace.rs:153
  13:     0x555555c07e49 - rust_begin_unwind
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/panicking.rs:483
  14:     0x555555c25041 - core::panicking::panic_fmt::h48c31e1e3d550146
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/panicking.rs:85
  15:     0x555555c24f8d - core::panicking::panic::h184ede6dd822ffb4
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/panicking.rs:50
  16:     0x5555556e29aa - core::option::Option<T>::unwrap::h7b750e5dc134384c
                               at /home/orion/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:383
  17:     0x555555652f32 - mirror::main::h305f75d50c5e91d3
                               at /home/orion/projects/skool/rover/experiments/libuvc-rs/examples/mirror.rs:62
  18:     0x55555563225b - core::ops::function::FnOnce::call_once::h46bbd7ce70df7f22
                               at /home/orion/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:227
  19:     0x5555555e499e - std::sys_common::backtrace::__rust_begin_short_backtrace::hb9392815093d8720
                               at /home/orion/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:137
  20:     0x5555556de621 - std::rt::lang_start::{{closure}}::hd5d779ad70c7efb1
                               at /home/orion/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:66
  21:     0x555555c08707 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::he179d32a5d10d957
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/ops/function.rs:259
  22:     0x555555c08707 - std::panicking::try::do_call::hcb3d5e7be089b2b4
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/panicking.rs:381
  23:     0x555555c08707 - std::panicking::try::h7ac93b0cd56fb701
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/panicking.rs:345
  24:     0x555555c08707 - std::panic::catch_unwind::h7b40e396c93a4fcd
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/panic.rs:382
  25:     0x555555c08707 - std::rt::lang_start_internal::h142b9cc66267fea1
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/rt.rs:51
  26:     0x5555556de5f7 - std::rt::lang_start::h85da232f7497e24f
                               at /home/orion/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:65
  27:     0x55555565419a - main
  28:     0x7ffff73d5bf7 - __libc_start_main
  29:     0x5555555e3d2a - _start
  30:                0x0 - <unknown>
[Thread 0x7ffff5d4f700 (LWP 14210) exited]
[Thread 0x7ffff6550700 (LWP 14202) exited]
[Inferior 1 (process 14198) exited with code 0145]

@mulimoen
Copy link
Collaborator

That would suggest there are no formats available for streaming. Does your camera work with other software using uvc?

@theunkn0wn1
Copy link

That would suggest there are no formats available for streaming. Does your camera work with other software using uvc?

Unclear, I haven't tested the camera against uvc itself. AFAIK this camera behaves as a standard USB webcam, which I have been able to read by other means, though i don't think any of those use uvc.

@mulimoen
Copy link
Collaborator

You could call supported_formats to get a list of recognized formats for libuvc. You could also try opening a stream with get_stream_handle_with_format.

@theunkn0wn1
Copy link

using the provided mirror.rs example, modified to make call to devh.supported_formats() doesn't return anything that is immediately meaningful for debugging.

What did appear to work was manually constructing a StreamFormat instance using values I obtained from another image-capture crate eye-rs

    let mut streamh = devh.get_stream_handle_with_format(StreamFormat {
        width: 1920,
        height: 1080,
        fps: 30,
        format: FrameFormat::MJPEG
    }).unwrap();

This produces a bunch of non-fatal errors, but does open the camera and streams live video, so it appears to work.
(presumably the errors are the result of this camera not being fully compatable with uvc)

Found device: Bus 001 Device 004 : ID 04f2:3501 UHM350 (Micro )
unsupported descriptor subtype VS_COLORFORMAT
Scanning mode: Err(Pipe)
Auto-exposure mode: Err(Pipe)
Auto-exposure priority: Err(Pipe)
Absolute exposure: Err(Pipe)
Relative exposure: Err(Pipe)
Aboslute focus: Err(Pipe)
Relative focus: Err(Pipe)
attempt to claim already-claimed interface 1
Not a JPEG file: starts with 0x00 0xac
Other

@mulimoen
Copy link
Collaborator

Not all cameras supports all modes and configurations, those errors are somewhat normal. The first frame is also corrupted, I've noticed this before on my own hardware

@theunkn0wn1
Copy link

Thanks for the feedback.
I believe the OP's segfault issue is resolved by the patch in #18 .

If i have any further issues they will go in their own tickets.
Thanks for the support!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants