profiling fuse-python
I am currently writing a fuse using fuse-python. It's already doing what it should. However, after it's mounted for a few weeks, it's becoming noticeably slow. So I wanted to profile it. I know about a few point where it could be optimized. But these should not be the culprits.
However, fuse-python hangs in an infinite loop (see line 733 and 757 of the fuse source). If I run fuse in debug mode (using the -d
switch), it will run in foreground. However, I cannot stop it with SIGINT
开发者_开发技巧 nor with CTRL+C
(which is anyway the same).
I tried to use the signal
module to trap the signal in the main thread. But this does not work either. Interestingly, once I shoot the process down with SIGKILL
, I see the KeyboardInterrupt
on stdout
. Also, after a SIGKILL
, the signal handler is executed as expected.
This has repercussions on profiling. As the process never terminates normally, cProfile
never gets the chance to save the stats file.
Any ideas?
Python installs a handler that raises KeyboardInterrupt
on SIGINT
. If a non-default signal handler is detected when fuse's main is called, it will not replace the handler with its own, which normally calls fuse_session_exit
and cleans up. After you've called fuse's main, the KeyboardInterrupt
is swallowed by CFUNCTYPE
wrappers and you never see them.
Your options are to:
- Send
SIGQUIT
by pressing Ctrl+\, or any other terminating signal other thanSIGINT
. However fuse will not exit cleanly. - Install the default signal handler to
SIGINT
before calling fuse's main, and restore the original when you're done.
old_handler =signal(SIGINT, SIG_DFL)
# call main
signal(SIGINT, old_handler)
I'd highly recommend you switch to an alternative binding also, fuse-python is terribly messy and difficult to work with. I've had a lot of luck with fusepy, and have submitted a few patches there.
When you're able to terminate your FUSE instance without using uncaught signals, the Python profiler will be able to save the stats as per normal.
精彩评论