什么原因导致Python分段错误?

时间:2012-04-05 20:28:56

标签: python segmentation-fault large-data

我正在用Python实现Kosaraju的强连接组件(SCC)图搜索算法。

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

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


其他信息: 首先,我在超大型数据集上运行时出现此错误:

"RuntimeError: maximum recursion depth exceeded in cmp"

然后我使用

重置递归限制
sys.setrecursionlimit(50000)

但得到了“分段错误”

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

7 个答案:

答案 0 :(得分:63)

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

您可以通过以下方式跟踪它。

  • 在代码的第一行添加sys.settrace
  • 使用this answer标记所述的gdb ..在命令提示符下

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

答案 1 :(得分:48)

我知道你已经解决了你的问题,但是对于其他读这个帖子的人来说,答案就是:你必须增加操作系统为python进程分配的堆栈。

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

增加它

尝试将前一个值加倍并继续加倍,如果它不起作用,直到找到一个执行或耗尽内存的值。

答案 2 :(得分:11)

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

  • 内存不足
  • Ram Ram memory
  • 使用查询从数据库中获取大量数据集(如果获取的数据大小超过交换内存)
  • 错误的查询/错误代码
  • 有长循环(多次递归)

答案 3 :(得分:2)

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

对于我的MAC,我发现了可能的最大值:

$ ulimit -s -H
65532

答案 4 :(得分:0)

Google搜索找到了这篇文章,但没有看到下面的“个人解决方案”。


我最近在Linux子系统Windows上使用Python 3.7的烦恼是:在具有相同Pandas库的两台计算机上,一台给我segmentation fault,另一台报告我。不清楚哪个是较新的,但是“重新安装” pandas解决了这个问题。

我在越野车上运行的命令。

conda install pandas

更多详细信息:我正在运行相同的脚本(通过Git同步),并且两者都是带有WSL + Anaconda的Windows 10计算机。在这里截屏以说明情况。同样,在命令行python会抱怨Segmentation fault (core dumped)的机器上,Jupyter实验室每次仅重新启动内核。更糟糕的是,根本没有发出警告。

enter image description here

答案 5 :(得分: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

答案 6 :(得分:-1)

好像您的内存不足。您可能希望像Davide所说的那样增加它。要在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's post on codeforces。用PyPy运行它有点trickier