Re: Segfault when setting an instance property on 2.7.3

2012-08-26 Thread Vincent Pelletier
Le samedi 25 août 2012 11:38:47, Vincent Pelletier a écrit :
 Any idea of ways to debug this problem further ?

Trying with pypy (just to see), I got even more reproductible segfaults - 
even with valgrind.

Turns out, I was not keeping strong references to ctypes buffers, which get 
very quickly collected with pypy and memory reused for something else, leading 
to a quick crash.

Now, I don't get yet why cpython was not crashing more often, even if I forced 
gc.collect() . Less memory recycling maybe ?

Regards,
-- 
Vincent Pelletier
-- 
http://mail.python.org/mailman/listinfo/python-list


Segfault when setting an instance property on 2.7.3

2012-08-25 Thread 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,
-- 
Vincent Pelletier
-- 
http://mail.python.org/mailman/listinfo/python-list