问题
I want to debug a Python program which is often stuck.
Basically, my program runs a spyne-server which accepts SOAP requests. My program is multi-threaded and sometimes, the client I use to reach it timeouts.
I've tryed severals debuggers such as PUDB, PDB, WINPDB, PYSTUCK but I wasn't able to catch any exception from them, in fact they happen to be stuck too (CTRL+C doesnt work...)
The best I've achieved was from GDB with the following command:
gdb -ex r --args python myscript.py
GDB manages to catch the exception but doesn't display any usefull informations:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffd7fff700 (LWP 22573)]
0x000000000057656d in PyEval_EvalCodeEx ()
(gdb) info threads
Id Target Id Frame
* 15 Thread 0x7fffd7fff700 (LWP 22573) "python" 0x000000000057656d in PyEval_EvalCodeEx ()
7 Thread 0x7fffecc2c700 (LWP 22277) "python" 0x00007ffff6998653 in select () at ../sysdeps/unix/syscall-template.S:82
6 Thread 0x7fffed42d700 (LWP 22276) "python" 0x00007ffff6998653 in select () at ../sysdeps/unix/syscall-template.S:82
5 Thread 0x7fffedc2e700 (LWP 22271) "python" sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
4 Thread 0x7fffee42f700 (LWP 22270) "python" sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
3 Thread 0x7fffef9e8700 (LWP 22261) "python" 0x00007ffff6993933 in __GI___poll (fds=<optimized out>, nfds=<optimized out>,
timeout=<optimized out>) at ../sysdeps/unix/sysv/linux/poll.c:87
2 Thread 0x7ffff613f700 (LWP 21988) "python" 0x00007ffff7bcc04d in accept () at ../sysdeps/unix/syscall-template.S:82
1 Thread 0x7ffff7fd6700 (LWP 20970) "python" 0x00007ffff6998653 in select () at ../sysdeps/unix/syscall-template.S:82
(gdb) bt
#0 0x000000000057656d in PyEval_EvalCodeEx ()
#1 0x0000000000577ab0 in function_call.15039 ()
#2 0x00000000004d91b6 in PyObject_Call ()
#3 0x000000000054d8a5 in PyEval_EvalFrameEx ()
#4 0x000000000054c272 in PyEval_EvalFrameEx ()
#5 0x000000000054c272 in PyEval_EvalFrameEx ()
#6 0x000000000054c272 in PyEval_EvalFrameEx ()
#7 0x000000000054c272 in PyEval_EvalFrameEx ()
#8 0x000000000054c272 in PyEval_EvalFrameEx ()
I've installed the package python2.7-dbg to enable the command "py-bt" but it is not more usefull:
(gdb) py-bt
#7 (unable to read python frame information)
#8 (unable to read python frame information)
#16 (unable to read python frame information)
#17 (unable to read python frame information)
#18 (unable to read python frame information)
#27 (unable to read python frame information)
#28 (unable to read python frame information)
#32 (unable to read python frame information)
#33 (unable to read python frame information)
#34 (unable to read python frame information)
I've read somewhere that it's because Python doesn't have the debug symbols then I've tryed the following
gdb -ex r --args python-dbg myscript.py
But it's doesn't work either, I cant even run the program, I have several errors:
ImportError: /usr/lib/python2.7/dist-packages/lxml/etree.so: undefined symbol: Py_InitModule4_64
ImportError: /usr/lib/python2.7/dist-packages/apt_pkg.so: undefined symbol: Py_InitModule4_64
I'm running out of options....
Details about my program: Python: Python 2.7 OS: Ubuntu 12.04 Server-Side Framework : Spyne (ex SoapLib) I also use Pyro on my program which may be the cause of all this. I have disabled the Multithreading on Pyro though
回答1:
Have you tried the built-in gdb module? I mean python -m pdb myscript.py. On top of that you can import gdb and hardcode some breakpoints.
回答2:
I've managed to get a better backtrace by running
gdb -ex r --args python-dbg myscript.py
I've resolved the symbol issues (cf above) by recompiling the package lxml with python-dbg. I had some troubles doing that but it finally worked following the steps:
pip install lxml --download-cache myDir
# for newer pip, use : pip install lxml --download myDir --no-use-wheel
cd myDir
tar -xvf lxml-4.2.1.tar.gz
cd lxml-4.2.1
sudo apt-get install libxslt-dev
sudo apt-get install gcc
sudo apt-get install python-dev
sudo apt-get install python-dbg
sudo python-dbg setup.py install
The following post helped a lot: http://hustoknow.blogspot.fr/2013/06/why-your-python-program-cant-start-when.html
Now I just have to understand the backtrace :-)
回答3:
I've tracked down hard to find fatal errors/segfaults using python's faulthandler from the standard library. It will create a traceback (recent call first) showing which line of code was being executed when python takes a dump.
ex:
import faulthandler
with open("fault_handler.log", "w") as fobj:
faulthandler.enable(fobj)
your_function_to_debug()
It's somewhat more limited than standard python tracebacks, but it's more than sufficient to at least point you in the right direction. From the docs:
Only ASCII is supported. The backslashreplace error handler is used on encoding.
Each string is limited to 500 characters.
Only the filename, the function name and the line number are displayed. (no source code)
It is limited to 100 frames and 100 threads.
The order is reversed: the most recent call is shown first.
来源:https://stackoverflow.com/questions/28108851/catching-segfault-with-debugger-in-python