106

我正在 Python 中实现 Kosaraju 的强连通分量 (SCC) 图搜索算法。

该程序在小型数据集上运行良好,但是当我在超大图(超过 800,000 个节点)上运行它时,它显示“分段错误”。

可能是什么原因造成的?谢谢!


附加信息:首先我在超大数据集上运行时遇到此错误:

"RuntimeError: maximum recursion depth exceeded in cmp"

然后我使用重置递归限制

sys.setrecursionlimit(50000)

但出现“分段错误”

相信我,这不是一个无限循环,它在相对较小的数据上运行正确。程序有可能耗尽资源吗?

4

8 回答 8

87

当 Python扩展(用 C 编写)尝试访问无法访问的内存时,就会发生这种情况。

您可以通过以下方式对其进行跟踪。

  • sys.settrace在代码的第一行添加。
  • 按照Mark此答案gdb中的描述使用.. 在命令提示符下

    gdb python
    (gdb) run /path/to/script.py
    ## wait for segfault ##
    (gdb) backtrace
    ## stack trace of the c code
    
于 2012-04-05T20:32:53.470 回答
59

我知道您已经解决了您的问题,但是对于阅读此线程的其他人,答案是:您必须增加操作系统为 python 进程分配的堆栈。

这样做的方法取决于操作系统。在linux中,您可以使用命令检查ulimit -s您的当前值,您可以使用ulimit -s <new_value>

尝试将先前的值加倍,如果它不起作用,则继续加倍,直到找到一个值或内存不足。

于 2012-07-06T19:19:45.147 回答
22

分段错误是一种通用错误,可能的原因有很多:

  • 记忆不足
  • 内存故障
  • 使用查询从数据库中获取大量数据集(如果获取的数据大小超过交换内存)
  • 错误的查询/错误代码
  • 有长循环(多次递归)
于 2013-11-04T21:04:58.330 回答
3

通过修复 Python(Python segfault.. 谁知道!)和 C++ 实现上的段错误,更新 ulimit 对我的 Kosaraju 的 SCC 实现有效。

对于我的 MAC,我通过以下方式找到了可能的最大值:

$ ulimit -s -H
65532
于 2016-11-18T04:08:19.690 回答
3

谷歌搜索找到了我这篇文章,并没有看到下面讨论的“个人解决方案”。


我最近对适用于 Linux 的 Windows 子系统上的 Python 3.7 的烦恼是:在两台具有相同 Pandas 库的机器上,一台给我segmentation fault,另一台报告警告。目前尚不清楚哪个更新,但“重新安装”pandas解决了问题。

我在有问题的机器上运行的命令。

conda install pandas

更多细节:我正在运行相同的脚本(通过 Git 同步),两者都是带有 WSL + Anaconda 的 Windows 10 机器。这里是截图来说明情况。此外,在命令行python会抱怨的机器上Segmentation fault (core dumped),Jupyter 实验室每次都会简单地重新启动内核。更糟糕的是,根本没有发出警告。

在此处输入图像描述


几个月后更新:我不再在 Windows 机器上托管 Jupyter 服务器。我现在在 Windows 上使用 WSL 来获取在 Linux 服务器上打开的远程端口,并在远程 Linux 机器上运行我的所有作业。我已经好几个月没有遇到任何执行错误了:)

于 2019-02-10T18:19:20.683 回答
0

在 RPI 上升级 dlib 后,我遇到了这个分段错误。我按照上面 Shiplu Mokaddim 的建议追溯了堆栈,并确定了一个 OpenBLAS 库。

由于 OpenBLAS 也是多线程的,因此在多线程应用程序中使用它会成倍增加线程,直到出现分段错误。对于多线程应用程序,将 OpenBlas 设置为单线程模式。

在 python 虚拟环境中,通过编辑告诉 OpenBLAS 只使用一个线程:

    $ workon <myenv>
    $ nano .virtualenv/<myenv>/bin/postactivate

并添加:

    export OPENBLAS_NUM_THREADS=1 
    export OPENBLAS_MAIN_FREE=1

重新启动后,我能够在 rpi3b 上运行我之前崩溃的所有图像识别应用程序。

参考: https ://github.com/ageitgey/face_recognition/issues/294

于 2019-03-22T12:42:55.067 回答
0

看起来你的堆栈内存不足。正如戴维德所说,您可能希望增加它。要在 python 代码中执行此操作,您需要使用线程运行“main()”:

def main():
    pass # write your code here

sys.setrecursionlimit(2097152)    # adjust numbers
threading.stack_size(134217728)   # for your needs

main_thread = threading.Thread(target=main)
main_thread.start()
main_thread.join()

资料来源:c1729 在 codeforces 上的帖子。用 PyPy 运行它有点棘手

于 2020-04-12T21:02:29.803 回答
0

我会遇到同样的错误。我从另一个 SO 答案中了解到,您需要通过sysresource模块设置递归限制。

于 2021-11-12T02:30:15.073 回答