2016-08-30 49 views
5

Windows Hata Raporlaması'ndan elde edilen dökümler, genellikle WerpReportFault numaralı bir yığında derin bir yığınla birlikte, hata iş parçacığı üzerinde kullanılan işe yaramaz bir geçerli içeriğe sahiptir. İstisna zamanındaki asıl içerik, .ecxr ile geri alınabilir - aynı zamanda bağlamı, aynı iş parçacığı üzerinde (k gibi) "doğru" bilgiyi döndürecek şekilde de ayarlar.Depolanmış özel durum içeriğinden yığın izlemesinin bir minidump içinde geri alınması (.ecxr; k'ye benzer)

Hatalı iş parçacığı kümesini elde etmek için IDebugControl::GetStackTrace kullanan otomatik döküm analizi için bir araç hazırlıyorum. IDebugControl4::GetStoredEventInformation kullanarak depolanmış istisna bağlamını alabilirim. EBP/RBP, ESP/RSP, EIP/RIP değerlerini saklanan içerikten GetStackTrace ile kullanırsam, doğru yığını alırım. Ancak, .ecxr komutunun, iş parçacığı olana kadar "doğru" durumu ayarlayarak ne yaptığını çoğaltmak isterim. IDebugAdvanced::SetThreadContext kullanmayı denedim, ancak dökümü hedefler için geçersiz bir işlem gibi görünüyor ve 0x8000FFFF ile başarısız.

Ben .ecxr bir WinDbg örneği ayıklama yoluyla ne yaptığını anlamaya çalıştı ve .ecxr dbgeng!DotEcxr uygulanan gibi görünüyor. Ancak, onu izlemeden ( wt ile), geçerli iş parçacığının içeriğini nasıl sıfırladığını anlayamadım. Yine de, herhangi bir COM hata ayıklama-istemci arabirimi yöntemini çağırıyor gibi görünmüyor ve IDebugAdvanced::SetThreadContext kullanmıyor.

İş parçacığı içeriğini bir döküm dosyasında nasıl ayarlayacağınız konusunda herhangi bir öneri çok takdir edilecektir. Son çare olarak, her zaman IDebugControl::Execute kullanabilir ve .ecxr komutunu çağırırım, ancak daha programlı bir yaklaşım tercih ederim.

cevap

2

.ecxr vb son olarak ayarlandığı bağlamında

:\>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> 
olacak k yoksa

kapsamını belirlemek için bu çağrıdan sonra bu

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

kullanabilirsiniz bağlam rekoru memcopies getStackTrace ve 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); 
} 
dahil

tam uzatma kodu

idam KVF ve 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

Harika. Tam olarak ihtiyacım olana benziyor. –

1

Bir kayıt bağlamını korumak ve her ileri API çağrısında kullanmak için dbgeng hiçbir sihirli bir yolu yoktur düşünüyorum, ama sen (IDebugControl4 :: GetStoredEventInformation bir istisna bağlamı alırsanız) GetStackTrace() 'i kandırmak yerine IDebugControl4 :: GetContextStackTrace() yöntemini tercih etmeniz gerektiğine inanıyorum.