Saya sedang mengerjakan aplikasi multithread, dan saya ingin men-debugnya menggunakan GDB.
Masalahnya adalah, salah satu utas saya terus mati dengan pesan:
pure virtual method called
terminate called without an active exception
Abort
Saya tahu penyebab pesan itu, tetapi saya tidak tahu di mana di utas saya pesan itu muncul. Pelacakan balik akan sangat membantu.
Saat saya menjalankan aplikasi saya di GDB, aplikasi akan berhenti setiap kali utas ditangguhkan atau dilanjutkan. Saya ingin aplikasi saya terus berjalan secara normal sampai salah satu utas mati dengan pengecualian itu, pada titik mana semuanya harus dihentikan sehingga saya bisa mendapatkan pelacakan balik.
handle SIGUSR1 pass noprint nostop
Jawaban:
Anda dapat mencoba menggunakan "catchpoint" (
catch throw
) untuk menghentikan debugger pada titik di mana pengecualian dibuat.Kutipan berikut dari manual gdb menjelaskan fitur catchpoint.
5.1.3 Mengatur catchpoint
Anda dapat menggunakan catchpoint agar debugger berhenti untuk jenis acara program tertentu, seperti pengecualian C ++ atau pemuatan pustaka bersama. Gunakan perintah catch untuk mengatur catchpoint.
acara tangkap
melemparkan
menangkap
eksekutif
garpu
vfork
memuat atau memuat libname
membongkar atau membongkar libname
acara tcatch
Gunakan
info break
perintah untuk membuat daftar catchpoints saat ini.Saat ini ada beberapa batasan untuk penanganan pengecualian C ++ (catch throw dan catch catch) di GDB:
Jika Anda memanggil suatu fungsi secara interaktif, GDB biasanya mengembalikan kontrol kepada Anda saat fungsi tersebut selesai dijalankan. Namun, jika panggilan memunculkan pengecualian, panggilan tersebut dapat melewati mekanisme yang mengembalikan kontrol kepada Anda dan menyebabkan program Anda dibatalkan atau terus berjalan hingga mencapai breakpoint, menangkap sinyal yang didengarkan oleh GDB, atau keluar. Ini adalah kasusnya bahkan jika Anda menetapkan catchpoint untuk pengecualian; catchpoints pada pengecualian dinonaktifkan dalam panggilan interaktif.
Anda tidak dapat mengajukan pengecualian secara interaktif.
Anda tidak dapat menginstal penangan pengecualian secara interaktif.
Terkadang catch bukanlah cara terbaik untuk men-debug penanganan pengecualian: jika Anda perlu tahu persis di mana pengecualian dimunculkan, lebih baik berhenti sebelum pengendali pengecualian dipanggil, karena dengan cara itu Anda dapat melihat tumpukan sebelum pelepasan apa pun terjadi. Jika Anda menetapkan breakpoint di penangan pengecualian, mungkin tidak mudah untuk mengetahui di mana pengecualian itu dimunculkan.
Untuk berhenti tepat sebelum penangan pengecualian dipanggil, Anda memerlukan pengetahuan tentang implementasinya. Dalam kasus GNU C ++, pengecualian dimunculkan dengan memanggil fungsi library bernama __raise_exception yang memiliki antarmuka ANSI C berikut:
Untuk membuat debugger menangkap semua pengecualian sebelum pelepasan tumpukan terjadi, setel breakpoint pada __raise_exception (lihat bagian Breakpoints; watchpoints; dan pengecualian).
Dengan breakpoint bersyarat (lihat bagian Kondisi break) yang bergantung pada nilai id, Anda bisa menghentikan program Anda saat pengecualian tertentu dimunculkan. Anda dapat menggunakan beberapa breakpoint bersyarat untuk menghentikan program Anda ketika salah satu dari sejumlah pengecualian dimunculkan.
sumber
catch throw std::runtime_exception
.Tetapkan breakpoint pada __pure_virtual
sumber
FWIW, rupanya, di gcc 4.1, nama fungsi yang sesuai telah berubah dan kita harus menetapkan titik putus di fungsi ini.
__cxa_pure_virtual
sumber
Hanya di bawah satu yang berhasil untuk saya dengan gdb 8.3:
"catch throw" atau "break __cxx_throw" tidak berhasil untuk saya.
sumber