¿Qué causa una falla de segmentación de Python?

82

Estoy implementando el algoritmo de búsqueda de gráficos del Componente Conectado Fuerte (SCC) de Kosaraju en Python.

El programa funciona muy bien en un conjunto de datos pequeño, pero cuando lo ejecuto en un gráfico supergrande (más de 800.000 nodos), dice "Fallo de segmentación".

¿Cuál podría ser la causa? ¡Gracias!


Información adicional: Primero recibí este error al ejecutar el conjunto de datos supergrande:

"RuntimeError: maximum recursion depth exceeded in cmp"

Luego restablezco el límite de recursividad usando

sys.setrecursionlimit(50000)

pero tiene una 'falla de segmentación'

Créame, no es un bucle infinito, funciona correctamente con datos relativamente más pequeños. ¿Es posible que el programa haya agotado los recursos?

Xiaolong
fuente
10
Tal vez puedas echar un vistazo CrashingPython
Abhijit
2
¿Se está ejecutando en Python puro o está utilizando un módulo de extensión C? Si es Python puro, entonces hay un error y felicitaciones. Si está utilizando un módulo de CA, entonces la falla de segmento probablemente provenga de allí.
aaronasterling
es Python puro. El programa funciona muy bien con un conjunto de datos relativamente pequeño y me hizo pensar que el código es correcto.
xiaolong
Según la documentación de Python:
James Thiele
2
Según la documentación de Python :::::: El límite más alto posible depende de la plataforma. Un usuario puede necesitar establecer el límite más alto cuando tiene un programa que requiere una recursividad profunda y una plataforma que admite un límite más alto. Esto debe hacerse con cuidado, porque un límite demasiado alto puede provocar un bloqueo. :::::: No especificó un sistema operativo. La referencia al bloqueo podría significar un error de segmentación en su sistema operativo. Pruebe con una pila más pequeña. Pero IIRC, el algoritmo que está utilizando, coloca el SSC completo en la pila, por lo que puede quedarse sin pila.
James Thiele

Respuestas:

80

Esto sucede cuando una extensión de Python (escrita en C) intenta acceder a una memoria fuera de su alcance.

Puede rastrearlo de las siguientes maneras.

  • Agregue sys.settraceen la primera línea del código.
  • Use gdbcomo lo describe Mark en esta respuesta . En el símbolo del sistema

    gdb python
    (gdb) run /path/to/script.py
    ## wait for segfault ##
    (gdb) backtrace
    ## stack trace of the c code
    
Shiplu Mokaddim
fuente
2
gracias, pero mi código es python puro, ¿hace alguna diferencia?
xiaolong
¿Compruebe qué módulos de Python está utilizando? Algunos módulos están escritos en Python y otros están en C. Creo que necesitas informar un error.
Shiplu Mokaddim
1
similar, también útil: el módulo de seguimiento de stdlib me ayudó a llegar al fondo de una falla de segmentación en un servidor de ensayo, sin instalar una nueva dependencia y sin modificar el código.
driftcatcher
3
en OSX Sierra, gdb fue reemplazado por lldb
kthouz
51

Entiendo que ha resuelto su problema, pero para otros que lean este hilo, aquí está la respuesta: debe aumentar la pila que su sistema operativo asigna para el proceso de Python.

La forma de hacerlo depende del sistema operativo. En linux, puede verificar con el comando ulimit -ssu valor actual y puede aumentarlo conulimit -s <new_value>

Intente duplicar el valor anterior y continúe duplicando si no funciona, hasta que encuentre uno que funcione o se quede sin memoria.

Davide
fuente
También una buena forma de comprobar si te encuentras con un ulimit max es ejecutar lsofy usar grepo wc -lhacer un seguimiento de todo.
fechado
Estoy de acuerdo. Esto realmente funcionó para la implementación de SCC de mi Kosaraju al corregir el error de segmentación en las implementaciones de Python y C ++. <br/> Para mi MAC, descubrí el máximo posible a través de:
Rock
4
tenga en cuenta que el valor ulimit se modifica solo para el shell particular en el que se ejecuta, de modo que no modifique accidentalmente el valor para todo su sistema
Tanmay Garg
1
Hice esto y terminé con ulimit -s 16384, sin embargo, después de ejecutar todavía recibí un error de segmentación.
Sreehari R
@SreehariR Intenta aumentarlo aún más. Sin embargo, también podría ser un problema con una extensión de Python (si está usando alguna), que (esta otra respuesta) [ stackoverflow.com/a/10035594/25891] sugiere cómo depurar
Davide
18

La falla de segmentación es genérica, hay muchas razones posibles para esto:

  • Memoria baja
  • Memoria RAM defectuosa
  • Obtener un gran conjunto de datos de la base de datos mediante una consulta (si el tamaño de los datos obtenidos es mayor que la memoria de intercambio)
  • consulta incorrecta / código con errores
  • tener bucle largo (recursividad múltiple)
Sadheesh
fuente
2

La actualización de ulimit funcionó para la implementación de SCC de mi Kosaraju al corregir la falla de segmentación en las implementaciones de Python (Python segfault ... ¡quién sabía!) Y C ++.

Para mi MAC, descubrí el máximo posible a través de:

$ ulimit -s -H
65532
Rock
fuente
¿cómo actualizar ese valor? ¿Es ese valor en qué tipo de unidad?
Pablo
2

La búsqueda de Google me encontró este artículo y no vi la siguiente "solución personal" discutida.


Mi molestia reciente con Python 3.7 en el subsistema de Windows para Linux es que: en dos máquinas con la misma biblioteca de Pandas, una me da a mí segmentation faulty la otra informa de advertencia. No estaba claro cuál era más nuevo, pero "reinstalar" pandasresuelve el problema.

Comando que corrí en la máquina con errores.

conda install pandas

Más detalles: estaba ejecutando scripts idénticos (sincronizados a través de Git), y ambos son una máquina Windows 10 con WSL + Anaconda. Aquí van las capturas de pantalla para hacer el caso. Además, en la máquina sobre la que pythonse quejará la línea de comandos Segmentation fault (core dumped), Jupyter lab simplemente reinicia el kernel cada vez. Peor aún, no se dio ninguna advertencia.

ingrese la descripción de la imagen aquí


Actualizaciones unos meses después: dejé de alojar servidores Jupyter en una máquina con Windows. Ahora uso WSL en Windows para buscar puertos remotos abiertos en un servidor Linux y ejecutar todos mis trabajos en la máquina Linux remota. Nunca he experimentado ningún error de ejecución durante una buena cantidad de meses :)

llinfeng
fuente
0

Estaba experimentando esta falla de segmentación después de actualizar dlib en RPI. Rastreé la pila como sugirió Shiplu Mokaddim arriba y se instaló en una biblioteca OpenBLAS.

Dado que OpenBLAS también tiene varios subprocesos, su uso en una aplicación de subprocesos múltiples multiplicará exponencialmente los subprocesos hasta que falle la segmentación. Para aplicaciones multiproceso, configure OpenBlas en modo de un solo hilo.

En el entorno virtual de Python, dígale a OpenBLAS que solo use un único hilo editando:

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

y añadir:

    export OPENBLAS_NUM_THREADS=1 
    export OPENBLAS_MAIN_FREE=1

Después de reiniciar, pude ejecutar todas mis aplicaciones de reconocimiento de imágenes en rpi3b que anteriormente lo estaban bloqueando.

referencia: https://github.com/ageitgey/face_recognition/issues/294

Digitalf8
fuente
-1

Parece que no tienes memoria de pila. Es posible que desee aumentarlo como dijo Davide. Para hacerlo en código Python, necesitaría ejecutar su "main ()" usando subprocesos:

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()

Fuente: publicación de c1729 sobre codeforces . Ejecutarlo con PyPy es un poco más complicado .

Rustam A.
fuente