您的位置:首页 > 其它

使用dmp查看程序崩溃信息

2016-10-09 15:31 323 查看
一使用Visual Studio调试dmp

(1)把dmp,PDB文件,放在exe同一目录下(PDB文件必须是与exe同时编译生成的)

(2)代码回滚到编译exe时的版本

(3)双击dmp文件,或把dmp文件拖动到Visual studio窗口

#1


(4)点击仅限本机进行调试

#2


#3


(5)然后可以查看调用堆栈等分析操作

【提示】如果查找堆栈提示找不到源码,可以右键项目“属性”-》“调试源文件”,设置源码根路径

#4


二 生成dmp

(1)使用任务管理器生成

tab栏“进程”-》右键”创建转存文件”

#5


(2)C++代码中,使用DbgHelp模块的MINIDUMP编程生成

#include "DbgHelp.h"
typedef BOOL (WINAPI* MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType,
CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);

long CSE_Exception::_DbgDumpError(struct _EXCEPTION_POINTERS *excpInfo, LPCTSTR szPrex )
{

LONG retval = EXCEPTION_CONTINUE_SEARCH;

HMODULE hDll = ::LoadLibrary(_T("DBGHELP.DLL"));
LPCTSTR szResult = NULL;
MINIDUMPWRITEDUMP pDump = NULL;

if (hDll)
pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(hDll,"MiniDumpWriteDump");

if (pDump)
{
TCHAR szDumpPath [_MAX_PATH] = {0};
TCHAR szDumpFile [_MAX_PATH] = {0};
GetModuleFileName(NULL, szDumpPath, _MAX_PATH);
_tcsrchr(szDumpPath, _T('\\'))[1] = 0;
_tcscat(szDumpPath, _T("..\\logs\"));

time_t timeCurrent = time(0);
struct tm* tmc = localtime(&timeCurrent);
if ( tmc )
_stprintf(szDumpFile, _T("%s%d_%d_%d_%d_%d.dmp"), szPrex, tmc->tm_mon+1, tmc->tm_mday, tmc->tm_hour, tmc->tm_min, tmc->tm_sec);
else
_tcscpy(szDumpFile, _T("error.dmp"));
_tcscat(szDumpPath, szDumpFile);

// create the file
HANDLE hFile = ::CreateFile( szDumpPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL );

if (hFile!=INVALID_HANDLE_VALUE)
{
if (excpInfo == NULL) //如果没有传入异常, 比如是在程序里面调用的, 生成一个异常
{
// Generate exception to get proper context in dump

DWORD dwSize = 0;
char *sz = "_EXCEPTION_POINTERS is null";
::WriteFile(hFile, sz, strlen(sz), &dwSize, NULL);
}
else
{
MINIDUMP_EXCEPTION_INFORMATION eInfo;
eInfo.ThreadId = GetCurrentThreadId(); //把需要的信息添进去
eInfo.ExceptionPointers = excpInfo;
eInfo.ClientPointers = FALSE;

// Dump的类型是小型的, 节省空间. 可以参考MSDN生成更详细的Dump.
pDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
excpInfo ? &eInfo : NULL,
NULL,
NULL);
}
::CloseHandle(hFile);

}
}
if( hDll )
::FreeLibrary(hDll);

return retval;
}

void CSE_Exception::InitSEException()
{
_set_se_translator( CSE_Exception::trans_func );
}

void CSE_Exception::_DumpCallStack()
{
__try
{
__try
{
RaiseException(1, 0, 0, NULL);
}
__finally
{
}
}
__except(_DbgDumpError(GetExceptionInformation(), _T("T")),
EXCEPTION_CONTINUE_EXECUTION)
{
}
}

void CSE_Exception::trans_func( unsigned int uSENum, _EXCEPTION_POINTERS* pExp )
{
#define SE_BUF_SIZE         250
TCHAR pszBuf[SE_BUF_SIZE+2];

_DbgDumpError(pExp, _T("e"));
switch(uSENum)
{
case EXCEPTION_ACCESS_VIOLATION:
_sntprintf(pszBuf, SE_BUF_SIZE, _T("Access Violation: IP: 0xX %s Address: 0xX"),
pExp->ExceptionRecord->ExceptionAddress, pExp->ExceptionRecord->ExceptionInformation[0]?_T("Write"):_T("Read"), pExp->ExceptionRecord->ExceptionInformation[1]);
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
_sntprintf(pszBuf, SE_BUF_SIZE, _T("INT_DIVIDE_BY_ZERO"));
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
_sntprintf(pszBuf, SE_BUF_SIZE, _T("FLT_DIVIDE_BY_ZERO"));
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
_sntprintf(pszBuf, SE_BUF_SIZE, _T("ILLEGAL_INSTRUCTION"));
break;
case EXCEPTION_PRIV_INSTRUCTION:
_sntprintf(pszBuf, SE_BUF_SIZE, _T("EXCEPTION_PRIV_INSTRUCTION"));
break;
case EXCEPTION_STACK_OVERFLOW:
_sntprintf(pszBuf, SE_BUF_SIZE, _T("EXCEPTION_STACK_OVERFLOW"));
break;
default:
_sntprintf(pszBuf, SE_BUF_SIZE, _T("Unknown SE_exception: X"), uSENum);
break;
}

CSE_Exception e(pszBuf);
e.m_nSENumber = uSENum;
e.m_SERecord  = *(pExp->ExceptionRecord);
e.m_SEContext  = *(pExp->ContextRecord);

throw e;
}

然后在程序的InitInstance中加入代码如下:
LONG WINAPI DbgUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
{
CSE_Exception::_DbgDumpError(pExceptionInfo, _T("E"));
return EXCEPTION_CONTINUE_SEARCH;    // 程序停止运行
}
BOOL CDCPWorkerApp::InitInstance()
{
//EHA
CSE_Exception::InitSEException();
//捕获未处理的异常
SetUnhandledExceptionFilter(DbgUnhandledExceptionFilter);
}


三 常见错误码含义

(1)0xC0000005 内存越界、野指针、重复释放指针等;

(0xBCD20000 处有未经处理的异常(在 MPR-FAST-5080-20160928115806.dmp 中): 0xC0000005: 执行位置 0xBCD20000 时发生访问冲突。)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐