Soru Sadece hata ayıklayıcı kullanmıyorken segfault


Programda belirli bir noktada tutarlı bir şekilde segmentasyon hatası oluşturan çok iş parçacıklı bir C programım var. Gdb ile çalıştırdığımda, herhangi bir hata gösterilmiyor. Hataların sadece hata ayıklayıcı kullanılmadığında meydana gelmesinin herhangi bir nedenini düşünebiliyor musunuz? Sorunu bulmak için kullanamayan oldukça sinir bozucu!


47
2018-01-07 17:44


Menşei


Bu tür bir hata denir "Heisenbug" ve birçok nedeni olabilir. - Sven Marnach
Hata, pencere yönetimi ve / veya User32.dll ile ilgili mi? - Mehrdad
Böyle bir sorun yaşadım, programım sadece GDB ile çöktü. Sorun, programımı çalıştırdığımda sınıf değerine sahip olmayan bir üye değişkeniydi, ancak GDB'de çalıştırdığımda dizi dizisi olarak kullandığımda segfault edilen bazı büyük değerler vardı. - GWW
Windows ile ilgili değil - Linux 2.6.32-24-jenerik # 43-Ubuntu kullanıyorum. - Benubird
Bir çekirdek dökümü düzenlemeyi denediniz mi? Koşmak ulimit -c unlimited Programı hata ayıklayıcısına başlamadan önce gdb myprogram core çekirdikten sonra çekirdek. gdb daha sonra segfault'unuzu yayınlayabilir. - Robie Basak


Cevaplar:


Klasik Heisenbug. Vikipedi'den:

Zaman heisenbugs da bir faktör olabilir. Bir programın bir hata ayıklayıcısının denetimi altında yürütülmesi, normal yürütme ile karşılaştırıldığında programın yürütme zamanlamasını değiştirebilir. Yarış koşulları gibi zamana duyarlı hatalar, program hata ayıklayıcısında tek basamaklı kaynak satırları tarafından yavaşlatıldığında yeniden oluşturulamayabilir. Bu davranış, davranış, bir hata ayıklayıcının denetimi altında olmayan bir varlıkla etkileşimi içerdiğinde, örneğin iki makine arasında ağ paketi işlemenin hata ayıklaması ve yalnızca bir tanesi hata ayıklayıcısının denetimi altında olduğu durumlarda geçerlidir.

Hata ayıklayıcı zamanlamayı değiştiriyor ve bir yarış koşulunu gizliyor olabilir.

Linux'ta, GDB ayrıca adres alanı rasgelelemesini de devre dışı bırakır ve çökmeniz adres alanı düzenine özgü olabilir. Deneyin (gdb) set disable-randomization off.

En sonunda, ulimit -c unlimited ve post-mortem hata ayıklama (zaten Robie tarafından önerilmektedir) işe yarayabilir.


66
2018-01-07 17:47



'devre dışı bırakma-randomizasyon kapalı' benim için benzer bir sorunu çözdü! - Marcus Johansson
Ya LLDB kullanıyorsam? eşdeğer komut nedir? - thiagoh
@thiagoh: Ne yazık ki bilmiyorum (bunu düzenleyen kişi ben değilim), başka birine sormak isteyebilirsiniz ... - Mehrdad


Belki kullanırken gdb bellek, fazla / az akışınızın bir kazaya neden olan bellekte ezilmediği bir yerde eşlenir. Ya da artık tetiklenmeyen bir yarış durumu olabilir. Anlaşılmaz görünmesine rağmen, mutlu Programın sana çarpacak kadar güzeldi.

Bazı öneriler

  1. Ücretsiz gibi bir statik kod analizörü deneyin cppcheck
  2. Malloc () gibi bir hata ayıklayıcısını deneyin. libefence
  3. Üzerinden çalıştırmayı deneyin valgrind

6
2018-01-07 17:48





Hata ayıklayarak, içinde çalıştığı ortamı değiştiriyorsunuz. Bir çeşit yarış durumuyla uğraştığınız gibi geliyor ve hata ayıklama yoluyla, işler biraz farklı şekilde planlanıyor, böylece sorunla karşılaşmıyorsunuz. Bu, ya da bazı şeyleri biraz farklı bir şekilde depolanmakta, böylece oluşmamaktadır. Sorunun çözülmesine yardımcı olmak için kodda bazı hata ayıklama çıktılarını koyabiliyor musunuz? Bunun daha az etkisi olabilir ve sorununuzu bulmanızı sağlayabilir.


4
2018-01-07 17:46





Bu sorunu daha önce tamamen yaşadım! Bu bir yarış durumuydu ve ben bir hata ayıklayıcısına sahip kodla adım attığımda, içinde bulunduğum iplik, yarış koşulunu tetikleyecek kadar yavaştı. Oldukça korkunç.


1
2018-01-07 20:49