Segfault when setting an instance property on 2.7.3

V

Vincent Pelletier

Hi.

(please keep me in CC for replies, I'm not subscribed)

I wrote a ctypes-(wait, read on)-based binding[1] for libusb1, in which I'm
triggering a segfault from an application[2] I wrote.

I've been through several segfault caused by ctypes mis-usage, this one seems
different enough. I think there is something else (maybe ultimately caused by
some ctypes effect, but I don't see the relation yet).

The Python line causing the segfault:
https://github.com/vpelletier/python-libusb1/blob/master/usb1.py#L192

C stack at segfault (with -dbg package installed):
http://pastebin.com/rVUPsSrU

#0
(gdb) print *op
$1 = {ob_refcnt = -4247522206314328575, ob_type = 0xcf0dc50ec50dc50e}
(gdb) up
#1
(gdb) print *obj
$2 = {ob_refcnt = 6, ob_type = 0x9c5f70}
(gdb) print obj
$3 = <USBTransfer at remote 0xb3a950>

The program using python-libusb1 which triggers the segfault:
https://github.com/vpelletier/ITI1480A-linux/blob/master/iti1480a/capture.py
The event loop is at the bottom: allocate USB transfers, submit them, loop on
libusb1 event handling until there is no more submitted transfer, libusb uses
callback which resubmits transfer, ...

ctypes possible segfault causes checklist:
- callback is cast into a ctype CFUNCTYPE type instance
See:
https://github.com/vpelletier/python-libusb1/blob/master/libusb1.py#L587
https://github.com/vpelletier/python-libusb1/blob/master/usb1.py#L133
- a strong ref to it is kept on USBTransfer instance so it is not GC'ed
See:
https://github.com/vpelletier/python-libusb1/blob/master/usb1.py#L808
- application is single-threaded (libusb1 doesn't create any C thread either)
so even if there were missing GIL acquisitions, it shouldn't be a problem
Also, a strong ref to USBTransfer is kept on USBDeviceHandle instance. When
an USBDeviceHandle is GC'ed, it cancels any pending transfer, waits for
completion (=libusb1 callback is executed) and then allow them to be GC'ed.
- we are not accessing unallocated memory in this traceback (although it could
be that memory got overwritten somehow)

I couldn't trigger the bug while under valgrind (which reported some
"Conditional jump or move depends on uninitialized value(s)" & "Use of
uninitialized value of size 8" in PyObject_Free, but reading the code I guess
they are harmless and unrelated).

Any idea of ways to debug this problem further ?

Regards,
 

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top