Python segmentasyon hatasına ne sebep olur?


85

Kosaraju'nun Strong Connected Component (SCC) grafik arama algoritmasını Python'da uyguluyorum.

Program küçük veri kümelerinde harika çalışıyor, ancak onu süper büyük bir grafikte (800.000'den fazla düğüm) çalıştırdığımda "Segmentasyon Hatası" diyor.

Nedeni ne olabilir? Teşekkür ederim!


Ek Bilgi: İlk önce süper büyük veri kümesinde çalışırken bu Hatayı aldım:

"RuntimeError: maximum recursion depth exceeded in cmp"

Sonra yineleme sınırını kullanarak sıfırladım

sys.setrecursionlimit(50000)

ancak "Segmentasyon hatası" var

İnanın bana bu sonsuz bir döngü değil, nispeten daha küçük verilerde doğru çalışıyor. Program kaynakları tüketmiş olabilir mi?


10
Belki bir göz atabilirsin CrashingPython
Abhijit

2
Bu saf Python'da mı çalışıyor yoksa bir C genişletme modülü mü kullanıyorsunuz? Saf Python ise, o zaman orada bir hata ve tebrikler. Eğer ac modülü kullanıyorsanız, segfault muhtemelen oradan geliyordur.
aaronasterling

Saf pitondur. Program nispeten küçük veri kümelerinde harika çalışıyor ve kodun doğru olduğunu düşünmemi sağladı.
xiaolong

Python belgelerine göre:
James Thiele

2
Python belgelerine göre :::::: Mümkün olan en yüksek sınır platforma bağlıdır. Derin özyineleme gerektiren bir programa ve daha yüksek bir limiti destekleyen bir platforma sahip olduğunda bir kullanıcının limiti daha yüksek ayarlaması gerekebilir. Bu dikkatli yapılmalıdır, çünkü çok yüksek bir sınır çökmeye neden olabilir. :::::: Bir işletim sistemi belirtmediniz. Çökme referansı , işletim sisteminizde segmentasyon hatası anlamına gelebilir . Daha küçük bir yığın deneyin. Ancak IIRC, kullandığınız algoritma tüm SSC'yi yığının üzerine koyar, böylece yığınınız tükenebilir.
James Thiele

Yanıtlar:


80

Bu, bir python uzantısı (C ile yazılmış) erişilemeyen bir belleğe erişmeye çalıştığında gerçekleşir.

Aşağıdaki şekillerde takip edebilirsiniz.

  • sys.settraceKodun ilk satırına ekleyin .
  • Kullanım gdbtarif ettiği Mark içinde bu cevap komut isteminde ..

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

2
teşekkürler, ama benim kodum saf python, bir fark yaratır mı?
xiaolong

Hangi python modüllerini kullandığınızı kontrol edin? Bazı modüller python ile yazılmıştır ve diğerleri C'dir. Bir hata bildirmeniz gerektiğini düşünüyorum.
Shiplu Mokaddim

1
benzer, aynı zamanda yararlı: stdlib'in izleme modülü, yeni bir bağımlılık yüklemeden ve kodu değiştirmeden bir aşamalandırma sunucusundaki bir bölümleme hatasının altına inmeme yardımcı oldu.
driftcatcher

4
OSX Sierra'da gdb, lldb
kthouz


54

Sorununuzu çözdüğünüzü anlıyorum, ancak bu konuyu okuyan diğerleri için cevap şudur: işletim sisteminizin python işlemi için ayırdığı yığını artırmanız gerekir.

Bunu yapmanın yolu işletim sistemine bağlıdır. Linux'ta ulimit -smevcut değerinizi komutu ile kontrol edebilir ve onu yükseltebilirsiniz.ulimit -s <new_value>

Önceki değeri iki katına çıkarmayı deneyin ve çalışmıyorsa, hafızası biten veya biten bir değer bulana kadar ikiye katlamaya devam edin.


Ayrıca bir ulimit max ile karşılaşıp karşılaşmadığınızı kontrol etmenin iyi bir yolu çalıştırmak lsofve kullanmak grepveya wc -lher şeyi takip etmektir.
cdated

Hemfikirim Bu aslında hem Python hem de C ++ uygulamalarında segfault'u düzelterek Kosaraju'nun SCC uygulaması için çalıştı. <br/> MAC'im için mümkün olan maksimum değeri
Rock

4
ulimit değerinin yalnızca çalıştırıldığı belirli kabuk için değiştirildiğini unutmayın, böylece tüm sisteminizin değerini yanlışlıkla değiştirmezsiniz
Tanmay Garg

1
Bunu yaptım ve ulimit -s 16384 ile sonuçlandım, ancak çalıştırdıktan sonra hala bir segmentasyon hatası alıyorum.
Sreehari R

@SreehariR Daha da artırmayı deneyin. Bununla birlikte, bir python uzantısıyla ilgili bir sorun da olabilir (eğer kullanıyorsanız), ki bu (bu diğer cevap) [ stackoverflow.com/a/10035594/25891] nasıl hata ayıklama yapılacağını gösterir
Davide

18

Segmentasyon hatası genel bir hatadır, bunun birçok olası nedeni vardır:

  • Düşük bellek
  • Hatalı Ram belleği
  • Bir sorgu kullanarak veritabanından büyük bir veri kümesi getirme (getirilen verilerin boyutu, takas belleğinden fazlaysa)
  • yanlış sorgu / hatalı kod
  • uzun döngüye sahip (çoklu özyineleme)

3

Ulimit'i güncellemek, hem Python (Python segfault .. kim biliyordu!) Hem de C ++ uygulamalarındaki segfault'u düzelterek Kosaraju'nun SCC uygulaması için çalıştı.

MAC'im için olası maksimum değeri şu yolla buldum:

$ ulimit -s -H
65532

bu değer nasıl güncellenir? bu değer ne tür bir birimde midir?
Pablo

Sınırlarınızın ne olması gerektiği hakkında çok şey BİLİYORSANIZ (ve platformunuzun Linux'tan asla değişmeyeceğini biliyorsanız), bu komutu kodunuzun içinden basitçe yürütmek için bir python çalıştırma komutu kullanabilirsiniz. Şahsen .bashrc dosyama ekledim.
2020

2

Google arama bana bu makaleyi buldu ve aşağıdaki "kişisel çözümün" tartışıldığını görmedim.


Linux için Windows Alt Sisteminde Python 3.7 ile ilgili son sıkıntım şudur: aynı Pandas kitaplığına sahip iki makinede biri bana segmentation fault, diğeri raporlar uyarıyor. Hangisinin daha yeni olduğu belli değildi, ancak "yeniden yükleme" pandassorunu çözdü.

Buggy makinesinde koştuğumu emredin.

conda install pandas

Daha fazla ayrıntı: Aynı komut dosyalarını çalıştırıyordum (Git aracılığıyla senkronize edildi) ve her ikisi de WSL + Anaconda ile Windows 10 makinesi. Davayı yapmak için ekran görüntülerine gidin. Ayrıca, komut satırının pythonşikayet edeceği makinede Segmentation fault (core dumped)Jupyter laboratuvarı, çekirdeği her seferinde yeniden başlatır. Daha da kötüsü, hiçbir uyarı yapılmadı.

görüntü açıklamasını buraya girin


Birkaç ay sonra güncellemeler: Jupyter sunucularını Windows makinesinde barındırmayı bıraktım. Şimdi bir Linux sunucusunda açılan uzak bağlantı noktalarını getirmek ve tüm işlerimi uzak Linux makinesinde çalıştırmak için Windows'ta WSL kullanıyorum. Birkaç aydır herhangi bir uygulama hatası yaşamadım :)


0

RPI'da dlib'i yükselttikten sonra bu segmentasyon hatasını yaşıyordum. Yukarıda Shiplu Mokaddim tarafından önerildiği gibi yığını izledim ve bir OpenBLAS kitaplığına yerleştim.

OpenBLAS ayrıca çok iş parçacıklı olduğundan, onu çok iş parçacıklı bir uygulamada kullanmak, bölümleme hatasına kadar iş parçacıklarını üssel olarak çoğaltır. Çok iş parçacıklı uygulamalar için OpenBlas'ı tek iş parçacığı moduna ayarlayın.

Python sanal ortamında, OpenBLAS'a düzenleyerek yalnızca tek bir iş parçacığı kullanmasını söyleyin:

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

ve Ekle:

    export OPENBLAS_NUM_THREADS=1 
    export OPENBLAS_MAIN_FREE=1

Yeniden başlattıktan sonra tüm görüntü tanıma uygulamalarımı daha önce çökmesine neden olan rpi3b'de çalıştırabildim.

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


-1

Görünüşe göre yığın hafızanız yetersiz. Davide'in söylediği gibi arttırmak isteyebilirsiniz. Bunu python kodunda yapmak için, "main ()" inizi threading kullanarak çalıştırmanız gerekir:

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

Kaynak: c1729'un kod kuvvetleri hakkındaki gönderisi . PyPy ile çalıştırmak biraz daha zordur .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.