2018-06-01 centos 7.x 版本下用gdb 调试 python3.6.3 解释器

恭喜你,当你来到这个帖子, 说明pdb的调试功能已经开始满足不了你。

Gdb 在7.0+ 版本上已经支持Python 程序的调试, 但是支持不代表说你系统自带的gdb 已经可以顺利调试python 程序,这还需要一些配置才能正确读取python 的符号 和 额外的命令行脚本。

当运行python 程序出现 core dump的情况下,这时候是程序员最麻烦的时候, 看见segmentation fault 就好比告诉你今晚你要加班的事实。众所周知, 目前安装的python 是由CPython 解释的。这个CPython解释器是用C语言实现的 。 所以在使用gdb 中读取的core 文件都是在C 层面上的调试,看到一大串的PyObject 的指针会让人无从下手。

俗话说的好, 工欲兴其事,必先利其器。 在参考了https://fedoraproject.org/wiki/Features/EasierPythonDebugging 和 http://podoliaka.org/2016/04/10/debugging-cpython-gdb/ 的帖子以后发现, 现在大部分帖子都是在ubuntu 系统安装pythonx.x-dgb 包实现对python2.X版本的调试,却很少帖子是针对python3的 centos调试。 为了解决调试python3 代码, 花了不少时间找资源和询问大腿方法。 这里特意感谢Morgan 大腿的鼎力支持!


1.    条件说明

先明确一点, 目前来说调试python 的条件比较苛刻, 只针对特定版本的python版本 和 centos 系统。

对于 centos6.x 系统, 目前已经开发出的 debuginfo 包是针对python3.4 版本

对于 centos7.x 系统, 目前针对python3.4 和python3.6 版本

如果各位看官能在别的RHEL源里找到别的版本,请及时联系我TAT

debuginfo包地址:

https://dl.fedoraproject.org/pub/epel/7Server/x86_64/debug/Packages/p/python36-debuginfo-3.6.3-7.el7.x86_64.rpm 

这个包是debug 符号, 针对python3.6.3版本

这些debug符号被CPython的脚本 用作分析 PyEval_EvalFrameEx frames(一个frame 代表的函数调用和上下文环境, 例如 函数内部局部变量,cpu寄存器),并且映射到应用层层面的python函数中。


2.  安装Python3.6.3

sudo yum -y groupinstall development  ##安装python3.6 必备依赖

sudo yum -y install zlib-devel  ## 安装zlib 是为了防止后面make和make install出错 

wget http://www.python.org/ftp/python/3.6.3/Python-3.6.3.tgz

tar -xzvf Python-3.6.3.tgz

cd  Python-3.6.3

./comfigure --prefix='/usr/local'  

 ## 这样安装的可执行文件python3.6 位于 /usr/local/bin/python3.6

##  安装后的文件分布  /usr/local +  /bin   /lib  /include /share

make 

sudo make install

中间出错的话 观察报告是否缺少什么依赖的包 直接用yum install 解决


3.    安装epel源 

sudo yum -y install  epel-release   ## -y 表示自动选择yes

sudo yum makecache 

4.   指向epel源文件

sudo vim /etc/yum.repos.d/epel.repo 

## 在这个文件的末尾添加下面的epel源 (一般源地址都带 repodata 文件夹)

[base-epel]

name=EPEL

baseurl=https://dl.fedoraproject.org/pub/epel/7Server/x86_64

gpgcheck=0

enabled=1

##保存文件后退出vim

sudo vim /etc/yum.repos.d/epel-debug.repo

[base-debuginfo-epel]

name=EPEL-DebugInfo

baseurl=https://dl.fedoraproject.org/pub/epel/7Server/x86_64/debug/

gpgcheck=0

enabled=1

4. 安装debuginfo包

yum install python36-debug && debuginfo-install python36-debug-3.6.3-7.el7.x86_64

5. 加载额外的python scripts, 使 gdb 提供如py-bt 的功能

到这一步, 帖主现在都不是很清楚gdb的 auto-load 功能是怎么设置的。所以用了别的方法导入。

该脚本在不同的系统有不同的名字: 如pythonx.x-gdb.py  or libpython.py 

对于centos 系统, 主要使用libpython.py

首先明确一点,该文件适用于Python2.x 和Python 3.x语法。

有一些帖子提及到gdb 会绑定一个python 版本解释器,  在gdb 里输入 

(gdb) py -V

或者

(gdb) python

>import sys

>print(sys.version)

>end

可以查询gdb 当前绑定的python 解释器版本

我个人的观点是, 无论gdb绑定的是什么版本, 只要能读取libpython.py即可。

所以没有必要把gdb 卸载, 然后再手动编译安装gdb(默认的gdb 是绑定操作系统自带的python, centos6 安装的是Python2.6 版本 centos7 安装的是Python2.7) 。


步骤如下:

A. 在你的系统中

    cd /  && sudo find . -name "*libpython*"

    在这里会找到几个类似的文件:

    ../Tools/gdb/libpython.py

    ../libpython3.6m.so-1.0-3.6.3-7.el7.x86_64.debug-gdb.py

    个人比较偏向于用下面的脚本,因为下面的脚本是由debuginfo包生成的


B. vim  ~/.gdbinit

    source /path/to/libpython/py

    举例:

    source ../libpython3.6m.so-1.0-3.6.3-7.el7.x86_64.debug-gdb.py

    保存完成

6. 测试


A . 先写一个会产生段错误的代码: a.py 

import sys

sys.setrecursionlimit(5000000)

def a():

    return a()  ## 无限递归使程序栈空间内存不够

a()

B. 设置产生core文件

ulimit -c unlimited

ulimit -a  ## 查看core file size 大小


C. 调用debug版本的解释器 运行a.py 文件

python3.6-debug a.py  

命令行出现

root @ localadmain: Segmentation Fault


D. 调用Gdb 调试python3.6-debug 解释器

gdb  python3.6-debug  core.XXXXX

(gdb)py-bt

就可以看到经过符号翻译和转换的函数调用栈了。


未调用前:


这里是普通的frame 0  调用栈, 可以看到 f = <error reading variable: cannot access memory at address)

这里的函数调用栈仍然在C 代码中解释, 还没在Python application 层面解释符号

(gdb) py-bt 

调用py-bt 时可以发现已经解释, Python 捕获到一个异常, 是memory error 

这里再次感谢Morgan 大神的鼎力帮助! 


Appendix:

最后附上手动安装gdb时出现的坑

1. ./configure --with-python="/path/to/python3.6"   后面的路径是指向python3.6 可执行文件的, 并且要包含

例如/usr/bin/python3.6

2. ./configure --with-python="/path/to/python3.6"  --prefix="destination path" 有时 --prefix 会检测不到  目前还没知道怎么解决

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容