Saya ingin memiliki cara untuk melaporkan jejak stack kepada pengguna jika ada pengecualian. Apa cara terbaik untuk melakukan ini? Apakah butuh kode ekstra dalam jumlah besar?
Untuk menjawab pertanyaan:
Saya ingin portabel jika mungkin. Saya ingin informasi muncul, sehingga pengguna dapat menyalin jejak tumpukan dan mengirim email kepada saya jika ada kesalahan.
Linux
tidakgcc
.libstdc++
(digunakan oleh GCC dan berpotensi Dentang) seperti yang dijelaskan dalam jawaban ini .Jawaban Andrew Grant tidak membantu mendapatkan jejak stack dari fungsi throwing , setidaknya tidak dengan GCC, karena pernyataan throw tidak menyimpan jejak stack saat ini dengan sendirinya, dan catch handler tidak akan memiliki akses ke jejak stack di titik itu lagi.
Satu-satunya cara - menggunakan GCC - untuk menyelesaikan ini adalah dengan memastikan untuk menghasilkan jejak stack pada titik instruksi melempar, dan menyimpannya dengan objek pengecualian.
Metode ini tentu saja mengharuskan setiap kode yang melempar pengecualian menggunakan kelas Exception tertentu.
Pembaruan 11 Juli 2017 : Untuk beberapa kode bermanfaat, lihat jawaban cahit beyaz, yang menunjuk ke http://stacktrace.sourceforge.net - Saya belum pernah menggunakannya tetapi terlihat menjanjikan.
sumber
throw stack_runtime_error
. Apakah saya benar dalam menyimpulkan bahwa lib ini hanya berfungsi untuk pengecualian yang berasal dari kelas itu, dan bukan untukstd::exception
atau pengecualian dari perpustakaan pihak ketiga?Jika Anda menggunakan Boost 1.65 atau lebih tinggi, Anda dapat menggunakan boost :: stacktrace :
sumber
Unix: backtrace
Mac: backtrace
Windows: CaptureBackTrace
sumber
Saya ingin menambahkan opsi pustaka standar (yaitu lintas-platform) cara membuat backtraces pengecualian, yang telah tersedia bersama C ++ 11 :
Gunakan
std::nested_exception
danstd::throw_with_nested
Ini tidak akan memberi Anda tumpukan bersantai, tetapi menurut saya hal terbaik berikutnya. Dijelaskan pada StackOverflow di sini dan di sini , bagaimana Anda bisa mendapatkan backtrace pada pengecualian Anda di dalam kode Anda tanpa perlu debugger atau logging yang rumit, dengan hanya menulis handler pengecualian yang tepat yang akan mengumpulkan kembali pengecualian bersarang.
Karena Anda bisa melakukan ini dengan kelas pengecualian apa pun, Anda dapat menambahkan banyak informasi ke backtrace tersebut! Anda juga dapat melihat MWE saya di GitHub , di mana backtrace akan terlihat seperti ini:
sumber
AFAIK libunwind cukup portabel dan sejauh ini saya belum menemukan sesuatu yang lebih mudah digunakan.
sumber
Saya merekomendasikan proyek http://stacktrace.sourceforge.net/ . Ini mendukung Windows, Mac OS dan juga Linux
sumber
throw stack_runtime_error
. Apakah saya benar dalam menyimpulkan bahwa lib ini hanya berfungsi untuk pengecualian yang berasal dari kelas itu, dan bukan untukstd::exception
atau pengecualian dari perpustakaan pihak ketiga?Jika Anda menggunakan C ++ dan tidak ingin / tidak bisa menggunakan Boost, Anda dapat mencetak jejak balik dengan nama yang terurai menggunakan kode berikut [tautan ke situs asli] .
Catatan, solusi ini khusus untuk Linux. Menggunakan libc fungsi backtrace () / backtrace_symbols () (dari execinfo.h) GNU untuk mendapatkan backtrace dan kemudian menggunakan __cxa_demangle () (dari cxxabi.h) untuk mengubah nama simbol backtrace.
HTH!
sumber
di linux dengan g ++ lihat lib ini
https://sourceforge.net/projects/libcsdbg
itu melakukan semua pekerjaan untuk Anda
sumber
Di Windows, lihat BugTrap . Ini tidak lagi di tautan asli, tetapi masih tersedia di CodeProject.
sumber
Saya memiliki masalah yang sama, dan meskipun saya suka portabilitas, saya hanya perlu dukungan gcc. Di gcc, execinfo.h dan panggilan backtrace tersedia. Untuk menghilangkan nama fungsi, Mr. Bingmann memiliki kode yang bagus. Untuk membuang backtrace pada pengecualian, saya membuat pengecualian yang mencetak backtrace di konstruktor. Jika saya mengharapkan ini berfungsi dengan pengecualian yang dilemparkan ke perpustakaan, mungkin diperlukan pembangunan kembali / penautan sehingga pengecualian backtracing digunakan.
Mengkompilasi dan menjalankan ini dengan gcc 4.8.4 menghasilkan sebuah backtrace dengan nama fungsi C ++ yang tidak berubah:
sumber
Karena tumpukan sudah dicabut saat memasuki blok tangkap, solusi dalam kasus saya adalah tidak menangkap pengecualian tertentu yang kemudian mengarah ke SIGABRT. Dalam penangan sinyal untuk SIGABRT saya kemudian bercabang () dan execl () baik gdb (dalam build debug) atau stackwalk Google breakwalk (dalam build rilis). Saya juga mencoba hanya menggunakan fungsi aman pengendali sinyal.
GDB:
minidump_stackwalk:
Sunting: Untuk membuatnya berfungsi untuk breakpad saya juga harus menambahkan ini:
Sumber: Bagaimana cara mendapatkan jejak stack untuk C ++ menggunakan gcc dengan informasi nomor baris? dan Apakah mungkin untuk melampirkan gdb ke proses macet (alias debugging "just-in-time")
sumber
Poppy tidak hanya dapat mengumpulkan jejak stack, tetapi juga nilai parameter, variabel lokal, dll. - segala sesuatu yang menyebabkan crash.
sumber
Kode berikut menghentikan eksekusi tepat setelah pengecualian dilemparkan. Anda perlu mengatur windows_exception_handler bersama dengan handler terminasi. Saya menguji ini dalam MinGW 32bits.
Periksa kode berikut untuk fungsi windows_exception_handler: http://www.codedisqus.com/0ziVPgVPUk/exception-handling-and-stacktrace-under-windows-mingwgcc.html
sumber
Cpp-tool ex_diag - easyweight, multiplatform, penggunaan sumber daya minimal, sederhana dan fleksibel saat dilacak.
sumber