这篇文章的主要应用场景是调试Python的C/C++ Extension
- 同时使用pdb / gdb 进行调试. 通俗点说, 既可以break在 .py 文件中,也可以break在 .cc 文件中
- 在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:
- 如果有任何问题, 参考 https://github.com/python/cpython 进行编译
make install
也会直接安装好pip, 如果没有,可以参考: https://pip.pypa.io/en/stable/installation/- 如果调试涉及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/