Program hanya macet saat rilis build - bagaimana cara men-debug?

98

Saya mendapat jenis masalah "Schroedinger's Cat" di sini - program saya (sebenarnya rangkaian pengujian untuk program saya, tapi tetap saja sebuah program) macet, tetapi hanya ketika dibangun dalam mode rilis, dan hanya ketika diluncurkan dari baris perintah . Melalui caveman debugging (mis., Pesan printf () yang buruk di semua tempat), saya telah menentukan metode pengujian di mana kode mengalami crash, meskipun sayangnya crash yang sebenarnya tampaknya terjadi di beberapa destruktor, karena jejak pesan terakhir yang saya lihat ada di perusak lain yang mengeksekusi dengan bersih.

Ketika saya mencoba menjalankan program ini di dalam Visual Studio, itu tidak macet. Hal yang sama berlaku saat meluncurkan dari WinDbg.exe. Kecelakaan hanya terjadi saat meluncurkan dari baris perintah. Ini terjadi di bawah Windows Vista, btw, dan sayangnya saya tidak memiliki akses ke mesin XP sekarang untuk mengujinya.

Akan sangat baik jika saya bisa mendapatkan Windows untuk mencetak jejak tumpukan, atau sesuatu selain hanya menghentikan program seolah-olah telah keluar dengan bersih. Adakah yang punya saran tentang bagaimana saya bisa mendapatkan informasi yang lebih bermakna di sini dan semoga memperbaiki bug ini?

Sunting: Masalahnya memang disebabkan oleh larik di luar batas, yang saya jelaskan lebih lanjut di posting ini . Terima kasih semuanya atas bantuan Anda dalam menemukan masalah ini!

Nik Reiman
sumber
Dapatkah Anda memberikan contoh metode pengujian itu?
akalenuk
Tidak ada maaf, kodenya terlalu rumit untuk ditempel dengan mudah di sini, dan seperti yang saya sebutkan, ini tidak terjadi dalam metode pengujian itu sendiri, melainkan destruktor setelahnya. Tidak ada petunjuk yang tidak diinisialisasi atau semacamnya dalam metode ini.
Nik Reiman
3
Kebanyakan jawaban tidak lebih dari sekadar tebakan. Ada beberapa teknik umum untuk menganalisis build rilis yang mogok tanpa memasang debugger: stackoverflow.com/a/18513077/214777?stw=2
Sebastian
Mungkin itu bukan salah Anda: Apakah tingkat pengoptimalan -O3 berbahaya di g ++?
Brent Bradburn

Jawaban:

130

Dalam 100% kasus yang pernah saya lihat atau dengar, di mana program C atau C ++ berjalan dengan baik di debugger tetapi gagal saat dijalankan di luar, penyebabnya telah menulis melewati akhir fungsi larik lokal. (Debugger menempatkan lebih banyak pada tumpukan, jadi Anda cenderung tidak menimpa sesuatu yang penting.)

James Curran
sumber
32
Seseorang beri orang ini cerutu! Dalam kasus saya, saya mengirimkan StringBuilder yang tidak memiliki kapasitas yang cukup besar untuk fungsi P / Invoke. Saya kira itu seperti seseorang yang menulis di wajah Anda dengan spidol ajaib ketika Anda tidur: di bawah debugger, mereka akhirnya mencoret-coret dahi Anda, jadi Anda tidak menyadarinya, tetapi tanpa debugger, mereka akhirnya menikam Anda di mata ... sesuatu seperti itu. Terima kasih atas tip ini!
Nicholas Piasecki
1
Dalam kasus saya, ternyata itu adalah masalah penyelarasan pada prosesor ARM yang menggunakan Obj-C.
Almo
1
11 tahun kemudian dan ini masih benar ... jangan lupa untuk menyimpan vektor Anda.
dav
1
ok, jadi bagaimana cara seseorang mengubah perilaku mode debug sehingga seseorang dapat benar-benar men-debug.
Paul Childs
1
"Sekarang mengetahui di mana mencarinya" tetapi bagaimana segala sesuatu yang bekerja dalam debug memberi tahu Anda di mana masalahnya. Meskipun saya pikir jawaban Anda benar dalam banyak kasus, dan mengetahui apa yang harus dicari adalah permulaan yang baik, menelusuri basis kode besar untuk menunjukkan dengan tepat di mana masalahnya bisa sangat mahal.
Paul Childs
56

Ketika saya mengalami masalah seperti ini sebelumnya umumnya disebabkan oleh inisialisasi variabel. Dalam mode debug, variabel dan pointer diinisialisasi ke nol secara otomatis tetapi dalam mode rilis tidak. Oleh karena itu, jika Anda memiliki kode seperti ini

int* p;
....
if (p == 0) { // do stuff }

Dalam mode debug, kode dalam if tidak dijalankan tetapi dalam mode rilis p berisi nilai yang tidak ditentukan, yang kemungkinan tidak bernilai 0, sehingga kode dieksekusi sering menyebabkan crash.

Saya akan memeriksa kode Anda untuk variabel yang tidak diinisialisasi. Ini juga dapat diterapkan pada konten array.

David Dibben
sumber
Kasus umum lupa untuk meletakkan variabel anggota di (salah satu) daftar inisialisasi anggota konstruktor. Memiliki efek yang sama tetapi lebih sulit untuk menemukan jika Anda tidak tahu bahwa Anda harus mencari inisialisasi anggota yang tepat juga.
steffenj
1
Dalam mode debug, variabel biasanya diinisialisasi ke beberapa 'Konstanta yang Ditentukan Kompilator' yang dapat digunakan dalam debugging untuk menunjukkan status variabel tersebut. Misalnya: pointer NULL atau 0xDeadBeef populer.
Martin York
Runtime debug biasanya menginisialisasi memori ke beberapa nilai bukan nol, khususnya sehingga tes penunjuk NULL akan menyebabkan kode bertindak seolah-olah penunjuk kita bukan-NULL. Jika tidak, Anda memiliki kode yang berjalan dengan benar dalam mode debug yang menghentikan mode rilis.
Michael Burr
1
Tidak, variabel tidak diinisialisasi sama sekali dan itu masih UB untuk "menggunakan" mereka sampai mereka ditugaskan ke. Namun, isi memori yang mendasarinya sering kali diisi dengan 0x0000000 atau 0xDEADBEEF atau pola lain yang dapat dikenali.
Balapan Ringan di Orbit
27

Sejauh ini tidak ada jawaban yang mencoba memberikan gambaran umum yang serius tentang teknik yang tersedia untuk men-debug aplikasi rilis:

  1. Rilis dan build Debug berperilaku berbeda karena berbagai alasan. Berikut ini ikhtisar yang bagus. Setiap perbedaan ini mungkin menyebabkan bug dalam build Rilis yang tidak ada di build Debug.

  2. Kehadiran debugger juga dapat mengubah perilaku program , baik untuk rilis maupun versi debug. Lihat jawaban ini. Singkatnya, setidaknya Visual Studio Debugger menggunakan Debug Heap secara otomatis saat dilampirkan ke program. Anda dapat menonaktifkan heap debug dengan menggunakan variabel lingkungan _NO_DEBUG_HEAP. Anda dapat menentukan ini di properti komputer Anda, atau di Pengaturan Proyek di Visual Studio. Tindakan tersebut mungkin membuat error dapat direkonstruksi dengan debugger terpasang.

    Lebih lanjut tentang men-debug korupsi heap di sini.

  3. Jika solusi sebelumnya tidak berhasil, Anda perlu menangkap pengecualian yang tidak tertangani dan melampirkan debugger post-mortem saat crash terjadi. Anda dapat menggunakan misalnya WinDbg untuk ini, detail tentang debugger post-mortem yang tersedia dan instalasinya di MSDN

  4. Anda dapat meningkatkan kode penanganan pengecualian dan jika ini adalah aplikasi produksi, Anda harus:

    Sebuah. Instal penangan terminasi kustom menggunakanstd::set_terminate

    Jika Anda ingin men-debug masalah ini secara lokal, Anda dapat menjalankan loop tanpa akhir di dalam pengendali terminasi dan menampilkan beberapa teks ke konsol untuk memberi tahu Anda bahwa std::terminatetelah dipanggil. Kemudian pasang debugger dan periksa tumpukan panggilan. Atau Anda mencetak jejak tumpukan seperti yang dijelaskan dalam jawaban ini.

    Dalam aplikasi produksi, Anda mungkin ingin mengirim laporan kesalahan kembali ke rumah, idealnya bersama dengan dump memori kecil yang memungkinkan Anda menganalisis masalah seperti yang dijelaskan di sini.

    b. Gunakan mekanisme penanganan pengecualian terstruktur Microsoft yang memungkinkan Anda menangkap pengecualian perangkat keras dan perangkat lunak. Lihat MSDN . Anda bisa menjaga bagian dari kode Anda menggunakan SEH dan menggunakan pendekatan yang sama seperti di a) untuk men-debug masalah. SEH memberikan lebih banyak informasi tentang pengecualian yang terjadi yang dapat Anda gunakan saat mengirim laporan kesalahan dari aplikasi produksi.

Sebastian
sumber
16

Hal-hal yang harus diperhatikan:

Array overruns - debugger studio visual menyisipkan padding yang dapat menghentikan error.

Kondisi balapan - apakah Anda memiliki beberapa utas yang terlibat jika demikian, kondisi balapan banyak yang hanya muncul ketika aplikasi dijalankan secara langsung.

Menautkan - apakah versi rilis Anda menggunakan pustaka yang benar.

Hal untuk dicoba:

Minidump - sangat mudah digunakan (lihat saja di msdn) akan memberi Anda crash dump lengkap untuk setiap utas. Anda hanya memuat output ke studio visual dan seolah-olah Anda sedang melakukan debug pada saat crash.

morechilli.dll
sumber
1
Hai - Saya memiliki suara negatif tanpa nama untuk jawaban ini. Saya ingin memahami mengapa?
morechilli
12

Anda dapat mengatur WinDbg sebagai debugger postmortem. Ini akan meluncurkan debugger dan melampirkannya ke proses saat crash terjadi. Untuk menginstal WinDbg untuk debugging postmortem, gunakan opsi / I (perhatikan itu dikapitalisasi ):

windbg /I

Lebih lengkapnya di sini .

Mengenai penyebabnya, kemungkinan besar itu adalah variabel yang disatukan seperti yang disarankan jawaban lain.

Franci Penov
sumber
2
Dan jangan lupa bahwa Anda dapat meminta kompiler menghasilkan file PDB bahkan untuk rilis build, meskipun ini bukan defaultnya.
Michael Burr
Satu-satunya jawaban nyata untuk pertanyaan itu.
Sebastian
10

Setelah berjam-jam debugging, akhirnya saya menemukan penyebab masalahnya, yang memang disebabkan oleh buffer overflow, menyebabkan perbedaan single byte:

char *end = static_cast<char*>(attr->data) + attr->dataSize;

Ini adalah kesalahan tiang pagar (kesalahan off-by-one) dan telah diperbaiki oleh:

char *end = static_cast<char*>(attr->data) + attr->dataSize - 1;

Yang aneh adalah, saya melakukan beberapa panggilan ke _CrtCheckMemory () di sekitar berbagai bagian kode saya, dan mereka selalu mengembalikan 1. Saya dapat menemukan sumber masalah dengan menempatkan "return false;" panggilan dalam kasus uji, dan akhirnya menentukan melalui trial-and-error di mana kesalahan itu.

Terima kasih semuanya atas komentar Anda - Saya belajar banyak tentang windbg.exe hari ini! :)

Nik Reiman
sumber
8
Hari ini saya telah men-debug masalah serupa dan _CrtCheckMemory () selalu kembali 1. Tapi kemudian saya menyadari mengapa: dalam mode Rilis, _CrtCheckMemory # didefinisikan sebagai ((int) 1).
Brian Morearty
7

Meskipun Anda telah membuat exe sebagai versi rilis, Anda masih dapat menghasilkan file PDB (Program database) yang memungkinkan Anda untuk menumpuk pelacakan, dan melakukan pemeriksaan variabel dalam jumlah terbatas. Dalam pengaturan build Anda, ada opsi untuk membuat file PDB. Nyalakan dan tautkan kembali. Kemudian coba jalankan dari IDE terlebih dahulu untuk melihat apakah Anda mengalami error. Jika demikian, maka bagus - Anda siap untuk melihat berbagai hal. Jika tidak, maka saat menjalankan dari baris perintah Anda dapat melakukan salah satu dari dua hal:

  1. Jalankan EXE, dan sebelum crash lakukan Attach To Process (menu Tools di Visual Studio).
  2. Setelah crash, pilih opsi untuk meluncurkan debugger.

Saat diminta untuk menunjuk ke file PDB, telusuri untuk menemukannya. Jika PDB diletakkan di folder keluaran yang sama dengan EXE atau DLL Anda, mereka mungkin akan diambil secara otomatis.

PDB menyediakan tautan ke sumber dengan informasi simbol yang cukup untuk memungkinkan melihat jejak tumpukan, variabel, dll. Anda dapat memeriksa nilai seperti biasa, tetapi perlu diketahui bahwa Anda bisa mendapatkan pembacaan yang salah karena pengoptimalan hanya dapat berarti muncul di register, atau sesuatu terjadi dalam urutan yang berbeda dari yang Anda harapkan.

NB: Saya mengasumsikan lingkungan Windows / Visual Studio di sini.

Greg Whitfield
sumber
3

Crash seperti ini hampir selalu disebabkan karena IDE biasanya akan menyetel konten variabel yang tidak diinisialisasi menjadi nol, null, atau nilai 'masuk akal' lainnya, sedangkan saat menjalankan native, Anda akan mendapatkan sampah acak apa pun yang diambil sistem.

Oleh karena itu, kesalahan Anda hampir pasti karena Anda menggunakan sesuatu seperti Anda menggunakan penunjuk sebelum diinisialisasi dengan benar dan Anda lolos begitu saja di IDE karena tidak menunjuk ke mana pun yang berbahaya - atau nilainya ditangani oleh Anda. pengecekan kesalahan - tetapi dalam mode rilis itu melakukan sesuatu yang buruk.

Cruachan
sumber
3

Untuk memiliki dump kerusakan yang dapat Anda analisis:

  1. Buat file pdb untuk kode Anda.
  2. Anda rebase agar exe dan dll Anda dimuat di alamat yang sama.
  3. Aktifkan debugger post mortem seperti Dr. Watson
  4. Periksa alamat kegagalan kerusakan menggunakan alat seperti pencari kerusakan .

Anda juga harus memeriksa alat di alat Debugging untuk windows . Anda dapat memantau aplikasi dan melihat semua peluang pengecualian pertama yang sebelum pengecualian kesempatan kedua Anda.

Semoga membantu ...

Yuval Peled
sumber
3

Cara yang bagus untuk men-debug error seperti ini adalah dengan mengaktifkan pengoptimalan untuk build debug Anda.

Mgill404
sumber
2

Suatu ketika saya mengalami masalah ketika aplikasi berperilaku mirip dengan milik Anda. Ternyata itu adalah buffer yang dibanjiri sprintf. Secara alami, ini bekerja ketika dijalankan dengan debugger terpasang. Apa yang saya lakukan, adalah menginstal filter pengecualian yang tidak tertangani ( SetUnhandledExceptionFilter ) di mana saya hanya memblokir tanpa batas (menggunakan WaitForSingleObject pada pegangan palsu dengan nilai batas waktu INFINITE).

Jadi Anda bisa melakukan sesuatu di sepanjang baris:

long __stdcall MyFilter (EXCEPTION_POINTERS *)
{
    HANDLE hEvt = :: CreateEventW (0,1,0,0);
    jika (hEvt)
    {
        jika (WAIT_FAILED == :: WaitForSingleObject (hEvt, INFINITE))
        {
            // mencatat kegagalan
        }
    }

}
// di suatu tempat di wmain / WinMain Anda:
SetUnhandledExceptionFilter (MyFilter);

Saya kemudian memasang debugger setelah bug terwujud (program gui berhenti merespons).

Kemudian Anda dapat mengambil dump dan mengerjakannya nanti:

.dump / ma path_to_dump_file

Atau langsung debug. Cara paling sederhana adalah melacak di mana konteks prosesor telah disimpan oleh mesin penanganan pengecualian waktu proses:

sd esp Rentang 1003f

Perintah akan mencari ruang alamat tumpukan untuk catatan KONTEKS asalkan panjang pencarian. Saya biasanya menggunakan sesuatu seperti 'l? 10000' . Catatan, jangan gunakan angka besar yang tidak biasa karena rekaman yang Anda kejar biasanya dekat dengan bingkai filter pengecualian yang tidak ditangani. 1003f adalah kombinasi dari flag (saya yakin ini sesuai dengan CONTEXT_FULL) yang digunakan untuk menangkap status prosesor. Pencarian Anda akan terlihat seperti ini:

0: 000> sd esp l1000 1003f
0012c160 0001003f 00000000 00000000 00000000? ...............

Setelah Anda mendapatkan hasil kembali, gunakan alamat di perintah cxr:

.cxr 0012c160

Ini akan membawa Anda ke KONTEKS baru ini, tepat pada saat kerusakan (Anda akan mendapatkan pelacakan tumpukan tepat pada saat aplikasi Anda mogok). Selain itu, gunakan:

.exr -1

untuk mengetahui dengan tepat pengecualian mana yang terjadi.

Semoga membantu.

deemok
sumber
2

Terkadang ini terjadi karena Anda telah memasukkan operasi penting di dalam makro "assert". Seperti yang Anda ketahui, "assert" mengevaluasi ekspresi hanya pada mode debug.

Mohamad mehdi Kharatizadeh
sumber
1

Berkenaan dengan masalah Anda mendapatkan informasi diagnostik, apakah Anda sudah mencoba menggunakan adplus.vbs sebagai alternatif untuk WinDbg.exe? Untuk melampirkan ke proses yang sedang berjalan, gunakan

adplus.vbs -crash -p <process_id>

Atau untuk memulai aplikasi jika crash terjadi dengan cepat:

adplus.vbs -crash -sc your_app.exe

Info lengkap tentang adplus.vbs dapat ditemukan di: http://support.microsoft.com/kb/286350

DocMax
sumber
1

Ntdll.dll dengan debugger terpasang

Satu perbedaan kecil yang diketahui antara meluncurkan program dari IDE atau WinDbg sebagai kebalikan dari meluncurkannya dari baris perintah / desktop adalah bahwa saat meluncurkan dengan debugger terpasang (yaitu IDE atau WinDbg) ntdll.dll menggunakan implementasi heap berbeda yang melakukan sedikit validasi pada alokasi / pembebasan memori.

Anda dapat membaca beberapa informasi yang relevan di breakpoint pengguna yang tidak terduga di ntdll.dll . Salah satu alat yang mungkin dapat membantu Anda mengidentifikasi masalah adalah PageHeap.exe .

Analisis kerusakan

Anda tidak menulis apa "kecelakaan" yang Anda alami. Setelah program macet dan menawarkan Anda untuk mengirim informasi kesalahan ke Microsoft, Anda harus dapat mengklik informasi teknis dan untuk memeriksa setidaknya kode pengecualian, dan dengan sedikit usaha Anda bahkan dapat melakukan analisis post-mortem (lihat Heisenbug : Program WinApi macet di beberapa komputer) untuk instruksi)

Suma
sumber
1

Vista SP1 sebenarnya memiliki generator crash dump yang sangat bagus yang dibangun ke dalam sistem. Sayangnya, ini tidak diaktifkan secara default!

Lihat artikel ini: http://msdn.microsoft.com/en-us/library/bb787181(VS.85).aspx

Manfaat dari pendekatan ini adalah tidak ada perangkat lunak tambahan yang perlu diinstal pada sistem yang terpengaruh. Pegang dan robek, sayang!


sumber
1

Menurut pengalaman saya, yang paling banyak adalah masalah kerusakan memori.

Sebagai contoh :

char a[8];
memset(&a[0], 0, 16);

: /*use array a doing some thing */

sangat mungkin untuk menjadi normal dalam mode debug ketika seseorang menjalankan kode.

Tapi dalam rilisnya, itu akan / mungkin crash.

Bagi saya, mencari-cari di mana memori sudah tidak terikat terlalu sulit.

Gunakan beberapa alat seperti Visual Leak Detector (windows) atau valgrind (linux) adalah pilihan yang lebih bijak.

Gaiger Chen
sumber
1

Saya telah melihat banyak jawaban yang benar. Namun, tidak ada yang membantu saya. Dalam kasus saya, ada penggunaan yang salah dari instruksi SSE dengan memori yang tidak selaras . Lihatlah perpustakaan matematika Anda (jika Anda menggunakannya), dan coba nonaktifkan dukungan SIMD, kompilasi ulang dan rekonstruksi crash.

Contoh:

Sebuah proyek menyertakan mathfu , dan menggunakan kelas dengan vektor STL: std :: vector <mathfu :: vec2> . Penggunaan seperti itu mungkin akan menyebabkan crash pada saat konstruksi item mathfu :: vec2 karena pengalokasi default STL tidak menjamin diperlukan penyelarasan 16-byte. Dalam hal ini untuk membuktikan idenya, seseorang dapat menentukan #define MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT 1sebelum setiap penyertaan mathfu , mengkompilasi ulang dalam konfigurasi Rilis dan memeriksa lagi.

The Debug dan RelWithDebInfo konfigurasi bekerja dengan baik untuk proyek saya, tapi bukan Rilis satu. Alasan di balik perilaku ini mungkin karena debugger memproses permintaan alokasi / deallocation dan melakukan beberapa pembukuan memori untuk memeriksa dan memverifikasi akses ke memori.

Saya mengalami situasi di lingkungan Visual Studio 2015 dan 2017.

Vlad Serhiienko
sumber
0

Sesuatu yang mirip terjadi pada saya sekali dengan GCC. Ternyata itu adalah pengoptimalan yang terlalu agresif yang hanya diaktifkan saat membuat rilis final dan bukan selama proses pengembangan.

Sejujurnya itu adalah kesalahan saya, bukan gcc, karena saya tidak memperhatikan bahwa kode saya mengandalkan fakta bahwa pengoptimalan tertentu tidak akan dilakukan.

Saya membutuhkan banyak waktu untuk melacaknya dan saya datang ke sana karena saya bertanya di newsgroup dan seseorang membuat saya memikirkannya. Jadi, izinkan saya membalas budi kalau-kalau ini terjadi pada Anda juga.

Remo.D
sumber
0

Saya telah menemukan artikel ini berguna untuk skenario Anda. ISTR opsi kompiler agak ketinggalan zaman. Lihat di sekitar opsi proyek Visual Studio Anda untuk melihat cara menghasilkan file pdb untuk rilis build Anda, dll.

fizzer
sumber
0

Sangat mencurigakan bahwa ini akan terjadi di luar debugger dan bukan di dalam; berjalan di debugger biasanya tidak mengubah perilaku aplikasi. Saya akan memeriksa perbedaan lingkungan antara konsol dan IDE. Juga, jelas, kompilasi rilis tanpa pengoptimalan dan dengan informasi debug, dan lihat apakah itu memengaruhi perilaku. Terakhir, periksa alat debugging post-mortem yang disarankan orang lain di sini, biasanya Anda bisa mendapatkan petunjuk dari mereka.

Nick
sumber
0

Debugging rilis build bisa sangat merepotkan karena pengoptimalan yang mengubah urutan baris kode Anda tampaknya akan dieksekusi. Ini benar-benar bisa membingungkan!

Satu teknik untuk setidaknya mempersempit masalah adalah dengan menggunakan MessageBox () untuk menampilkan pernyataan cepat yang menyatakan bagian mana dari program kode Anda harus ("Memulai Foo ()", "Memulai Foo2 ()"); mulailah menempatkannya di bagian atas fungsi di area kode yang Anda curigai (apa yang Anda lakukan saat macet?). Saat Anda dapat mengetahui fungsi mana, ubah kotak pesan menjadi blok kode atau bahkan baris individual dalam fungsi itu hingga Anda mempersempitnya menjadi beberapa baris. Kemudian Anda dapat mulai mencetak nilai variabel untuk melihat statusnya pada titik kerusakan.


sumber
Dia sudah mencoba menaburkan printf, jadi kotak pesan tidak akan membawa sesuatu yang baru ke pesta.
Greg Whitfield
0

Coba gunakan _CrtCheckMemory () untuk melihat status memori yang dialokasikan. Jika semuanya berjalan dengan baik, _CrtCheckMemory mengembalikan TRUE , jika tidak FALSE .

Vhaerun
sumber
0

Anda dapat menjalankan perangkat lunak Anda dengan Bendera Global diaktifkan (Lihat di Alat Debugging untuk Windows). Ini akan sangat sering membantu menyelesaikan masalah.

Marcin Gil
sumber
0

Buat program Anda menghasilkan mini dump saat pengecualian terjadi, lalu buka di debugger (misalnya, di WinDbg). Fungsi utama yang harus dilihat: MiniDumpWriteDump, SetUnhandledExceptionFilter

mikhailitsky
sumber
0

Inilah kasus yang saya miliki yang mungkin dianggap instruktif. Itu hanya macet saat rilis di Qt Creator - bukan di debug. Saya menggunakan file .ini (karena saya lebih suka aplikasi yang dapat disalin ke drive lain, vs. yang kehilangan pengaturannya jika Registry rusak). Ini berlaku untuk semua aplikasi yang menyimpan pengaturannya di bawah pohon direktori aplikasi. Jika build debug dan rilis berada di bawah direktori yang berbeda, Anda juga dapat memiliki pengaturan yang berbeda di antara keduanya. Saya memiliki preferensi yang diperiksa di salah satu yang tidak diperiksa di yang lain. Ternyata itulah sumber kecelakaan saya. Untung saya menemukannya.

Saya benci untuk mengatakannya, tapi saya hanya mendiagnosis crash di MS Visual Studio Community Edition; setelah VS diinstal, membiarkan aplikasi saya crash di Qt Creator, dan memilih untuk membukanya di debugger Visual Studio . Meskipun aplikasi Qt saya tidak memiliki info simbol, ternyata perpustakaan Qt memiliki beberapa. Itu membawa saya ke garis yang menyinggung; karena saya bisa melihat metode apa yang dipanggil. (Namun, menurut saya Qt adalah kerangka kerja LGPL yang nyaman, kuat, & lintas platform.)

CodeLurker
sumber
0

Saya punya masalah ini juga. Dalam kasus saya, mode RELEASE memiliki msvscrtd.dll dalam definisi linker. Kami menghapusnya dan masalah teratasi.

Alternatifnya, menambahkan / NODEFAULTLIB ke argumen baris perintah linker juga menyelesaikan masalah.

Pavan Dittakavi
sumber
-3

Saya mengalami kesalahan ini dan vs macet bahkan ketika mencoba! Bersih! proyek saya. Jadi saya menghapus file obj secara manual dari direktori Rilis, dan setelah itu dibangun dengan baik.

Chris89
sumber
-6

Saya setuju dengan Rolf. Karena reproduktifitas sangat penting, Anda tidak boleh memiliki mode non-debug. Semua bangunan Anda harus dapat di-debug. Memiliki dua target untuk men-debug lebih dari dua kali lipat beban debugging Anda. Kirimkan saja versi "mode debug", kecuali jika tidak dapat digunakan. Dalam hal ini, buat itu bisa digunakan.

wnoise
sumber
Ini mungkin berhasil untuk 10% aplikasi tetapi tentu saja tidak untuk semuanya. Apakah Anda ingin memainkan game yang dirilis sebagai DEBUG build? Berikan kode keamanan rahasia bermerek dagang Anda dalam mode ramah pembongkaran, bahkan mungkin bersama dengan PDB? Saya rasa tidak.
steffenj
Steffenj: Saya ingin pengembang game menemukan bug. Idealnya, sebelum mereka mengirim, tetapi jika setelahnya, saya ingin mereka mendapatkan informasi yang cukup untuk mereproduksi dan melacaknya. jika itu kode rahasia, merek dagang tidak berlaku. PDB? Bank data protein? python debugger?
wnoise
IMHO, itu ide yang buruk. Dapat dieksekusi lebih besar, tidak dioptimalkan, dan berjalan jauh lebih lambat. Kasus-kasus ini sangat jarang; meskipun sangat menjengkelkan ketika itu benar-benar terjadi. Anda tidak boleh mengirimkan produk dengan kualitas rendah secara konsisten, mengkhawatirkan proses debug kasus terburuk yang sangat langka. (Suara negatif saya bukan salah satu dari banyak suara negatif.) Saya membuat beberapa program untuk NASA; dan kami mengatakan bahwa minimal, setiap baris kode harus diuji sekali. Pengujian unit juga dapat membantu.
CodeLurker