MiniDump.h
#pragma once
#include "dbghelp.h"
class Mini_Dump
{
public:
Mini_Dump(void);
static Mini_Dump *gpDumper;
protected:
static LONG WINAPI Handler(struct _EXCEPTION_POINTERS *pExceptionInfo);
_EXCEPTION_POINTERS *m_pExceptionInfo;
TCHAR m_szDumpPath[_MAX_PATH];
TCHAR m_szAppPath[_MAX_PATH];
TCHAR m_szAppBaseName[_MAX_PATH];
LONG WriteMiniDump(_EXCEPTION_POINTERS *pExceptionInfo);
virtual void VSetDumpFileName(void);
virtual MINIDUMP_USER_STREAM_INFORMATION *VGetUserStreamArray() {return NULL;};
};
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);
MiniDump.cpp
#include <windows.h>
#include "MiniDump.h"
#include "assert.h"
Mini_Dump *Mini_Dump::gpDumper = NULL;
//// 클래스 생성 함수
Mini_Dump::Mini_Dump( void )
{
assert(!gpDumper);
if(!gpDumper)
{
::SetUnhandledExceptionFilter(Handler);
gpDumper = this;
}
}
//// 덤저장 핸들
LONG Mini_Dump::Handler(_EXCEPTION_POINTERS *pExceptionInfo)
{
LONG retvel = EXCEPTION_CONTINUE_SEARCH;
// 덤프 확인
if(!gpDumper)
{
return retvel;
}
// 텀프 저장
return gpDumper->WriteMiniDump(pExceptionInfo);
}
//// 덤프를 저장한다.
LONG Mini_Dump::WriteMiniDump(_EXCEPTION_POINTERS *pExceptionInfo)
{
LONG retvel = EXCEPTION_CONTINUE_SEARCH;
// 익셉션 포인터 저장
m_pExceptionInfo = pExceptionInfo;
// dbghelp.dll 찾기
HMODULE hDll = NULL;
TCHAR szDbgHelpPath[_MAX_PATH];
if(GetModuleFileName(NULL,m_szAppPath,_MAX_PATH))
{
TCHAR *pSlash = strrchr(m_szAppPath,'\\');
if(pSlash)
{
strcpy(m_szAppBaseName,pSlash +1);
*(pSlash+1) = 0;
}
strcpy(szDbgHelpPath,m_szAppPath);
strcat(szDbgHelpPath,"DBGHELP.DLL");
hDll = ::LoadLibrary(szDbgHelpPath);
}
if(hDll == NULL)
{
// DLL 다시 한번 찾기
hDll = ::LoadLibrary("DBGHELP.DLL");
}
TCHAR szResult[_MAX_PATH];
BOOL bResult;
if(hDll)
{
MINIDUMPWRITEDUMP pMiniDumpWriteDump = (MINIDUMPWRITEDUMP)::GetProcAddress(hDll,"MiniDumpWriteDump");
if(pMiniDumpWriteDump)
{
// 덤프 파일 이름 설정
VSetDumpFileName();
// 덤프 파일 저장
HANDLE hFile = ::CreateFile(m_szDumpPath,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
_MINIDUMP_EXCEPTION_INFORMATION ExInfo;
ExInfo.ThreadId = ::GetCurrentThreadId();
ExInfo.ExceptionPointers = pExceptionInfo;
ExInfo.ClientPointers = NULL;
// 덤프 기록
BOOL bOK = pMiniDumpWriteDump(GetCurrentProcess(),GetCurrentProcessId(),
hFile,MiniDumpNormal,&ExInfo,VGetUserStreamArray(),NULL);
if(bOK)
{
wsprintf(szResult,"");
bResult = false;
retvel = EXCEPTION_EXECUTE_HANDLER;
}
else
{
bResult = true;
}
::CloseHandle(hFile);
}
else
{
// 파일 생성 오류
bResult = true;
}
}
else
{
wsprintf(szResult,"DBGHELP.DLL 구버전 입니다.");
bResult = true;
}
}
else
{
wsprintf(szResult,"DBBHELP.DLL 없습니다.");
bResult = true;
}
TerminateProcess(GetCurrentProcess(),0);
return retvel;
}
//// 저장 덤프 파일의 풀 경로 설정
void Mini_Dump::VSetDumpFileName()
{
// 저장 파일 이름 설정
wsprintf(m_szDumpPath,"%s%s.dmp",m_szAppPath,m_szAppBaseName);
}
Main.cpp
#include "stdafx.h"
#include <Windows.h>
#include "MiniDump.h"
void (*g_pRandFunction[5])();
void OnTest1(void)
{
int nRandValue = rand()%5;
g_pRandFunction[nRandValue]();
}
void OnTest2(void)
{
int nRandValue = rand()%5;
g_pRandFunction[nRandValue]();
}
void OnTest3(void)
{
int *p = NULL;
for( int i = 0; i < 20000; i++ )
{
p[i] = 100;
}
}
void OnTest4(void)
{
int nRandValue = rand()%5;
g_pRandFunction[nRandValue]();
}
void OnTest5(void)
{
int *p = NULL;
for( int i = 0; i < 1000; i++ )
{
p[i] = 100;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Mini_Dump::gpDumper = new Mini_Dump;
// 메모리 할당 실패 테스트
//char *pc1 = new char[1000000000];
//char *pc2 = new char[1000000000];
//char *pc3 = new char[1000000000];
//char *pc4 = new char[0x7fffffff];
g_pRandFunction[0] = OnTest1;
g_pRandFunction[1] = OnTest2;
g_pRandFunction[2] = OnTest3;
g_pRandFunction[3] = OnTest4;
g_pRandFunction[4] = OnTest5;
srand(GetTickCount());
int nRandValue = rand()%5;
g_pRandFunction[nRandValue]();
return 0;
}