Apa itu LogHelp_TerminateOnAssert?
Ada pertanyaan serupa dari satu dekade yang lalu, tetapi tidak ada jawaban yang baik - semoga banyak hal telah berubah sejak saat itu.
Saya memiliki aplikasi Winforms yang cukup multithread berdasarkan .NET 4.72. Saya melihatnya dengan tampilan Thread Explorer Proses dan memiliki banyak clr.dll!LogHelp_TerminateOnAssert+0x6835jenis panggilan. Saya telah menyiapkan jalur Simbol tetapi tidak benar-benar menjelaskan apa pun untuk saya.
Saya mengambil dump aplikasi dan menjalankannya melalui DebugDiag dan WinDbg dan tidak melihat sesuatu yang mencurigakan yang menonjol.
Jadi pertanyaan saya:
- Haruskah saya khawatir dengan banyaknya panggilan LogHelp_TerminateOnAssert?
- Apakah aplikasi membocorkan memori?
- Apakah itu memiliki jumlah pengecualian yang berlebihan yang tidak memfilter saat saya menjalankan aplikasi di Visual Studio?
Satu-satunya entri dari kode saya di sini adalah !get_FrameReceiveddan tumpukan utas itu adalah sebagai berikut:
Tumpukan utas dengan siklus paling banyak adalah seperti ini:
Jawaban
Offset besar
clr.dll!LogHelp_TerminateOnAssert+0x6835
artinya eksekusi sebenarnya dalam metode itu berjarak 0x6835 = 26661 byte dari awalnya. Tidak mungkin suatu metode sebesar itu. (Seperti yang ditunjukkan @blabb, ini adalah metode 1 byte).
Biasanya Anda melihat itu ketika Anda belum mengatur simbol dengan benar (seperti dalam pertanyaan asli yang ditautkan), tetapi Anda telah memperbaikinya.
Kemungkinannya adalah Microsoft hanya merilis simbol publik clr.dlldan bukan simbol privat. Dalam hal ini, Anda hanya akan melihat metode publik terakhir yang diketahui.
Alamat awal
Harap diperhatikan bahwa kolom tersebut bernama "Alamat awal". Process Explorer akan menampilkan entri pertama di tumpukan.
Jadi di sinilah semuanya dimulai. Anda tampaknya khawatir bahwa di sinilah semuanya berakhir.
Catatan: beberapa metode internal yang dikenal seperti RtlUserThreadStartdan BaseThreadInitThunkakan dilewati saat menampilkan alamat awal. Kalau tidak, mereka mungkin akan terlihat sama.
Apa yang sebenarnya dilakukan thread ada di bagian atas daftar, yaitu ZwRemoveIoCompletion, jadi sepertinya melakukan beberapa operasi IO.
Pertanyaan Anda
Haruskah saya khawatir dengan banyaknya panggilan LogHelp_TerminateOnAssert?
Tidak. Ini hanyalah titik awal untuk sesuatu yang baik. The GetQueuedCompletionStatus()terlihat seperti ada beberapa IO terjadi dan NET menggunakan IO Penyelesaian Ports (IOCP) untuk Anda.
Apakah aplikasi membocorkan memori?
Anda tidak tahu itu dari melihat tumpukan panggilan. Anda mengatakannya dengan melihat memori dari waktu ke waktu.
Jika Anda memiliki terlalu banyak IO jaringan yang terjadi dan jaringan tidak dapat mengikutinya, .NET mungkin memiliki lebih banyak item dalam antrean, jadi ini mungkin terlihat seperti kebocoran memori.
Apakah itu memiliki jumlah pengecualian yang berlebihan yang tidak memfilter saat saya menjalankan aplikasi di Visual Studio?
Anda juga tidak akan mengatakannya dari tumpukan panggilan. Anda harus memasang debugger (misalnya WinDbg) dan memeriksa pengecualian (seperti sxe clr), jika Anda tidak mempercayai Visual Studio.
pada rilis membangun semua pernyataan ini dikompilasi menjadi ret sederhana yang mirip dengan
ifdef ( debug ) { function body here } elseif { ret } endif
jadi simbol dengan offset yang sangat bagus adalah palsu
jadi Anda mungkin perlu memuat simbol sebenarnya untuk alamat itu untuk callstack yang masuk akal
Anda dapat melihat ukuran fungsi di clr 4.0.30319 clr.dll hanya 1 byte
0:000> x /v /t clr!LogHelp_TerminateOnAssert
pub func 100115a0 0 <NoType> clr!LogHelp_TerminateOnAssert (<no parameter info>)
0:000> .fnent clr!LogHelp_TerminateOnAssert
Debugger function entry 01bad5e0 for:
(100115a0) clr!RtlUnwindCallback | (100115a1) clr!memset
Exact matches:
clr!RtlUnwindCallback (void)
clr!_TlgDefineProvider_annotation__Tlgg_hClrProviderProv (void)
OffStart: 000115a0
ProcSize: 0x1
Prologue: 0x0
Params: 0n0 (0x0 bytes)
Locals: 0n0 (0x0 bytes)
Registers: 0n0
0:000> u clr!LogHelp_TerminateOnAssert l1
clr!RtlUnwindCallback:
100115a0 c3 ret