dmp文件自动分析
dmp文件的分析,可以借助各种工具,比如WinDbg, CDB , NTSD,KD等。Windbg提供了窗口接口,而CDB , NTSD是基于命令行的工具,它们都使用了同样的调试引擎Dbgeng.dll,该调试引擎就是 “Windows 调试程序”。
dbgeng.dll 可以在基于x86,x64 或ARM的处理器上运行,并且可以调试在那些相同体系结构上运行的代码。
dbgeng.dll 的使用:
out.hpp
#ifndef __OUT_HPP__
#define __OUT_HPP__
#include <DbgEng.h>
class StdioOutputCallbacks : public IDebugOutputCallbacks
{
public:
// IUnknown.
STDMETHOD(QueryInterface)(
THIS_
_In_ REFIID InterfaceId,
_Out_ PVOID* Interface
);
STDMETHOD_(ULONG, AddRef)(
THIS
);
STDMETHOD_(ULONG, Release)(
THIS
);
// IDebugOutputCallbacks.
STDMETHOD(Output)(
THIS_
_In_ ULONG Mask,
_In_ PCSTR Text
);
};
extern StdioOutputCallbacks g_OutputCb;
#endif // #ifndef __OUT_HPP__
out.cpp
#include <stdio.h>
#include <windows.h>
#include <dbgeng.h>
#include "out.hpp"
StdioOutputCallbacks g_OutputCb;
FILE *fp = NULL;
STDMETHODIMP
StdioOutputCallbacks::QueryInterface(
THIS_
_In_ REFIID InterfaceId,
_Out_ PVOID* Interface
)
{
if (!fp) {
fp = fopen("D:/ZZZ/analyze.txt", "w+");
}
*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
)
{
// This class is designed to be static so
// there's no true refcount.
return 1;
}
STDMETHODIMP_(ULONG)
StdioOutputCallbacks::Release(
THIS
)
{
// This class is designed to be static so
// there's no true refcount.
//fclose(fp);
return 0;
}
STDMETHODIMP
StdioOutputCallbacks::Output(
THIS_
_In_ ULONG Mask,
_In_ PCSTR Text
)
{
UNREFERENCED_PARAMETER(Mask);
//fputs(Text, fp);
fputs(Text, stdout);
return S_OK;
}
main.cpp
#include "out.hpp" #include <stdlib.h> #include <stdio.h> #include <stdarg.h>
#include <windows.h> #include <dbgeng.h>
PSTR g_DumpFile; IDebugClient* g_Client; IDebugControl* g_Control; IDebugSymbols3* g_Symbols3; void Exit(int Code, _In_ _Printf_format_string_ PCSTR Format, ...) { // Clean up any resources. if (g_Symbols3 != NULL) { g_Symbols3->Release(); } if (g_Control != NULL) { g_Control->Release(); } if (g_Client != NULL) { g_Client->SetOutputCallbacks(NULL); g_Client->EndSession(DEBUG_END_PASSIVE); g_Client->Release(); } // Output an error message if given. if (Format != NULL) { va_list Args; va_start(Args, Format); vfprintf(stderr, Format, Args); va_end(Args); } exit(Code); } void CreateInterfaces(void) { HRESULT Status; // Start things off by getting an initial interface from // the engine. This can be any engine interface but is // generally IDebugClient as the client interface is // where sessions are started. if ((Status = DebugCreate(__uuidof(IDebugClient), (void**)&g_Client)) != S_OK) { Exit(1, "DebugCreate failed, 0x%X\n", Status); } // Query for some other interfaces that we'll need. if ((Status = g_Client->QueryInterface(__uuidof(IDebugControl), (void**)&g_Control)) != S_OK || (Status = g_Client->QueryInterface(__uuidof(IDebugSymbols3), (void**)&g_Symbols3)) != S_OK) { Exit(1, "QueryInterface failed, 0x%X\n", Status); } } //typedef _Null_terminated_ CHAR *TTPSTR; void ParseCommandLine(int Argc, _In_reads_(Argc) PSTR* Argv) { int i; while (--Argc > 0) { Argv++; if (!strcmp(Argv[0], "-z")) { Argv++; Argc--; if (Argc > 0) { g_DumpFile = Argv[0]; } else { Exit(1, "-z missing argument\n"); } } else { //Exit(1, "Unknown command line argument '%s'\n", Argv[0]); } } if (g_DumpFile == NULL) { Exit(1, "No dump file specified, use -z <file>\n"); } } void ApplyCommandLineArguments(void) { HRESULT Status; // Install output callbacks so we get any output that the // later calls produce. if ((Status = g_Client->SetOutputCallbacks(&g_OutputCb)) != S_OK) { Exit(1, "SetOutputCallbacks failed, 0x%X\n", Status); } // Everything's set up so open the dump file. if ((Status = g_Client->OpenDumpFile(g_DumpFile)) != S_OK) { Exit(1, "OpenDumpFile failed, 0x%X\n", Status); } // Finish initialization by waiting for the event that // caused the dump. This will return immediately as the // dump file is considered to be at its event. if ((Status = g_Control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE)) != S_OK) { Exit(1, "WaitForEvent failed, 0x%X\n", Status); } // Everything is now initialized and we can make any // queries we want. } void DumpStack(void) { HRESULT Status; DEBUG_STACK_FRAME Frames[3] = { 0 }; ULONG Filled; g_Symbols3->SetScopeFromStoredEvent(); if (Frames == NULL) { Exit(1, "Unable to allocate stack frames\n"); } if ((Status = g_Control-> GetStackTrace(0, 0, 0, Frames, 3, &Filled)) != S_OK) { Exit(1, "GetStackTrace failed, 0x%X\n", Status); } printf("\nFirst %d frames of the call stack:\n", Filled); //// Print the call stack. if ((Status = g_Control-> OutputStackTrace(DEBUG_OUTCTL_ALL_CLIENTS, Frames, Filled, DEBUG_STACK_ARGUMENTS | DEBUG_STACK_SOURCE_LINE | DEBUG_STACK_FRAME_ADDRESSES | DEBUG_STACK_COLUMN_NAMES | DEBUG_STACK_FRAME_NUMBERS)) != S_OK) { Exit(1, "OutputStackTrace failed, 0x%X\n", Status); } } int main(int argc, char *argv[]) { CreateInterfaces(); ParseCommandLine(argc, argv); ApplyCommandLineArguments(); DumpStack(); return 0; }

浙公网安备 33010602011771号