Python 跟踪段错误

60 投票
7 回答
58210 浏览
提问于 2025-04-15 21:45

我正在从Python开发C扩展,但在开发过程中遇到了一些段错误(这在开发中是不可避免的……)。

我想找到一种方法,能够显示段错误发生在哪一行代码上(我想的办法是像追踪每一行代码一样),我该怎么做呢?

7 个回答

19

在使用C扩展时,出现段错误(segfault)通常是因为在创建对象的新引用时没有增加引用计数。这种错误很难找到,因为段错误只会在最后一个引用被移除后才发生,而且通常是在分配其他对象时才会出现。

你没有说明你写了多少C扩展代码,但如果你刚开始,可以考虑使用ctypes或者Cython。ctypes可能不够灵活,但使用Cython你几乎可以链接到任何C库,并且引用计数会自动为你维护。

不过,这并不总是够的:如果你的Python对象和底层的C对象的生命周期不同,仍然可能会出现问题,但这样做确实能大大简化事情。

103

如果你在使用Linux系统,可以在gdb这个工具下运行python。

gdb python
(gdb) run /path/to/script.py
## wait for segfault ##
(gdb) backtrace
## stack trace of the c code
49

这里有一种方法,可以输出你运行的每一行Python代码的文件名和行号:

import sys

def trace(frame, event, arg):
    print("%s, %s:%d" % (event, frame.f_code.co_filename, frame.f_lineno))
    return trace

def test():
    print("Line 8")
    print("Line 9")

sys.settrace(trace)
test()

输出结果:

call, test.py:7
line, test.py:8
Line 8
line, test.py:9
Line 9
return, test.py:9

(当然,你可能会想把这些追踪信息写到一个文件里。)

撰写回答