This post aims to introduce a very useful tool to debug low-level issues in Python, how to enhance it and finally how to solve two annoying common problems.
1. Debugging Python with gdb
All the basics are there : https://wiki.python.org/moin/DebuggingWithGdb
gdb -p $(pgrep -f your_running_python_program_name)
2. Installing the macros for Python
A set of GDB macros are distributed with Python that aid in debugging the Python process. (from: https://wiki.python.org/moin/DebuggingWithGdb#GDB_Macros).
One-liner to install those macros:
curl --silent http://svn.python.org/projects/python/trunk/Misc/gdbinit >> ~/.gdbinit
There is a minor fix to the
lineno macro to make:
sed -i 's/printf "%d", $__li/printf "%d", $__li + 1/' ~/.gdbinit
Usage example taken from the comments:
Quoted from: Python SVN Misc/.gdbinit
(gdb) pyo apyobjectptr <module 'foobar' (built-in)> refcounts: 1 address : 84a7a2c $1 = void
Some other useful macros:
List them all with:
grep define ~/.gdbinit.
3. Persistent history & colored prompt
The following command will append some lines to your ~/.gdbinit configuration file in order to keep a persistent history between your gdb sessions, and to set a very useful colored prompt:
cat <<END >> ~/.gdbinit # Custom configuration by USER=$USER ## Persistent history: set history save set history filename ~/.gdb_history ## Colored prompt: set prompt \001\033[1;32m\002(gdb)\001\033[0m\002\040 END
4. Solving: 'ptrace: Operation not permitted'
DO NOT SET THE SUID/SGID BIT :
sudo chmod +s /usr/bin/gdb
As explained in the comments (thanks to Romain Geissler), this solution I initially recommended actually creates a security vulnerability.
A better solution looks to be :
echo 0 > /proc/sys/kernel/yama/ptrace_scope # to execute as root
kernel.yama.ptrace_scope = 0 in /etc/sysctl.d/10-ptrace.conf.
5. Solving: 'No symbol "co" in current context'
This one is trickier. It's a known issue described in https://wiki.python.org/moin/DebuggingWithGdb#GDB_Macros. The recommended solution is to
Recompile python with make CFLAGS=-g -fno-inline -fno-strict-aliasing (the alternative patch did not work for me).
Yeah, I know, SIGH...
But it's in fact not so difficult to built a stand-alone python interpreter:
dbg_py_v=2.7.8; dbg_py=Python-$dbg_py_v mkdir /opt; cd /opt curl -L http://python.org/ftp/python/$dbg_py_v/$dbg_py.tar.xz | tar xJvf - cd $dbg_py ./configure --prefix=/usr/local --enable-unicode=ucs4 --disable-shared LDFLAGS="-Wl,-rpath /usr/local/lib" make -j3 "CFLAGS=-g -fno-inline -fno-strict-aliasing"
export PYTHONPATH=... # can be extracted from the original script with print('\n'.join(sys.path)) /opt/$dbg_py/python your_python_program
And no more "undefined symbol" error message in
EDIT: Actually, if your
gdb version has been compiled with python support (
gdb --batch --quiet -ex 'show configuration' | grep with-python), no need to download any .gdbinit file !
You can replace all those macros definition by this single line in your .gdbinit (after manually replacing the $dbg_py variable) :
You now have access to all the following commands:
- py-down / py-up
On the other hand, the latest version of the gdbinit file on the new Mercurial repository doesn't seem to work: https://hg.python.org/cpython/raw-file/default/Misc/gdbinit. I get a 'No symbol "_PyUnicode_AsString" in current context.' error message.
EDIT (2016/04/15): a more recent article on the subject : http://podoliaka.org/2016/04/10/debugging-cpython-gdb/
The following commands taken from this article helped me once:
yum install python33-python-debuginfo glibc-debuginfo # from base-debuginfo repository - can also be installed with: debuginfo-install ...