2011-07-26 5 views
1

Windows 시스템의 BSOD 때문에 일부 미니 덤프가 있습니다.WinDbg 및 "! analyze -v": BSOD에서 미니 덤프를 프로그래밍 방식으로 분석 할 수 있습니까?

!analyze -v 확장을 사용하여 수동으로 WinDbg에서 분석 할 수 있지만 프로그래밍 방식으로 분석 할 수 있는지 알고 싶습니다.

분석을 수행하기위한 API가 있습니까? 예 :

감사합니다.

알레산드로

편집 :

나는 다음 예제 코드를 추가합니다. 나는 그것을 빌드하고 WinDbg 폴더에 exe 파일을 복사한다 (내 시스템에서는 %ProgramFiles%\WinDbg). 그런 다음 (Microsoft (R) Windows Debugger Version 6.11.0001.404 X86) 테스트를하고 수동으로 수행 한 분석 결과와 동일한 결과를 얻는다. WinDbg.

#include <dbgeng.h> 
#include <atlbase.h> 

#include <string> 
#include <iostream> 

// For class StdioOutputCallbacks see: 
// http://blogs.msdn.com/b/sqlblog/archive/2009/12/30/tools-of-the-trade-part-iv-developing-windbg-extension-dlls.aspx 
class StdioOutputCallbacks : public IDebugOutputCallbacks 
{ 
private: 
    std::string m_OutputBuffer; 
    CHAR m_OutPutBuffer[4096]; 

public: 
    void InitOutPutBuffer(); 

    std::string GetOutputBuffer() 
    { 
     return m_OutputBuffer; 
    }; 

    void ClearOutPutBuffer()    
    { 
     m_OutputBuffer = ""; 
    }; 

    STDMETHOD(QueryInterface)(IN REFIID InterfaceId, OUT PVOID* Interface); 

    STDMETHOD_(ULONG, AddRef)(); 

    STDMETHOD_(ULONG, Release)(); 

    STDMETHOD(Output)(IN ULONG Mask, IN PCSTR Text); 
}; 

StdioOutputCallbacks g_OutputCb; 

STDMETHODIMP StdioOutputCallbacks::QueryInterface(IN REFIID InterfaceId, 
                OUT PVOID* Interface) 
{ 
    *Interface = NULL; 
    if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) || 
     IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks))) 
    { 
     *Interface = (IDebugOutputCallbacks *)this; 
     AddRef(); 
     return S_OK; 
    } 
    else 
    { 
     return E_NOINTERFACE; 
    } 
} 

STDMETHODIMP_(ULONG) StdioOutputCallbacks::AddRef() 
{ 
    // This class is designed to be static so 
    // there's no true refcount. 
    return 1; 
} 

STDMETHODIMP_(ULONG) StdioOutputCallbacks::Release() 
{ 
    // This class is designed to be static so 
    // there's no true refcount. 
    return 0; 
} 

STDMETHODIMP StdioOutputCallbacks::Output(IN ULONG Mask, IN PCSTR Text) 
{ 
    UNREFERENCED_PARAMETER(Mask); 
    m_OutputBuffer += Text; 
    return S_OK; 
} 

void StdioOutputCallbacks::InitOutPutBuffer() 
{ 
    m_OutputBuffer.erase(); 
} 

int analyze(const char* dump_file) 
{ 
    // See: http://pwiki.pontetec.com/index.php?title=Hooking_Windbg&printable=yes 

    CComPtr<IDebugClient> client; 
    HRESULT hr = DebugCreate(__uuidof(IDebugClient), 
          reinterpret_cast<LPVOID*>(&client)); 
    if (FAILED(hr)) return __LINE__; 

    CComQIPtr<IDebugControl> control(client); 
    if (!control) return __LINE__; 

    hr = client->SetOutputCallbacks(&g_OutputCb); 
    if (FAILED(hr)) return __LINE__; 

    CComQIPtr<IDebugSymbols> symbols(client); 
    if (!symbols) return __LINE__; 

    hr = symbols->SetSymbolPath("srv*http://msdl.microsoft.com/download/symbols"); 
    if (FAILED(hr)) return __LINE__; 

    hr = client->OpenDumpFile(dump_file); 
    if (FAILED(hr)) return __LINE__; 

    // it seems it is always returning E_INVALIDARG... so we don't check hr 
    control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE); 

    std::cout << "\n\n*** Output after loading the dump:\n\n"; 
    std::cout << g_OutputCb.GetOutputBuffer().c_str(); 

    g_OutputCb.ClearOutPutBuffer(); 

    hr = control->Execute(DEBUG_OUTCTL_THIS_CLIENT | 
          DEBUG_OUTCTL_OVERRIDE_MASK | 
          DEBUG_OUTCTL_NOT_LOGGED, 
          "!analyze -v", 
          DEBUG_EXECUTE_DEFAULT); 
    if (FAILED(hr)) return __LINE__; 

    ::Sleep(15000); 

    std::cout << "\n\n*** Output after the command `!analyze -v`:\n\n"; 
    std::cout << g_OutputCb.GetOutputBuffer().c_str(); 

    return 0; 
} 



int main(int argc, char* argv[]) 
{ 
    HRESULT hr = CoInitialize(NULL); 

    int r = analyze(argv[1]); 

    CoUninitialize(); 

    return r; 
} 

답변

0

MiniDumpReadDumpStream이 작업을 수행해야하는 것처럼 보입니다.

+0

의사가 '사용자 모드 미니 덤프 파일'에서 말한 이후로는 작동하지 않을 것이라고 생각합니다. 커널 모드에서 덤프를 나타내는 BSOD를 얻는 경우. – linuxuser27

관련 문제