larskanis/libusb

Bug: Segmentation fault when exiting

erikarvstedt opened this issue · 1 comments

When running this simple script

require "libusb"

usb = LIBUSB::Context.new

device = usb.devices(idVendor: 0x0100, idProduct: 0x0001).first

device.open do |dev|
  if dev.kernel_driver_active?(0)
    dev.detach_kernel_driver(0)
  end
  dev.claim_interface(0) {}
end

puts 'exiting'

to access my Generic HID device (a custom AVR ATMEGA32U4), in 20% of the cases I'm getting a segfault:

exiting
segfault-demo.rb: [BUG] Segmentation fault at 0x00007f9bff0be7ef
ruby 2.4.5p335 (2018-10-18) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0001 p:0000 s:0003 E:001710 (none) [FINISH]


-- Machine register context ------------------------------------------------
 RIP: 0x00007f9bff0be7ef RBP: 0x00007f9bff0aced0 RSP: 0x00007f9bff0acec0
 RAX: 0x0000000000000001 RBX: 0x00000000ffffffff RCX: 0x00007f9c07708501
 RDX: 0x00000000ffffffff RDI: 0x0000000000000000 RSI: 0x0000000000000002
  R8: 0x0000000000000000  R9: 0x00007f9bff0ad700 R10: 0x00007f9bff0ad9d0
 R11: 0x0000000000000000 R12: 0x00007ffd3f7dad4e R13: 0x00007ffd3f7dad4f
 R14: 0x00007f9bff0ad700 R15: 0x00007f9c08afd000 EFL: 0x0000000000010206

-- C level backtrace information -------------------------------------------
/nix/store/n8i8zc2max1cq7nz50lwrry2w6i3gfgi-ruby-2.4.5/lib/libruby.so.2.4(rb_vm_bugreport+0x769) [0x7f9c085e93d9]
/nix/store/n8i8zc2max1cq7nz50lwrry2w6i3gfgi-ruby-2.4.5/lib/libruby.so.2.4 [0x7f9c084685d4]
/nix/store/n8i8zc2max1cq7nz50lwrry2w6i3gfgi-ruby-2.4.5/lib/libruby.so.2.4 [0x7f9c0855d02e]
/nix/store/fg4yq8i8wd08xg3fy58l6q73cjy8hjr2-glibc-2.27/lib/libpthread.so.0 [0x7f9c081b6f10]
/nix/store/fg4yq8i8wd08xg3fy58l6q73cjy8hjr2-glibc-2.27/lib/libgcc_s.so.1(__getf2+0x3f) [0x7f9bff0be7ef]
/nix/store/fg4yq8i8wd08xg3fy58l6q73cjy8hjr2-glibc-2.27/lib/libpthread.so.0 [0x7f9c081ac5a7]
/nix/store/fg4yq8i8wd08xg3fy58l6q73cjy8hjr2-glibc-2.27/lib/libc.so.6(clone+0x3f) [0x7f9c0771222f]

(Full diagnostic output)

The error doesn't happen when using libusb in a similar way via C or Python.
Note that the error appears while exiting, after the last code statement.
The error disappears when running sleep 0.01 before exiting. (But not sleep 0.001, which seems to be a too short sleep duration).
Besides this error, other features of this library, like transfers, are properly functioning.

Environment:

Tested Ruby versions: 2.5.3p105, 2.4.5p335
ffi (1.10.0)
libusb (0.6.4)
Linux 4.14.83 (NixOS)

Let me know if's there's anything more I can do to help debugging this.

Thank you @erikarvstedt for your detailed bug report!

I tried to reproduce this issue with your provided script, changed to a vendor/product id of my system. Unfortunately I don't get any segfaults, even when running an endless bash loop. Your C backtrace isn't particular meaningful. I might help if you could install debug symbols of ruby (usually by the package manager) or/and if you could run the program via valgrind ruby segfault-demo.rb .

Moreover I remember that I've got a similar segfault in the early days of libusb development, which was caused by the non-deterministic order by which the ruby GC frees objects, when they are no longer in use. It happened, that some object made a call to the USB context while closing, although the context was already freed. I played a little bit with your program, but wasn't able to trigger a segfault either.