GDB with Python

这篇文章的主要应用场景是调试Python的C/C++ Extension

  1. 同时使用pdb / gdb 进行调试. 通俗点说, 既可以break在 .py 文件中,也可以break在 .cc 文件中
  2. 在gdb中不但可以获得常规的调试信息, 还可以获得python VM 的调试信息, 例如获得python的调用栈, 访问Python局部变量等. 这将会在调试exception时(如Segmentfalut)非常有用, 这种场景下, 定位 Python VM 正运行到哪一行代码往往可以提供一些直观的重要信息.

第一步: 编译源码以获得一些辅助数据.

我们并不真的需要使用从源码编译的Python, 但是一些调试相关的辅助文件需要从源码中获得, 包括 python-gdb.py及debug symbol等.

https://www.python.org/ftp/python/https://github.com/python/cpython 获得与你当前使用Python版本一致的源码.

一般而言,可以直接使用下面的指令

mkdir build
cd build
../configure --prefix=/path/to/install
make
make install

Note:

  1. 如果有任何问题, 参考 https://github.com/python/cpython 进行编译
  2. make install 也会直接安装好pip, 如果没有,可以参考: https://pip.pypa.io/en/stable/installation/
  3. 如果调试涉及Python自身的代码, 可以使用 –with-pydebug 进行编译. 需要注意, Python 3.8 之前 ,Debug 和 Release 的 ABI 是不同的, 这意味着,为 Release 编译的 C-Extension(包括第三方的) 可能不能在Debug版本下正常工作

第二步

设置autoloadpath

在C-Extension Load之后, 用 gdb attach 到 Python 进程中, 此时你应该可以直接break 在 C-Extension 的源码中.

在gdb中
source /path/to/source/build/python-gdb.py ,这样可以使能py-bt等调试指令.

参考 python-gdb的使用说明 https://devguide.python.org/gdb/