LogHelp_TerminaOnAssert là gì?
Có một câu hỏi tương tự từ một thập kỷ trước, nhưng không có câu trả lời tốt - hy vọng rằng mọi thứ đã thay đổi kể từ đó.
Tôi có một ứng dụng Winforms khá đa luồng dựa trên .NET 4.72. Tôi đang xem nó bằng chế độ xem Process Explorer Threads và nó có rất nhiều clr.dll!LogHelp_TerminateOnAssert+0x6835kiểu gọi. Tôi đã thiết lập đường dẫn Biểu tượng nhưng nó không thực sự rõ ràng cho tôi.
Tôi đã tải xuống ứng dụng và chạy nó qua DebugDiag và WinDbg và không thấy bất kỳ điều gì đáng ngờ nổi bật.
Vì vậy, câu hỏi của tôi:
- Tôi có nên lo lắng về số lượng lớn lệnh gọi LogHelp_TerminaOnAssert không?
- Ứng dụng có bị rò rỉ bộ nhớ không?
- Nó có quá nhiều ngoại lệ không lọc xuống khi tôi đang chạy ứng dụng trong Visual Studio?
Mục nhập duy nhất từ mã của tôi ở đây là !get_FrameReceivedvà ngăn xếp cho chuỗi đó như sau:
Ngăn xếp cho luồng có nhiều chu kỳ nhất là như sau:
Trả lời
Hiệu số lớn
clr.dll!LogHelp_TerminateOnAssert+0x6835
có nghĩa là thực thi thực tế trong phương thức đó là 0x6835 = 26661 byte kể từ đầu của nó. Nó không chắc rằng một phương pháp là lớn như vậy. (Như @blabb đã chỉ ra, đó là phương thức 1 byte).
Thông thường bạn thấy rằng khi bạn chưa thiết lập các ký hiệu một cách chính xác (như trong câu hỏi gốc được liên kết), nhưng bạn đã sửa điều đó.
Rất có thể Microsoft chỉ phát hành các biểu tượng công khai clr.dllchứ không phải các biểu tượng riêng tư. Trong trường hợp đó, bạn sẽ chỉ thấy phương thức công khai cuối cùng đã biết.
Địa chỉ bắt đầu
Xin lưu ý rằng cột được đặt tên là "Địa chỉ bắt đầu". Process Explorer sẽ hiển thị mục nhập đầu tiên trên ngăn xếp.
Vì vậy, đây là nơi mọi thứ bắt đầu. Bạn có vẻ lo ngại rằng đây là nơi mọi thứ kết thúc.
Lưu ý: một số phương thức nội bộ đã biết như RtlUserThreadStartvà BaseThreadInitThunksẽ bị bỏ qua khi hiển thị địa chỉ bắt đầu. Nếu không, chúng có thể trông giống nhau.
Điều mà luồng thực sự đang làm nằm ở đầu danh sách, tức là ZwRemoveIoCompletion, nó dường như thực hiện một số hoạt động IO.
Những câu hỏi của bạn
Tôi có nên lo lắng về số lượng lớn lệnh gọi LogHelp_TerminaOnAssert không?
Không. Đây chỉ là điểm khởi đầu cho một điều gì đó tốt đẹp. Có GetQueuedCompletionStatus()vẻ như có một số IO đang diễn ra và .NET sử dụng Cổng hoàn thành IO (IOCP) cho bạn.
Ứng dụng có bị rò rỉ bộ nhớ không?
Bạn sẽ không biết điều đó khi nhìn vào ngăn xếp cuộc gọi. Bạn nói điều đó bằng cách nhìn vào bộ nhớ theo thời gian.
Nếu bạn có quá nhiều IO mạng đang diễn ra và mạng không thể theo kịp, .NET có thể có ngày càng nhiều mục trong hàng đợi, vì vậy nó có thể giống như rò rỉ bộ nhớ.
Nó có quá nhiều ngoại lệ không lọc xuống khi tôi đang chạy ứng dụng trong Visual Studio?
Bạn cũng sẽ không nói điều đó từ ngăn xếp cuộc gọi. Bạn sẽ đính kèm một trình gỡ lỗi (ví dụ: WinDbg) và kiểm tra các ngoại lệ (như sxe clr), nếu bạn không tin tưởng Visual Studio.
khi phát hành, xây dựng tất cả các xác nhận này được biên dịch thành một bản ret đơn giản, tương tự như
ifdef ( debug ) { function body here } elseif { ret } endif
vì vậy các biểu tượng có độ lệch lớn như vậy là không có thật
vì vậy bạn có thể cần phải tải các ký hiệu thực tế cho địa chỉ đó để có một callstack hợp lý
bạn có thể thấy kích thước của hàm trong clr 4.0.30319 clr.dll chỉ là 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