New submission from Nikolaus Rath <nikol...@rath.org>:

The following is a very subtle bug and it took me a couple of days to reduce it 
to a manageable test case. So please bear with me even if it's tedious.

The problem is that in some cases the use of ctypes for a callback function 
freezes the entire process. Even 'gdb -p' freezes when trying to attach to the 
affected PID. The process can not be killed with SIGTERM.

Please consider the attached example. It needs the fuse headers installed to 
work (package libfuse-dev under Debian).

Step 1: Compile hello_ll.c with   

gcc -Wall -g3 -O0 -fPIC `pkg-config fuse --cflags` -c hello_ll.c
gcc -Wall -g3 -O0 -shared `pkg-config fuse --libs` -o hello_ll.so hello_ll.o

into a shared library. The do_mount() function will be called with ctypes from 
call_hello.py.

Step 2: In call_hello.py you need to adjust the import of libfuse to match your 
installed FUSE version (2.6 or 2.8). The libfuse2{6,8}.py files have been 
autogenerated with ctypeslib. I can provide versions for other FUSE versions as 
well if necessary. Note that the problem is most likely not with the 
definitions in this file, I checked all of them carefully by hand.


Step 3: Create an empty directory 'mnt' in the working directory

Step 4: Run call_hello.py. It will mount a simple example FUSE file system in 
mnt, read the directory, umount the fs and exit.

Step 5: Uncomment line 36 of call_hello.py. This will substitute the C function 
hello_ll_opendir() (defined in hello_ll.c) by the Python function 
fuse_opendir(). Note that both functions do exactly the same thing, they just 
call the fuse function fuse_reply_err.

Step 6: Run call_hello.py again. The program will hang completely. You can 
salvage the mount point with "fusermount -u -z mnt".

Step 7: Comment out line 47 in call_hello.py, so that the process itself does 
not try to access the mountpoint anymore.

Step 8: Run call_hello.py again. Observe that the file system mounts and 
umounts fine. Accessing the mountpoint with a different process does not 
trigger the freeze either.


In summary, the process hangs only if:

1) The opendir function is implemented as a ctypes callback

and

2) the mounting process itself tries to access the mountpoint


I suspect that the ctypes callback may somehow deadlock with the thread that 
tries to access the mountpoint.

If someone can tell me how to get around the hanging gdb process, i'll be happy 
to provide a backtrace. I have already installed debugging symbols for both 
Python and libfuse.


Thank you for taking the time to read up to this point :-)

----------
assignee: theller
components: ctypes
messages: 98038
nosy: Nikratio, theller
severity: normal
status: open
title: ctypes freezes/deadlocks process
type: crash
versions: Python 2.6

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue7736>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to