LogHelp_TerminateOnAssert คืออะไร

Nov 04 2020

มีคำถามคล้าย ๆ กันเมื่อทศวรรษที่แล้ว แต่ไม่มีคำตอบที่ดี - หวังว่าสิ่งต่างๆจะเปลี่ยนไปตั้งแต่นั้นมา

ฉันมีแอป Winforms แบบมัลติเธรดที่ใช้. NET 4.72 ฉันกำลังดูด้วยมุมมอง Process Explorer Threads และมีการclr.dll!LogHelp_TerminateOnAssert+0x6835เรียกประเภทต่างๆมากมาย ฉันได้ตั้งค่าเส้นทางสัญลักษณ์ แต่มันไม่ได้ชัดเจนอะไรสำหรับฉัน

ฉันถ่ายโอนแอปพลิเคชันและเรียกใช้ผ่าน DebugDiag และ WinDbg และไม่เห็นสิ่งที่น่าสงสัยที่โดดเด่น

ดังนั้นคำถามของฉัน:

  • ฉันควรกังวลกับการโทร LogHelp_TerminateOnAssert จำนวนมากหรือไม่
  • แอปพลิเคชันหน่วยความจำรั่วหรือไม่?
  • มีข้อยกเว้นจำนวนมากเกินไปที่ไม่กรองลงเมื่อฉันเรียกใช้แอปใน Visual Studio หรือไม่

รายการเดียวจากรหัสของฉันที่นี่คือ!get_FrameReceivedและสแต็กสำหรับเธรดนั้นมีดังนี้:

สแต็กสำหรับเธรดที่มีรอบมากที่สุดเป็นดังนี้:

คำตอบ

2 ThomasWeller Nov 05 2020 at 21:01

การชดเชยขนาดใหญ่

clr.dll!LogHelp_TerminateOnAssert+0x6835

หมายความว่าการดำเนินการจริงในวิธีนั้นอยู่ห่างจากจุดเริ่มต้น 0x6835 = 26661 ไบต์ มันไม่น่าเป็นไปได้ที่วิธีการใหญ่ (ดังที่ @blabb ชี้ให้เห็นว่าเป็นวิธีการ 1 ไบต์)

โดยปกติคุณจะเห็นว่าเมื่อคุณตั้งค่าสัญลักษณ์ไม่ถูกต้อง (เหมือนในคำถามเดิมที่เชื่อมโยง) แต่คุณได้รับการแก้ไขแล้ว

มีโอกาสที่ Microsoft จะเผยแพร่เฉพาะสัญลักษณ์สาธารณะclr.dllและไม่ใช่สัญลักษณ์ส่วนตัว ในกรณีนี้คุณจะเห็นเฉพาะวิธีสาธารณะล่าสุดเท่านั้น

ที่อยู่เริ่มต้น

โปรดทราบว่าคอลัมน์นี้มีชื่อว่า "ที่อยู่เริ่มต้น" Process Explorer จะแสดงรายการแรกบนสแต็ก

นี่คือจุดเริ่มต้นของทุกสิ่ง ดูเหมือนคุณจะกังวลว่านี่คือจุดสิ้นสุดของทุกสิ่ง

หมายเหตุ: วิธีการภายในที่รู้จักบางอย่างเช่นRtlUserThreadStartและBaseThreadInitThunkจะถูกข้ามไปเมื่อแสดงที่อยู่เริ่มต้น มิฉะนั้นพวกเขาอาจจะดูเหมือนกันทั้งหมด

สิ่งที่เธรดกำลังทำอยู่นั้นอยู่ด้านบนสุดของรายการกล่าวคือZwRemoveIoCompletionดูเหมือนว่าจะดำเนินการ IO บางอย่าง

คำถามของคุณ

ฉันควรกังวลกับการโทร LogHelp_TerminateOnAssert จำนวนมากหรือไม่

ไม่นี่เป็นเพียงจุดเริ่มต้นของสิ่งดีๆ GetQueuedCompletionStatus()ดูเหมือนว่ามีบาง IO ที่เกิดขึ้นและ .NET ใช้พอร์ต IO เสร็จ (IOCP) สำหรับคุณ

แอปพลิเคชันหน่วยความจำรั่วหรือไม่?

คุณไม่ได้บอกสิ่งนั้นจากการดูที่กองการโทร คุณบอกสิ่งนั้นโดยดูจากความทรงจำเมื่อเวลาผ่านไป

หากคุณมีเครือข่าย IO เกิดขึ้นมากเกินไปและเครือข่ายไม่สามารถใช้งานได้ตามปกติ NET อาจมีรายการในคิวมากขึ้นเรื่อย ๆ ดังนั้นจึงอาจดูเหมือนหน่วยความจำรั่ว

มีข้อยกเว้นจำนวนมากเกินไปที่ไม่กรองลงเมื่อฉันเรียกใช้แอปใน Visual Studio หรือไม่

คุณจะไม่บอกสิ่งนั้นจากกลุ่มการโทร คุณจะแนบดีบักเกอร์ (เช่น WinDbg) และตรวจสอบข้อยกเว้น (เช่นsxe clr) หากคุณไม่ไว้วางใจ Visual Studio

2 blabb Nov 05 2020 at 18:43

ในการเปิดตัวสร้างการยืนยันทั้งหมดเหล่านี้จะรวบรวมไว้ในสิ่งที่คล้ายกัน

ifdef ( debug ) { function body here } elseif { ret } endif

ดังนั้นสัญลักษณ์ที่มีการชดเชยที่ยอดเยี่ยมเช่นนี้จึงเป็นของปลอม

ดังนั้นคุณอาจต้องโหลดสัญลักษณ์จริงสำหรับที่อยู่นั้นเพื่อให้ได้ callstack ที่เหมาะสม

คุณสามารถดูขนาดของฟังก์ชันใน clr 4.0.30319 clr.dll เป็นเพียง 1 ไบต์

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