加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

gdb调试python程序中无“py-bt”命令的原因分析[转]

(2014-01-17 15:53:19)
分类: python
转载地址:http://backend.blog.163.com/blog/static/202294126201352174057579/

有时我们需要使用gdb对python进行调试。网上很多文章都写了方法:
gdb -p一个python进程上去,然后使用py-bt命令就可以看到目前这个python程序运行到哪儿:


osdba@osdba-work:~/src/pytest$ sudo gdb -p 7194
....
....
0x00007fda5b938030 in __accept_nocancel () from /lib/x86_64-linux-gnu/libpthread.so.0
(gdb) py-bt
#3 (frame information optimized out)
#6 Frame 0x23e25c0, for file t1.py, line 19, in ()
connection, address = sock.accept()
而有些环境下,我们会发现在gdb中没有py-bt这个命令,从原理上说gdb7.1以上就支持对python的调试了,难道是gdb的版本过低的原因:


root@ubuntu01:~# gdb -v
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <</span>http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<</span>http://bugs.launchpad.net/gdb-linaro/>.

我们使用的gdb的版本是7.4了,不是gdb版本的问题
这时有人发现在ubuntu下,只要安装了python-dbg包后,再调试python程序时,就有了py-bt命令。细心的人还会发现,当使用gdb 调试C语言编写的程序时,会发现也没有py-bt等命令,最后得出一个结论:
gdb是“智能的”,它能检测出你调试的程序是否是python程序,同时能智能的感知你是否安装了python-dbg的包,如果是这样,就会有py-bt等命令。
下面就给大家讲解gdb这个“智能"是如何实现的。
先要说gdb的一个功能:
当gdb调试一个可执行程序时,会自动装载一个python脚本,假设gdb调试的程序为:


gdb /usr/bin/myprog
gdb会自动装载一个名字叫myprog-gdb.py的脚本文件。通过这个脚本文件可以给gdb增加一个自定义的命令。这时有人就问了,这会不会带来安全问题,设计gdb的人也想到了这个问题,这个脚本文件并不是与程序在同一个目录下的,而是在指定的一个安全目录,这样只要这个安全目录不被人乱写,则不存在这个问题。这个安全目录的设置为:


(gdb) show auto-load safe-path
List of directories from which it is safe to auto-load files is $debugdir:$datadir/auto-load.
可从上面看出,安装目录配置为“$debugdir:$datadir/auto-load",其中的路径设置与PATH环境变量的设置是相同的,多个路径都是使用冒号分隔。
而$debugdir是指debug-file-directory这个目录:


(gdb) show debug-file-directory
The directory where separate debug symbols are searched for is "/usr/lib/debug".
我们可以看到,这个目录是指向/usr/lib/debug的。而我们用gdb调试python程序,实际上是调试/usr/bin/python2.7这个程序,所以,当调试python程序时,gdb会自动装载一个python脚本,名称应该叫:


/usr/lib/debug/usr/bin/python2.7-gdb.py
我们ls -l 一样,果然可以看到这个程序:


osdba@osdba-work:~$ ls -l /usr/lib/debug/usr/bin
total 6456
-rw-r--r-- 1 root root 6561706 Sep 27  2012 python2.7
lrwxrwxrwx 1 root root      16 Sep 27  2012 python2.7-dbg-gdb.py -> python2.7-gdb.py
-rwxr-xr-x 1 root root   48368 Sep 27  2012 python2.7-gdb.py
我们再看这个文件是哪个包中的:


osdba@osdba-work:~$ dpkg -S /usr/lib/debug/usr/bin/python2.7-gdb.py
python2.7-dbg: /usr/lib/debug/usr/bin/python2.7-gdb.py
看到了,这个文件是python2.7-dbg包。
这样前面的疑惑都解决了。如果我们没有安装python2.7-dbg这个包(当安装python-dbg这个包时,自动会根据当前python 的版本而安装python2.7-dbg),因为没有/usr/lib/debug/usr/bin/python2.7-gdb.py这个脚本,所以在gdb中无法使用"py-bt"调试。另当使用gdb调试C语言的编译的程序时,从上面的原理看,也不会装载/usr/lib/debug/usr/bin/python2.7-gdb.py,所以在gdb中也不会出现“py-bt”这个命令了。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有