如何调试Python分段错误?

问题描述 投票:0回答:5

如何调试 Python 分段错误?

我们正在尝试在 SuSE 12.3 上运行我们的 python 代码。我们得到可重现的分段错误。多年来,Python 代码一直在其他平台上运行,没有出现分段错误。

我们只编写Python代码,没有C扩展....

调试此问题的最佳方法是什么?我懂一点ansi c,但那是十年前的事了....

Python 2.7.5

更新

解释器关闭时发生分段错误。

我可以多次运行脚本:

python -m pdb myscript.py arg1 arg1
continue
run
continue
run

但是,如果我用 ctrl-d 离开 pdb,就会发生分段错误。

更新2

我现在尝试用gdb调试它:

gdb 
> file python
> run myscript.py arg1 arg2
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffefbe2700 (LWP 15483)]
0x00007ffff7aef93c in PyEval_EvalFrameEx () from /usr/lib64/libpython2.7.so.1.0
(gdb) bt
#0  0x00007ffff7aef93c in PyEval_EvalFrameEx () from /usr/lib64/libpython2.7.so.1.0
#1  0x00007ffff7af5303 in PyEval_EvalCodeEx () from /usr/lib64/libpython2.7.so.1.0
#2  0x00007ffff7adc858 in ?? () from /usr/lib64/libpython2.7.so.1.0
#3  0x00007ffff7ad840d in PyObject_Call () from /usr/lib64/libpython2.7.so.1.0
#4  0x00007ffff7af1082 in PyEval_EvalFrameEx () from /usr/lib64/libpython2.7.so.1.0
#5  0x00007ffff7af233d in PyEval_EvalFrameEx () from /usr/lib64/libpython2.7.so.1.0
#6  0x00007ffff7af233d in PyEval_EvalFrameEx () from /usr/lib64/libpython2.7.so.1.0
#7  0x00007ffff7af5303 in PyEval_EvalCodeEx () from /usr/lib64/libpython2.7.so.1.0
#8  0x00007ffff7adc5b6 in ?? () from /usr/lib64/libpython2.7.so.1.0
#9  0x00007ffff7ad840d in PyObject_Call () from /usr/lib64/libpython2.7.so.1.0
#10 0x00007ffff7ad9171 in ?? () from /usr/lib64/libpython2.7.so.1.0
#11 0x00007ffff7ad840d in PyObject_Call () from /usr/lib64/libpython2.7.so.1.0
#12 0x00007ffff7aeeb62 in PyEval_CallObjectWithKeywords () from /usr/lib64/libpython2.7.so.1.0
#13 0x00007ffff7acc757 in ?? () from /usr/lib64/libpython2.7.so.1.0
#14 0x00007ffff7828e0f in start_thread () from /lib64/libpthread.so.0
#15 0x00007ffff755c7dd in clone () from /lib64/libc.so.6

更新3

我从 http://hg.python.org/cpython/file/default/Misc/gdbinit 安装了 gdbinit 以及来自 http://download.opensuse.org/debug/distribution/12.3/repo/oss/suse/x86_64/

的调试符号
(gdb) pystack
No symbol "_PyUnicode_AsString" in current context.

现在怎么办?

更新4 我们安装了新的 RPM (python-2.7.5-3.1.x86_64)。我们遇到的段错误较少,但它们仍然会发生。 这是存储库的链接:

http://download.opensuse.org/repositories/devel:/languages:/python:/Factory/openSUSE_12.3/x86_64/

更新5 解决了我最初的问题:

它是 http://bugs.python.org/issue1856(关闭(退出)可能会在守护进程线程运行时挂起或出现段错误)

相关:检测解释器在守护线程中关闭

python segmentation-fault
5个回答
89
投票

我之所以提出这个问题是因为

Segmentation fault
,但不是在退出时,只是一般而言,我发现没有什么比faulthandler更有效的帮助了。它是 Python 3.3 的一部分,您可以使用
pip
在 2.7 中安装。

要启用故障处理程序,只需设置

PYTHONFAULTHANDLER
环境变量

PYTHONFAULTHANDLER=1 python myscript.py

83
投票

tl;dr 对于 python3 用户。

首先,来自文档:

faulthandler是Python 3.3以来的内置模块

代码使用:

import faulthandler

faulthandler.enable()
// bad code goes here

外壳用途:

$ python3 -q -X faulthandler
>>> /// bad cod goes here

12
投票

也许有一个守护线程正在运行?有一个可重现的错误,仅针对 3.x 进行了修复,但未针对 2.x 进行了修复:

http://bugs.python.org/issue1856

shutdown (exit) can hang or segfault with daemon threads running

这是我自己问题的答案。花了一些时间才找到问题的根源。

这是下一个问题:如何围绕此错误进行编码:检测解释器在守护进程线程中关闭


12
投票

您可以使用提到的错误处理程序来执行此操作。例如

import faulthandler; faulthandler.enable()

只需在

import
语句附近添加此行并运行代码即可。它将帮助您调试或尝试向您显示代码中导致分段错误的最近行。然后您可以在需要的地方进行更改。


7
投票

如果您只执行 Python 代码(即使通过导入的第三方模块),则段错误可能意味着解释器或其内置 C 模块之一存在错误。

您可以构建 CPython 并尝试自己调试它,或者尝试生成重现崩溃的最小脚本并提交问题

© www.soinside.com 2019 - 2024. All rights reserved.