Wat veroorzaakt een fout van Python Segmentation?

Ik implementeer Kosaraju’s sterk aangesloten component (SCC) grafiekzoek algoritme in Python.

Het programma loopt geweldig op kleine dataset, maar wanneer ik het op een supergrote grafiek (meer dan 800.000 knooppunten) uitvoeren, zegt het “Segmentation Fault”.

Wat is de oorzaak ervan? Bedankt!


Aanvullende informatie:
Eerst kreeg ik deze fout bij het uitvoeren van de super-grote dataset:

"RuntimeError: maximum recursion depth exceeded in cmp"

Dan reset ik de recursietlimiet met

sys.setrecursionlimit(50000)

maar kreeg een ‘segmentatiefout’

Geloof me, het is geen oneindige lus, het loopt correct op relatief kleinere gegevens. Het is mogelijk het programma uitgeput de bronnen?


Antwoord 1, Autoriteit 100%

Dit gebeurt wanneer een python extensie (geschreven in c) probeert toegang te krijgen tot een geheugen dat verder bereikbaar is.

U kunt het op de volgende manieren volgen.

  • Voeg sys.settracebij de allereerste regel van de code.
  • Gebruik gdbzoals beschreven door Mark in dit antwoord .. op de opdrachtprompt

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

Antwoord 2, Autoriteit 68%

Ik begrijp dat je je probleem hebt opgelost, maar voor anderen die deze draad lezen, hier is het antwoord: je moet de stapel verhogen die je besturingssysteem voor het Python-proces toekent.

De manier om dit te doen, is afhankelijk van het besturingssysteem. In linux kun je met het commando ulimit -sje huidige waarde controleren en deze verhogen met ulimit -s <new_value>

Probeer de vorige waarde te verdubbelen en ga door met verdubbelen als het niet werkt, totdat je er een vindt die wel werkt of geen geheugen meer heeft.


Antwoord 3, autoriteit 24%

Segmentatiefout is een algemene fout, hier zijn veel mogelijke redenen voor:

  • Laag geheugen
  • Defect Ram-geheugen
  • Een enorme dataset ophalen uit de db met behulp van een query (als de grootte van de opgehaalde gegevens groter is dan swap mem)
  • verkeerde zoekopdracht / foutcode
  • met een lange lus (meerdere recursie)

Antwoord 4, autoriteit 4%

Het bijwerken van de ulimit werkte voor de SCC-implementatie van mijn Kosaraju door de segfault op zowel Python (Python segfault… wie weet!) als C++-implementaties te repareren.

Voor mijn MAC ontdekte ik het mogelijke maximum via :

$ ulimit -s -H
65532

Antwoord 5, autoriteit 2%

Zoeken met Google vond ik dit artikel en ik zag de volgende “persoonlijke oplossing” niet besproken.


Mijn recente ergernis met Python 3.7 op het Windows-subsysteem voor Linux is dat: op twee machines met dezelfde Pandas-bibliotheek, de ene me segmentation faultgeeft en de andere een waarschuwing geeft. Het was niet duidelijk welke nieuwer was, maar het “opnieuw installeren” van pandaslost het probleem op.

Beveel dat ik op de buggy-machine rende.

conda install pandas

Meer details: ik draaide identieke scripts (gesynchroniseerd via Git) en beide zijn Windows 10-machine met WSL + Anaconda. Ga hier de schermafbeeldingen om de zaak te maken. Ook, op de machine waar opdrachtregel pythonklagen over Segmentation fault (core dumped), start JUPYTER LAB eenvoudig de kernel opnieuw op de kernel. Erger nog, er werd helemaal geen waarschuwing gegeven.


Updates een paar maanden later: ik stop met hosting jupyter-servers op Windows-machine. Ik gebruik nu WSL op Windows om afstandspoorten op te halen die op een Linux-server is geopend en voert u al mijn taken uit op de afstandsbediening op de afstandsbediening. Ik heb nog nooit een uitvoeringsfout ervaren voor een goed aantal maanden 🙂


Antwoord 6

Ik ervoer deze segmentatiefout na het upgraden van DLIB op RPI.
Ik heb de stapel gevolgd zoals gesuggereerd door Shiplu Mokaddim hierboven en het vestigde zich op een openblas-bibliotheek.

Aangezien Openblas ook multi-threaded is, zal het gebruik van IT in een met de Muilted-threaded-applicatie exponentieel vermenigvuldigingen vermenigvuldig tot segmentatiefout. Voor toepassingen met meerdere schroefdraad, stelt u Openblas in op de modus Single Thread.

Virtuele omgeving in Python, vertel Openblas om alleen een enkele draad te gebruiken door te bewerken:

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

en toevoegen:

   export OPENBLAS_NUM_THREADS=1 
    export OPENBLAS_MAIN_FREE=1

Na het opnieuw opstarten was ik in staat om al mijn foto-herkennings-apps op RPI3B te draaien die het eerder breken.

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


Antwoord 7

Het lijkt erop dat je geen geheugen meer hebt. Misschien wilt u het verhogen zoals Davide zei. Om het in python-code te doen, moet u uw “main()” uitvoeren met behulp van threading:

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

Bron: post van c1729 op codeforces. Het uitvoeren met PyPy is een beetje lastiger.

Other episodes