İstisna Oluşana Kadar GDB'de Uygulama Çalıştırın


102

Çok iş parçacıklı bir uygulama üzerinde çalışıyorum ve GDB'yi kullanarak hata ayıklamak istiyorum.

Sorun şu ki, ileti dizilerimden biri mesajla ölmeye devam ediyor:

pure virtual method called
terminate called without an active exception
Abort

Bu mesajın nedenini biliyorum, ancak mesaj dizimde nerede oluştuğu hakkında hiçbir fikrim yok. Geri izleme gerçekten yardımcı olacaktır.

Uygulamamı GDB'de çalıştırdığımda, her iş parçacığı askıya alındığında veya devam ettirildiğinde duraklıyor. Uygulamamın, iş parçacıklarından biri bu istisna dışında ölünceye kadar normal şekilde çalışmaya devam etmesini istiyorum, bu noktada geri izleme alabilmem için her şey durdurulmalı.


GDB durakladığında hangi sinyali bildiriyor? gibi bir komut çalıştırabilmeniz gerekirhandle SIGUSR1 pass noprint nostop
Hasturkun

Yanıtlar:


148

İstisnanın üretildiği catch thrownoktada hata ayıklayıcıyı durdurmak için bir "catchpoint" ( ) kullanmayı deneyebilirsiniz .

Aşağıdaki gdb kılavuzundan alıntı , catchpoint özelliğini açıklamaktadır.


5.1.3 Hedef noktaları belirleme

C ++ istisnaları veya paylaşılan bir kitaplığın yüklenmesi gibi belirli program olayları türleri için hata ayıklayıcının durmasına neden olmak için yakalama noktalarını kullanabilirsiniz. Bir yakalama noktası ayarlamak için catch komutunu kullanın.

  • olayı yakalamak

    Ne zaman durdurun olay meydana gelir. olay aşağıdakilerden herhangi biri olabilir:

    • atmak

      Bir C ++ istisnasının atılması.

    • tutmak

      Bir C ++ istisnasının yakalanması.

    • exec

      Yürütme çağrısı. Bu, şu anda yalnızca HP-UX için mevcuttur.

    • çatal

      Bir çatallaşma çağrısı. Bu, şu anda yalnızca HP-UX için mevcuttur.

    • vfork

      Vfork'a bir çağrı. Bu, şu anda yalnızca HP-UX için mevcuttur.

    • libname yükle veya yükle

      Herhangi bir paylaşılan kitaplığın dinamik yüklenmesi veya kitaplık kitaplık adının yüklenmesi. Bu, şu anda yalnızca HP-UX için mevcuttur.

    • boşaltma veya boşaltma kütüphane-adı

      Dinamik olarak yüklenen herhangi bir paylaşılan kitaplığın kaldırılması veya kitaplık kitaplık adının kaldırılması. Bu, şu anda yalnızca HP-UX için mevcuttur.

  • tcatch olayı

    Yalnızca bir durak için etkinleştirilen bir yakalama noktası ayarlayın. Olay ilk yakalandıktan sonra yakalama noktası otomatik olarak silinir.

info breakMevcut yakalama noktalarını listelemek için komutu kullanın .

Şu anda GDB'de C ++ istisna işlemede (yakalama ve yakalama yakalama) bazı sınırlamalar vardır:

  • Bir işlevi etkileşimli olarak çağırırsanız, GDB normalde işlevin yürütülmesi bittiğinde kontrolü size geri verir. Ancak çağrı bir istisna yaratırsa, çağrı kontrolü size geri döndüren mekanizmayı atlayabilir ve programınızın durdurulmasına veya bir kesme noktasına gelene kadar çalışmaya devam etmesine, GDB'nin dinlediği bir sinyali yakalamasına veya çıkmasına neden olabilir. İstisna için bir kapanış noktası belirleseniz bile durum budur; istisnalar üzerindeki yakalama noktaları etkileşimli aramalarda devre dışı bırakılır.

  • Etkileşimli olarak bir istisna oluşturamazsınız.

  • Etkileşimli olarak bir istisna işleyicisi kuramazsınız.

Bazen catch, istisna işlemede hata ayıklamanın en iyi yolu değildir: Bir istisnanın tam olarak nerede ortaya çıktığını bilmeniz gerekiyorsa, istisna işleyicisi çağrılmadan önce durmanız daha iyidir, çünkü bu şekilde herhangi bir çözülme gerçekleşmeden önce yığını görebilirsiniz. Bunun yerine bir istisna işleyicide bir kesme noktası ayarlarsanız, istisnanın nerede ortaya çıktığını bulmak kolay olmayabilir.

Bir istisna işleyicisi çağrılmadan hemen önce durmak için, uygulama hakkında biraz bilgi sahibi olmanız gerekir. GNU C ++ durumunda, aşağıdaki ANSI C arayüzüne sahip __raise_exception adlı bir kütüphane işlevi çağrılarak istisnalar ortaya çıkar:

/* addr is where the exception identifier is stored.
   id is the exception identifier.  */
void __raise_exception (void **addr, void *id);

Herhangi bir yığın çözülmeden önce hata ayıklayıcının tüm istisnaları yakalamasını sağlamak için __raise_exception üzerine bir kesme noktası ayarlayın (bkz. Bölüm Kesme noktaları; izleme noktaları ve istisnalar).

İd değerine bağlı olan koşullu bir kesme noktasıyla (bkz. Kesme koşulları bölümü), belirli bir istisna ortaya çıktığında programınızı durdurabilirsiniz. Çok sayıda istisna ortaya çıktığında programınızı durdurmak için birden çok koşullu kesme noktası kullanabilirsiniz.


Ayrıca, yakalanacak istisna türünü de belirtebilirsiniz, örn catch throw std::runtime_exception.
scai

5

__Pure_virtual üzerinde bir kesme noktası ayarlayın


@JeffreyHill yanıtında buna __cxa_pure_virtual denir. Bunu kendim nasıl kontrol edeceğimi bilmiyorum, bu yüzden yanıtı düzenlemek istemiyorum. Olumsuz oy vermeyi düşünmüyorum, ancak cevap şu anda yanlış olabilir ve neyin doğru olduğunu bilen biri tarafından düzeltilmelidir.
Philipp Claßen

5

FWIW, görünüşe göre, gcc 4.1'de uygun işlev adı değişmiştir ve bu işlevde bir kesme noktası ayarlanmalıdır.

__cxa_pure_virtual


0

Sadece biri benim için gdb 8.3 ile çalıştı:

break _Unwind_RaiseException

"catch throw" veya "break __cxx_throw" benim için çalışmadı.

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.