2016-08-30 20 views
5

Dumps thu được từ Báo cáo lỗi Windows thường có ngữ cảnh hiện tại vô dụng được đặt trên chuỗi lỗi, với ngăn xếp sâu trong WerpReportFault. Ngữ cảnh thực tế tại thời điểm ngoại lệ có thể được truy xuất với .ecxr - cũng đặt bối cảnh theo cách mà các lệnh tiếp theo trên cùng một luồng (chẳng hạn như k) trả lại thông tin "chính xác".Lấy dấu vết ngăn xếp từ ngữ cảnh ngoại lệ được lưu trữ trong một minidump (tương tự như .ecxr; k)

Tôi đang xây dựng một công cụ để phân tích kết xuất tự động, sử dụng IDebugControl::GetStackTrace để lấy ngăn xếp của chuỗi bị lỗi. Tôi có thể truy xuất ngữ cảnh ngoại lệ được lưu trữ bằng cách sử dụng IDebugControl4::GetStoredEventInformation. Nếu tôi sử dụng các giá trị EBP/RBP, ESP/RSP, EIP/RIP từ ngữ cảnh được lưu trữ với GetStackTrace, tôi sẽ có được ngăn xếp chính xác. Tuy nhiên, tôi sẽ nhân rộng hơn những gì lệnh .ecxr làm, thiết lập trạng thái "đúng" cho đến khi chủ đề được chuyển đổi. Tôi đã thử sử dụng IDebugAdvanced::SetThreadContext, nhưng nó có vẻ là một hoạt động bất hợp pháp cho các mục tiêu đổ và không thành công với 0x8000FFFF.

Tôi đã cố gắng tìm ra những gì .ecxr thực hiện bằng cách gỡ lỗi một cá thể WinDbg và có vẻ như .ecxr được triển khai trong dbgeng!DotEcxr. Tuy nhiên, từ truy tìm nó (với wt) tôi đã không thể hiểu cách nó đặt lại bối cảnh của luồng hiện tại. Nó dường như không gọi bất kỳ phương thức giao diện gỡ lỗi COM-client nào, dù sao, và không sử dụng IDebugAdvanced::SetThreadContext.

Bất kỳ đề xuất nào về cách đặt ngữ cảnh luồng trong tệp kết xuất sẽ được đánh giá cao. Như một phương sách cuối cùng, tôi luôn có thể sử dụng IDebugControl::Execute và chỉ cần gọi lệnh .ecxr, nhưng tôi muốn có cách tiếp cận có lập trình hơn.

Trả lời

2

.ecxr memcopies kỷ lục bối cảnh

để thiết lập các phạm vi bạn có thể sử dụng

EXT_COMMAND(setscope, "setscope", "{;e,[email protected]$ip;!setscope;}") 
{ 
    m_Symbols3->SetScopeFromStoredEvent(); 
} 

sau khi cuộc gọi này nếu bạn k vv nó sẽ được cho tập cuối cùng bối cảnh

:\>cdb -z oktest.dmp 
Microsoft (R) Windows Debugger Version 10.0.10586.567 X86 

This dump file has a breakpoint exception stored in it. 
The stored exception information can be accessed via .ecxr. 

0:000> k 
ChildEBP RetAddr 
0007fb1c 7c940442 ntdll!DbgBreakPoint 
0007fc94 7c9210af ntdll!LdrpInitializeProcess+0xffa 
0007fd1c 7c90e457 ntdll!_LdrpInitialize+0x183 
00000000 00000000 ntdll!KiUserApcDispatcher+0x7 


0:000> .load setscope 
0:000> !setscope 
0:000> k 


    *** Stack trace for last set context - .thread/.cxr resets it 
ChildEBP RetAddr 
0007fb1c 7c940442 ntdll!DbgBreakPoint 
0007fc94 7c9210af ntdll!LdrpInitializeProcess+0xffa 
0007fd1c 7c90e457 ntdll!_LdrpInitialize+0x183 
00000000 00000000 ntdll!KiUserApcDispatcher+0x7 
0:000> 

mã mở rộng đầy đủ bao gồm getstacktrace và outputstacktrace

#include <codeanalysis\warnings.h> 
#pragma warning(push) 
#pragma warning (disable : ALL_CODE_ANALYSIS_WARNINGS) 
#include <engextcpp.cpp> 
#pragma warning(pop) 
class EXT_CLASS : public ExtExtension 
{ 
public: 
    EXT_COMMAND_METHOD(setscope); 
}; 
EXT_DECLARE_GLOBALS(); 
EXT_COMMAND(setscope, "setscope", "{;e,[email protected]$ip;!setscope;}") 
{ 
    m_Symbols3->SetScopeFromStoredEvent(); 
    DEBUG_STACK_FRAME Frames[0x20] = {0}; 
    ULONG FramesFilled = NULL; 
    m_Control->GetStackTrace(0,0,0,Frames,0x20,&FramesFilled); 
    m_Control->OutputStackTrace(DEBUG_OUTCTL_THIS_CLIENT,Frames,FramesFilled,0x1fff); 
} 

KVF thực hiện và setscope

0:000> kVf 
    *** Stack trace for last set context - .thread/.cxr resets it 
# Memory ChildEBP RetAddr Args to Child    
00   0007fb1c 7c940442 00000000 00000000 00000000 ntdll!DbgBreakPoint (FPO: [0,0,0]) 
01  178 0007fc94 7c9210af 0007fd30 7c900000 0007fce0 ntdll!LdrpInitializeProcess+0xffa (FPO: [Non-Fpo]) 
02  88 0007fd1c 7c90e457 0007fd30 7c900000 00000000 ntdll!_LdrpInitialize+0x183 (FPO: [Non-Fpo]) 
03   00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7 
0:000> !setscope 
# Memory ChildEBP RetAddr Args to Child    
00   0007fb1c 7c940442 00000000 00000000 00000000 ntdll!DbgBreakPoint (FPO: [0,0,0]) 
01  178 0007fc94 7c9210af 0007fd30 7c900000 0007fce0 ntdll!LdrpInitializeProcess+0xffa (FPO: [Non-Fpo]) 
02  88 0007fd1c 7c90e457 0007fd30 7c900000 00000000 ntdll!_LdrpInitialize+0x183 (FPO: [Non-Fpo]) 
03   00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7 
+0

Tuyệt vời. Âm thanh như chính xác những gì tôi cần. –

1

Tôi nghĩ rằng không có cách nào kỳ diệu trong dbgeng để giữ lại một bối cảnh đăng ký và sử dụng nó trong mọi cuộc gọi API hơn nữa, nhưng nếu bạn nhận được một bối cảnh ngoại lệ từ IDebugControl4 :: GetStoredEventInformation () Tôi tin rằng bạn nên thích IDebugControl4 :: GetContextStackTrace() thay vì lừa GetStackTrace().

Các vấn đề liên quan