Mini dump

Programming/VisualStudio 2014. 8. 21. 11:47
#include "stdafx.h"
#include < WINDOWS.H >
#include < PSAPI.H >
#include < DBGHELP.H >
#include < STRING >
#pragma comment(lib, "psapi.lib") 
#pragma comment(lib, "dbghelp.lib") 

static bool CreateMinidump(const char outputFileName[], _EXCEPTION_POINTERS* ExceptionInfo);

static LPTOP_LEVEL_EXCEPTION_FILTER prevFilter = NULL;
static _invalid_parameter_handler prevInvParamHandler = NULL;
static _purecall_handler prevPureCallHandler = NULL;
static bool s_enableSorryDialogBoxAtCrash = true;
static MINIDUMP_TYPE s_miniDumpType = MiniDumpWithFullMemory;

wchar_t s_AdditionalInformation[256];
wchar_t s_GraphicInformation[256];
wchar_t s_SystemInformation[4096];


void WriteSystemInformation(const wchar_t* graphicInfo, const wchar_t* additionalInfo, wchar_t* destBuf, size_t destBufSize)
{
	std::string result;

	wchar_t* bufEnd = destBuf + destBufSize;
	wchar_t* pBuf = destBuf;

	// remained buffer size
#define rbs (bufEnd - pBuf)

	SYSTEM_INFO si;
	GetSystemInfo(&si);
	{
		pBuf += swprintf_s(pBuf, rbs, L"OEM ID: %d, Number of processors: %d\n", si.dwOemId, si.dwNumberOfProcessors);
		pBuf += swprintf_s(pBuf, rbs, L"Processor type: %d, Processor level: %d, Processor revision: %d\n", si.dwProcessorType, si.wProcessorLevel, si.wProcessorRevision);
	}

	{
		HKEY hKey;
		LONG lResult = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Hardware/Description/System/CentralProcessor/0", 0, KEY_QUERY_VALUE, &hKey);

		if (lResult == ERROR_SUCCESS)
		{
			DWORD dwVal;
			DWORD dwSize;
			wchar_t buf[256];
			DWORD typeDword = REG_DWORD;
			DWORD typeSz    = REG_SZ;

			dwSize = sizeof(dwVal);
			if (lResult = RegQueryValueExW(hKey, L"~MHz", NULL, &typeDword, (LPBYTE)&dwVal, &dwSize), lResult == ERROR_SUCCESS)
			{
				pBuf += swprintf_s(pBuf, rbs, L"CPU speed: %d MHz\n", dwVal);
			}

			dwSize = sizeof(buf) - 2;
			if (lResult = RegQueryValueExW(hKey, L"ProcessorNameString", NULL, &typeSz, (LPBYTE)buf, &dwSize), lResult == ERROR_SUCCESS)
			{
				pBuf += swprintf_s(pBuf, rbs, L"Processor name: %s\n", buf);
			}

			dwSize = sizeof(buf) - 2;
			if (lResult = RegQueryValueExW(hKey, L"Identifier", NULL, &typeSz, (LPBYTE)buf, &dwSize), lResult == ERROR_SUCCESS)
			{
				pBuf += swprintf_s(pBuf, rbs, L"Processor identifier: %s\n", buf);
			}

			RegCloseKey(hKey);
		}
	}

	_OSVERSIONINFOEXW osVersionInfoEx;
	ZeroMemory(&osVersionInfoEx, sizeof(_OSVERSIONINFOEXW));
	osVersionInfoEx.dwOSVersionInfoSize = sizeof(_OSVERSIONINFOEXW);
	if (GetVersionExW((_OSVERSIONINFOW*)&osVersionInfoEx))
	{
		pBuf += swprintf_s(pBuf, rbs, 
			L"dwMajorVersion: %ld; dwMinorVersion: %ld; dwBuildNumber: %ld; wServicePackMajor: %d; wServicePackMinor: %d\n",
			osVersionInfoEx.dwMajorVersion, osVersionInfoEx.dwMinorVersion, osVersionInfoEx.dwBuildNumber, osVersionInfoEx.wServicePackMajor, osVersionInfoEx.wServicePackMinor);
	}

	MEMORYSTATUS ms;
	GlobalMemoryStatus(&ms);
	{
		pBuf += swprintf_s(pBuf, rbs,  
			L"TotalPhys     : %8luk, AvailPhys     : %8luk, "
			L"TotalPagefile : %8luk, AvailPageFile : %8luk, "
			L"TotalVirtual  : %8luk, AvailVirtual  : %8luk\n",
			ms.dwTotalPhys / 1024, ms.dwAvailPhys/ 1024,
			ms.dwTotalPageFile/ 1024, ms.dwAvailPageFile/ 1024,
			ms.dwTotalVirtual/ 1024, ms.dwAvailVirtual/ 1024);
	}

	PROCESS_MEMORY_COUNTERS_EX pmcex;
	pmcex.cb = sizeof(pmcex);
	if(GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmcex, sizeof(pmcex)))
	{
		pBuf += swprintf_s(pBuf, rbs, L" Process memory information ===\n");
		pBuf += swprintf_s(pBuf, rbs, L"Page fault count           : %12ld, \n", pmcex.PageFaultCount);
		pBuf += swprintf_s(pBuf, rbs, L"PeakWorkingSetSize         : %12ldk, WorkingSetSize         : %12ldk\n", pmcex.PeakWorkingSetSize/1024, pmcex.WorkingSetSize/1024);
		pBuf += swprintf_s(pBuf, rbs, L"QuotaPeakPagedPoolUsage    : %12ldk, QuotaPagedPoolUsage    : %12ldk\n", pmcex.QuotaPeakPagedPoolUsage/1024, pmcex.QuotaPagedPoolUsage/1024);
		pBuf += swprintf_s(pBuf, rbs, L"QuotaPeakNonPagedPoolUsage : %12ldk, QuotaNonPagedPoolUsage : %12ldk\n", pmcex.QuotaPeakNonPagedPoolUsage/1024, pmcex.QuotaNonPagedPoolUsage/1024);
		pBuf += swprintf_s(pBuf, rbs, L"PeakPagefileUsage          : %12ldk, PagefileUsage          : %12ldk\n", pmcex.PeakPagefileUsage/1024, pmcex.PagefileUsage/1024);
		pBuf += swprintf_s(pBuf, rbs, L"PrivateUsage               : %12ldk\n", pmcex.PrivateUsage/1024);
	}
	else
	{
		pBuf += swprintf_s(pBuf, rbs, L"Process memory information unavailable.\n");
	}

	pBuf += swprintf_s(pBuf, rbs, L"\n Graphic Information ===\n%s\n", graphicInfo);
	pBuf += swprintf_s(pBuf, rbs, L"\n Additional Information ===\n%s\n", additionalInfo);

#undef rbs
}


static bool CreateMinidump(const char outputFileName[], _EXCEPTION_POINTERS* ExceptionInfo)
{
	WriteSystemInformation(s_GraphicInformation, s_AdditionalInformation, s_SystemInformation, 4096);

	MINIDUMP_EXCEPTION_INFORMATION* pExcInfo = NULL;

	MINIDUMP_EXCEPTION_INFORMATION excInfo;
	if(ExceptionInfo)
	{
		excInfo.ClientPointers    = FALSE;
		excInfo.ExceptionPointers = ExceptionInfo;
		excInfo.ThreadId          = GetCurrentThreadId();
		pExcInfo = &excInfo;
	}

	MINIDUMP_USER_STREAM userStreams[2];

	userStreams[0].Type = SystemInfoStream;
	userStreams[0].BufferSize = sizeof(SYSTEM_INFO);
	SYSTEM_INFO si;
	GetSystemInfo(&si);
	userStreams[0].Buffer = &si;

	userStreams[1].Type = CommentStreamW;
	userStreams[1].BufferSize = 4096;
	userStreams[1].Buffer = s_SystemInformation;

	MINIDUMP_USER_STREAM_INFORMATION userInfo;
	userInfo.UserStreamCount = 2;
	userInfo.UserStreamArray = userStreams;

	HANDLE fileHandle = CreateFileA(outputFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if(fileHandle == INVALID_HANDLE_VALUE)
		return false;

	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), 
		fileHandle, s_miniDumpType, pExcInfo, &userInfo, NULL);

	CloseHandle(fileHandle);
	return true;
}

static void MakeDumpFileName(char dumpFileName[], void* address)
{
	//실행 파일
	char execPath[MAX_PATH];
	GetModuleFileName(NULL, execPath, MAX_PATH);
	char* p = strrchr(execPath, '\\');

	// 컴퓨터 이름
	char computerName[MAX_PATH];
	DWORD len = MAX_PATH;

	GetComputerName(computerName, &len);

	//현재 시간
	SYSTEMTIME lt;
	GetLocalTime(<);

	sprintf_s(dumpFileName, MAX_PATH, "%s %p @ %s (%d-%02d-%02d %02d;%02d;%02d).dmp",
		p + 1, address,
		computerName, lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);
}

void CreateMiniDumpNow()
{
	char outputFileName[MAX_PATH] = "minidump.dmp";
	MakeDumpFileName(outputFileName, (void*)0x7FFFFFFF);
	CreateMinidump(outputFileName, NULL);
}


static LONG WINAPI CrashHandlerExceptionFilter(_EXCEPTION_POINTERS* exceptionInfo)
{
	char outputFileName[MAX_PATH];
	strcpy(outputFileName, "minidump.dmp");
	MakeDumpFileName(outputFileName, exceptionInfo->ExceptionRecord->ExceptionAddress);
	CreateMinidump(outputFileName, exceptionInfo);

	// 에러메시지창을 띄우고
	MessageBox(NULL, "프로그램이 죽었습니다.\n\n개발팀에 문의해주세요.", "MapleStory2", MB_OK);

	// 프로세스 종료
	TerminateProcess(GetCurrentProcess(), 2);

	return EXCEPTION_EXECUTE_HANDLER;
}

static void InvParamHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
{
	_asm int 3;
}

static void PureVirtualFunctionCallHandler()
{
	_asm int 3;
}

int _tmain(int argc, _TCHAR* argv[])
{
	prevFilter = SetUnhandledExceptionFilter(CrashHandlerExceptionFilter);
	prevInvParamHandler = _set_invalid_parameter_handler(&InvParamHandler);
	prevPureCallHandler = _set_purecall_handler(&PureVirtualFunctionCallHandler);

	int* x = 0;

	*x = 100;

	return 0;
}


'Programming > VisualStudio' 카테고리의 다른 글

네이티브 환경에서 사용자 정의 그래픽 시각화 만들기  (0) 2014.10.23
VTune 세팅법  (0) 2014.10.15
리소스 편집  (0) 2014.07.18
The Windows Heap Is Slow When Launched from the Debugger  (0) 2014.07.16
autoexp.dat  (0) 2014.06.08

리소스 편집

Programming/VisualStudio 2014. 7. 18. 17:31

'Programming > VisualStudio' 카테고리의 다른 글

네이티브 환경에서 사용자 정의 그래픽 시각화 만들기  (0) 2014.10.23
VTune 세팅법  (0) 2014.10.15
Mini dump  (0) 2014.08.21
The Windows Heap Is Slow When Launched from the Debugger  (0) 2014.07.16
autoexp.dat  (0) 2014.06.08

The Windows Heap Is Slow When Launched from the Debugger

Programming/VisualStudio 2014. 7. 16. 10:41

'Programming > VisualStudio' 카테고리의 다른 글

네이티브 환경에서 사용자 정의 그래픽 시각화 만들기  (0) 2014.10.23
VTune 세팅법  (0) 2014.10.15
Mini dump  (0) 2014.08.21
리소스 편집  (0) 2014.07.18
autoexp.dat  (0) 2014.06.08

autoexp.dat

Programming/VisualStudio 2014. 6. 8. 19:15

http://msdn.microsoft.com/ko-kr/library/zf0e8s14.aspx

atl이나 atlport를 디버깅 할 때 해당 컨테이너의 값을 보기가 힘든데

autoexp.data 를 수정하면 보기 편하게 바꿀수 있다.

 

autoexp.dat

 

 

'Programming > VisualStudio' 카테고리의 다른 글

네이티브 환경에서 사용자 정의 그래픽 시각화 만들기  (0) 2014.10.23
VTune 세팅법  (0) 2014.10.15
Mini dump  (0) 2014.08.21
리소스 편집  (0) 2014.07.18
The Windows Heap Is Slow When Launched from the Debugger  (0) 2014.07.16