使用GDB进行Python内存调试

5
我们有一个Linux应用程序,它使用OpenSSL的Python绑定,我怀疑它会导致随机崩溃。偶尔,我们会看到它崩溃并显示以下消息:

“Python致命错误:GC对象已被跟踪”,这似乎是库方面的编程错误或者内存损坏的症状。是否有任何方法可以知道给定核心文件时它执行的最后一行Python源代码?或者如果它被附加在GDB中呢?我意识到它可能全部是编译的字节码,但我希望有人能够处理这个问题。目前它正在运行,启用了trace模块,我们希望它再次发生,但这可能需要很长时间。

你在64位Linux上使用这个程序吗? - Douglas Mayle
4个回答

5

是的,您可以做这样的事情:

(gdb) print PyRun_SimpleString("import traceback; traceback.print_stack()")
  File "<string>", line 1, in <module>
  File "/var/tmp/foo.py", line 2, in <module>
    i**2
  File "<string>", line 1, in <module>
$1 = 0

还可以使用在Python gdbinit 文件中定义的 pystack 命令,但对我来说没有用。如果您想了解更多信息,可以在此处查看

另外,如果您怀疑存在内存问题,值得注意的是,您可以重新编译Python并使用valgrind。详细的步骤请参考此处


如果我没记错的话,gdbinit文件需要更改,因为.c文件中函数的顺序已经改变。这是我上次使用gdb+python时的情况。我应该提交一个补丁... - Tony Arkles
太棒了,我会在gdb下让它运行,并希望它在周末崩溃。 - Matt Green
之前没有注意到,但核心转储位于不同的位置。这几乎肯定是内存损坏。非常感谢! - Matt Green
没问题,马特。托尼,pystack命令失败是因为它引用了一个当前框架中不存在的变量“co”。 - Alex Coventry

1

如果你有Mac或Sun Box,你可以使用dtrace和一个编译了dtrace的Python版本来找出应用程序在运行时正在做什么。注意:在10.5中,Python已经预编译了dtrace,这非常方便。

如果这对你不可用,那么你可以import gc并启用调试,然后将其输出到日志文件中。

为了具体回答你关于使用GDB进行调试的问题,你可能想阅读Python维基上的“Debugging With GDB”。


0
如果您正在使用CDLL将C库包装在Python中,并且这是64位Linux,则很有可能您的CDLL包装程序配置错误。 在所有平台上,CDLL默认为int返回类型(应该是64位系统上的long long),并且只期望您传递正确的参数。 在这种情况下,您可能需要验证CDLL包装程序...

0

除了以上所有内容,您还可以通过跟踪模块快速实现一个特定的跟踪器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接