New submission from Nikolaus Rath <[email protected]>:
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 <[email protected]>
<http://bugs.python.org/issue7736>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com