美文网首页学习了
2018-06-01 centos 7.x 版本下用gdb 调试

2018-06-01 centos 7.x 版本下用gdb 调试

作者: 罗兆峰 | 来源:发表于2018-06-01 16:55 被阅读979次

恭喜你,当你来到这个帖子, 说明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 会检测不到  目前还没知道怎么解决

相关文章

  • 2018-06-01 centos 7.x 版本下用gdb 调试

    恭喜你,当你来到这个帖子, 说明pdb的调试功能已经开始满足不了你。 Gdb 在7.0+ 版本上已经支持Pytho...

  • GDB调试环境配置

    GDB调试环境配置 GDB安装 在调试的时候,会提示如下信息 首先需要修改CentOS-Debuginfo.rep...

  • iOS_LLDB 调试命令

    GDB 和LLDB LLDB 在xcode4.3或者之后的版本里面默认的调试器,在这之前用的就是GDB。 LLDB...

  • 用gdb调试代码

    title: 用gdb调试代码tags: gdbdate: 2017-08-09 15:09:22 gdb调试 开...

  • linux编程入门(七)-使用gdb调试程序

    程序开发离不开调试,可以断点调试,也可以打log调试,linux下断点调试c,c++程序用gdb。 断点调试虽然很...

  • GDB在mac上安装与运行

    what gdb? Gdb是一款代码调试工具。Mac下依旧支持,但是由于MacOS系统本身以及版本不协调等原因使用...

  • linux Vim gcc gdb 等配置

    vim配置将vim打造成c++编译器CentOs下安装gcc/g++/gdbcentos学习笔记--gdb调试部分...

  • Pwnable.kr系列--bof(3)

    明显可以看出gets(overflowme)中存在栈溢出,用gdb调试一下 gdb .bof 在main函数处设个...

  • PWN入门到放弃

    Linux下的pwn常用到的工具有: gdb:Linux调试中必要用到的 gdb-peda:gdb方便调试的工具,...

  • PHP7.0安装

    更新yum源 系统版本CentOS/RHEL 7.x: CentOS/RHEL 6.x: php7.0安装 上述命...

网友评论

    本文标题:2018-06-01 centos 7.x 版本下用gdb 调试

    本文链接:https://www.haomeiwen.com/subject/edkksftx.html