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程序运行到哪儿:
这时有人发现在ubuntu下,只要安装了python-dbg包后,再调试python程序时,就有了py-bt命令。细心的人还会发现,当使用gdb 调试C语言编写的程序时,会发现也没有py-bt等命令,最后得出一个结论:
gdb是“智能的”,它能检测出你调试的程序是否是python程序,同时能智能的感知你是否安装了python-dbg的包,如果是这样,就会有py-bt等命令。
下面就给大家讲解gdb这个“智能"是如何实现的。
先要说gdb的一个功能:
当gdb调试一个可执行程序时,会自动装载一个python脚本,假设gdb调试的程序为:
而$debugdir是指debug-file-directory这个目录:
这样前面的疑惑都解决了。如果我们没有安装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”这个命令了。
gdb -p一个python进程上去,然后使用py-bt命令就可以看到目前这个python程序运行到哪儿:
而有些环境下,我们会发现在gdb中没有py-bt这个命令,从原理上说gdb7.1以上就支持对python的调试了,难道是gdb的版本过低的原因:
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的版本是7.4了,不是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/>.
这时有人发现在ubuntu下,只要安装了python-dbg包后,再调试python程序时,就有了py-bt命令。细心的人还会发现,当使用gdb 调试C语言编写的程序时,会发现也没有py-bt等命令,最后得出一个结论:
gdb是“智能的”,它能检测出你调试的程序是否是python程序,同时能智能的感知你是否安装了python-dbg的包,如果是这样,就会有py-bt等命令。
下面就给大家讲解gdb这个“智能"是如何实现的。
先要说gdb的一个功能:
当gdb调试一个可执行程序时,会自动装载一个python脚本,假设gdb调试的程序为:
gdb会自动装载一个名字叫myprog-gdb.py的脚本文件。通过这个脚本文件可以给gdb增加一个自定义的命令。这时有人就问了,这会不会带来安全问题,设计gdb的人也想到了这个问题,这个脚本文件并不是与程序在同一个目录下的,而是在指定的一个安全目录,这样只要这个安全目录不被人乱写,则不存在这个问题。这个安全目录的设置为:
gdb /usr/bin/myprog
可从上面看出,安装目录配置为“$debugdir:$datadir/auto-load",其中的路径设置与PATH环境变量的设置是相同的,多个路径都是使用冒号分隔。
(gdb) show auto-load safe-path
List of directories from which it is safe to auto-load files is $debugdir:$datadir/auto-load.
而$debugdir是指debug-file-directory这个目录:
我们可以看到,这个目录是指向/usr/lib/debug的。而我们用gdb调试python程序,实际上是调试/usr/bin/python2.7这个程序,所以,当调试python程序时,gdb会自动装载一个python脚本,名称应该叫:
(gdb) show debug-file-directory
The directory where separate debug symbols are searched for is "/usr/lib/debug".
我们ls -l 一样,果然可以看到这个程序:
/usr/lib/debug/usr/bin/python2.7-gdb.py
我们再看这个文件是哪个包中的:
osdba@osdba-work:~$ ls -l /usr/lib/debug/usr/bin
total 6456
-rw-r--r-- 1 root root 6561706 Sep 272012 python2.7
lrwxrwxrwx 1 root root16 Sep 27 2012 python2.7-dbg-gdb.py -> python2.7-gdb.py
-rwxr-xr-x 1 root root48368 Sep 27 2012 python2.7-gdb.py
看到了,这个文件是python2.7-dbg包。
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这个包(当安装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”这个命令了。