gdb调试python运行中的进程

本文详细介绍了如何使用含有调试符号的Python版本(python-dbg)及GDB调试器解决Python脚本运行过程中遇到的假死问题,并提供了实际案例演示调试过程。
       python虽然是脚本语言,但有时候也会出一些奇怪的问题,比如假死之类 的。对脚本语言来说,调试比较简单,加个print语句就可以了,这也是比较原始的方法,简单的问题print基本上可以解决,但复杂的问题,还是得通过调试器来辅助啊。最近就碰到比较棘手的问题,一个python爬虫进程运行一周之后就假死了,不知道是什么原因导致的,这个爬虫进程要是C写的二进制程序就好办了,直接gdb attach上去就知道了,但是python进程就不好搞了,主要是之前没弄过没经验。遇到越难的问题我就越想搞定它,因为搞定之后就瞬间觉得自己的帅气指数暴涨,哈哈,言归正传,看咋解决吧:
      首先从python官方文档: https://wiki.python.org/moin/DebuggingWithGdb   得知,先安装python2.7-dbg,就是有调试符号的python版本,自己手工源码编译加上--with-pydebug参数应该也可以。
      其次看gdb的版本,7.4以上的应该直接支持,否则自己源码编译或者重新安装一个,源码编译的话加上--with-python选项。验证一下gdb是否支持python:
root@jusse ~# gdb 
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 <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: 
<http://bugs.launchpad.net/gdb-linaro/>. 
(gdb) python 
>print 'Hello' 
>end 
Hello 
(gdb) 
在gdb里面执行python命令如果不报错的话就可以了。
        最后就是调试python程序了,我之前根据网上一些文章和官方文档始终不成功,在gdb里面执行py-bt要么没有信息要么报这个错:(unable to read python frame information),放弃了几天,后来在stackoverflow一个帖子上找到了灵感,其实就是用含有调试符号的python来运行脚本,也就是用python-dbg或者python2.7-dbg来运行py脚本程序,写了个简单的程序:
#!/usr/bin/env python
#filename: cc_py_gdb.py

import time

while True:
    print '=' * 100
    time.sleep(10)
运行这个python程序:
# python-dbg ./cc_py_gdb.py
ps看一下PID:
# ps -ef | grep cc_py_gdb
root 1287 1092 0 18:18 pts/0 00:00:00 python-dbg ./cc_py_gdb.py
最后我们gdb attach上去看看:
# gdb -q python-dbg -p 1287
Reading symbols from /usr/bin/python-dbg...done.
Attaching to program: /usr/bin/python-dbg, process 1287
Reading symbols from /lib/x86_64-linux-gnu/libpthread.so.0...Reading symbols from /usr/lib/debug/lib/x86_64-linux-gnu/libpthread-2.15.so...done.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
done.
Loaded symbols for /lib/x86_64-linux-gnu/libpthread.so.0
Reading symbols from /lib/x86_64-linux-gnu/libdl.so.2...Reading symbols from /usr/lib/debug/lib/x86_64-linux-gnu/libdl-2.15.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libdl.so.2
Reading symbols from /lib/x86_64-linux-gnu/libutil.so.1...Reading symbols from /usr/lib/debug/lib/x86_64-linux-gnu/libutil-2.15.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libutil.so.1
Reading symbols from /lib/x86_64-linux-gnu/libssl.so.1.0.0...(no debugging symbols found)...done.
Loaded symbols for /lib/x86_64-linux-gnu/libssl.so.1.0.0
Reading symbols from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0...(no debugging symbols found)...done.
Loaded symbols for /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
Reading symbols from /lib/x86_64-linux-gnu/libz.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/x86_64-linux-gnu/libz.so.1
Reading symbols from /lib/x86_64-linux-gnu/libm.so.6...Reading symbols from /usr/lib/debug/lib/x86_64-linux-gnu/libm-2.15.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libm.so.6
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.15.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.15.so...done.
done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2

warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7fff11dfe000
0x00007f9dde67f663 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:82
82 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) py-bt
#5 Frame 0x10a26c0, for file ./cc_py_gdb.py, line 7, in <module> ()
    time.sleep(10)
(gdb) py-list
   2
   3 import time
   4
   5 while True:
   6 print '=' * 100
  >7 time.sleep(10)
   8
(gdb) q
从结果上看符合预期了,剩下的就是GDB的调试技巧了,这里就不讲了,本文主要讲GDB调试python程序时无法找到调试符号的解决办法。

      最主要的是运行python脚本时要用python-dbg或者python2.7-dbg,gdb的参数也要用相应的python-dbg或者python2.7-dbg,否则可能找不到符号哦。

参考文章:

(全文完)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值