Python脚本在使用gdb调试时常会遇到的三个“克星”

Phoenixor 2010-03-26

使用gdb调试Python脚本

我们在实际调试python脚本中一般可以用记录log和python本身自带的pdb,当然这是在一般的情况下,以下的文章就会提出一些运用log和python本身自带的pdb却不能解决的相关情况的相关介绍。 但凡事总有例外,在以下三种情况时上述方法就无能为力了。
1 段错误

2 运行中的daemon程序

3 core dump

这个时候就需祭出gdb进行调试。python2.6的源码中提供了部分预定义函数以便大家使用gdb调试,我们只需将文件Python-2.6/Misc/gdbinit所包括的内容加入到用户目录下的.gdbinit文件中即可,这样每次启动gdb时会自动完成这些宏的定义。但可惜的是Python2.6.2 gdbini对于pylocals的定义居然有错误, 看来是没有随着代码的更新而同步更新。

我们只需将

while $_i < f->f_nlocals 

修改为

while $_i < f->f_code->co_nlocals 

即可。文章后面所附的几个宏建议也加入的.gdbinit文件中,更多的宏可参考我们首先需要构造一个会造成段错误的python脚本。老实说让python发生段错误并不容易,但通过其外部调用库就很简单了。我们将该文件命名为gdb_test.py

import sys, os, libxml2  


def segv_test():  



s = "<html><body><div><a><a></a></a><a></a></div></body></html>" 




options = libxml2.HTML_PARSE_RECOVER + \  



libxml2.HTML_PARSE_NOERROR + \  


libxml2.HTML_PARSE_NOWARNING  



doc = libxml2.htmlReadDoc(s, None, 'utf-8', options).doc  




ctxt = doc.xpathNewContext()  




nodes = ctxt.xpathEval('//body/node()')  



nodes.reverse()  


for note in nodes:  



nexts = note.xpathEval('node()')  



note.unlinkNode()   


note.freeNode()  

freeNode会将该节点及其子节点释放掉

nexts[0].unlinkNode()   


nexts[0].freeNode()  

资源已经释放,再次释放会造成段错误

def main():  


segv_test()  



if __name__ == "__main__":  



main()  

使用gdb运行该脚本,我们会得到段错误信息。

相关推荐