From bc3c8299e8d06db5b5b2c013425348805b660909 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Fri, 4 Mar 2016 03:05:09 +0100 Subject: [PATCH] Moved minidump code to MiniDump.cpp from main. --- include/Game/MiniDump.h | 4 +- src/Game/MiniDump.cpp | 139 ++++++++++++++-------------------------- src/Game/main.cpp | 98 +--------------------------- 3 files changed, 52 insertions(+), 189 deletions(-) diff --git a/include/Game/MiniDump.h b/include/Game/MiniDump.h index a984f6e4..022622a7 100644 --- a/include/Game/MiniDump.h +++ b/include/Game/MiniDump.h @@ -1,11 +1,9 @@ #ifndef MiniDump_h__ #define MiniDump_h__ +#include #include -#include -#include - long WINAPI Create_Dump_Immediate(LPEXCEPTION_POINTERS pException); #endif diff --git a/src/Game/MiniDump.cpp b/src/Game/MiniDump.cpp index 4ebf1536..01ed4c90 100644 --- a/src/Game/MiniDump.cpp +++ b/src/Game/MiniDump.cpp @@ -1,102 +1,49 @@ /* - Author: Vladimir Sedach. +Inspired by Original Author: Vladimir Sedach. - Purpose: demo of Call Stack creation by our own means, - and with MiniDumpWriteDump() function of DbgHelp.dll. +Purpose: demo of Call Stack creation by our own means, +and with MiniDumpWriteDump() function of DbgHelp.dll. */ +#include "MiniDump.h" + +#include #include #include - -#include #include -#include -//#include "dbghelp.h" -//#define DEBUG_DPRINTF 1 //allow d() -//#include "wfun.h" +#pragma optimize("y", off) //generate stack frame pointers for all functions - same as /Oy- in the project +#pragma warning(disable: 4200) //nonstandard extension used : zero-sized array in struct/union +#pragma warning(disable: 4100) //unreferenced formal parameter -#pragma optimize("y", off) //generate stack frame pointers for all functions - same as /Oy- in the project -#pragma warning(disable: 4200) //nonstandard extension used : zero-sized array in struct/union -#pragma warning(disable: 4100) //unreferenced formal parameter - -// In case you don't have dbghelp.h. -#ifndef _DBGHELP_ - -typedef struct _MINIDUMP_EXCEPTION_INFORMATION { - DWORD ThreadId; - PEXCEPTION_POINTERS ExceptionPointers; - BOOL ClientPointers; -} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; - -typedef enum _MINIDUMP_TYPE -{ - MiniDumpNormal = 0x00000000, - MiniDumpWithDataSegs = 0x00000001, - MiniDumpWithFullMemory = 0x00000002, - MiniDumpWithHandleData = 0x00000004, - MiniDumpFilterMemory = 0x00000008, - MiniDumpScanMemory = 0x00000010, - MiniDumpWithUnloadedModules = 0x00000020, - MiniDumpWithIndirectlyReferencedMemory = 0x00000040, - MiniDumpFilterModulePaths = 0x00000080, - MiniDumpWithProcessThreadData = 0x00000100, - MiniDumpWithPrivateReadWriteMemory = 0x00000200, - MiniDumpWithoutOptionalData = 0x00000400, - MiniDumpWithFullMemoryInfo = 0x00000800, - MiniDumpWithThreadInfo = 0x00001000, - MiniDumpWithCodeSegs = 0x00002000, - MiniDumpWithoutManagedState = 0x00004000, -} MINIDUMP_TYPE; - -typedef BOOL (WINAPI * MINIDUMP_WRITE_DUMP)( - IN HANDLE hProcess, - IN DWORD ProcessId, - IN HANDLE hFile, - IN MINIDUMP_TYPE DumpType, - IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL - IN PVOID UserStreamParam, OPTIONAL - IN PVOID CallbackParam OPTIONAL - ); - -#else - -typedef BOOL (WINAPI * MINIDUMP_WRITE_DUMP)( - IN HANDLE hProcess, - IN DWORD ProcessId, - IN HANDLE hFile, - IN MINIDUMP_TYPE DumpType, - IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL - IN PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL - IN PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL - ); -#endif //#ifndef _DBGHELP_ - -HMODULE hDbgHelp; -MINIDUMP_WRITE_DUMP MiniDumpWriteDump_; - -// Tool Help functions. -typedef HANDLE (WINAPI * CREATE_TOOL_HELP32_SNAPSHOT)(DWORD dwFlags, DWORD th32ProcessID); +typedef BOOL(WINAPI * MINIDUMP_WRITE_DUMP)( + IN HANDLE hProcess, + IN DWORD ProcessId, + IN HANDLE hFile, + IN MINIDUMP_TYPE DumpType, + IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL + IN PVOID UserStreamParam, OPTIONAL + IN PVOID CallbackParam OPTIONAL + ); //************************************************************************************* -void WINAPI Create_Dump(PEXCEPTION_POINTERS pException) +long WINAPI Create_Dump_Immediate(LPEXCEPTION_POINTERS pException) //************************************************************************************* // Create dump. // pException can be either GetExceptionInformation() or NULL. { // Try to get MiniDumpWriteDump() address. - hDbgHelp = LoadLibrary("DBGHELP.DLL"); - MiniDumpWriteDump_ = (MINIDUMP_WRITE_DUMP)GetProcAddress(hDbgHelp, "MiniDumpWriteDump"); + HMODULE hDbgHelp = LoadLibrary("DBGHELP.DLL"); + MINIDUMP_WRITE_DUMP MiniDumpWriteDump_ = (MINIDUMP_WRITE_DUMP)GetProcAddress(hDbgHelp, "MiniDumpWriteDump"); // If MiniDumpWriteDump() of DbgHelp.dll available. - if (MiniDumpWriteDump_) - { - //get absolute path of current process: C:/ ... /name.exe + if (MiniDumpWriteDump_) { + // Get absolute path of current process: C:/ ... /name.exe CHAR Dump_Path[MAX_PATH]; GetModuleFileName(NULL, Dump_Path, sizeof(Dump_Path)); std::string path(Dump_Path); - //Get current time in a string. + // Get current time in a string. std::time_t t = std::time(NULL); char tStr[16]; std::strftime(tStr, ARRAYSIZE(tStr), " %a %H-%M-%S", std::localtime(&t)); @@ -104,39 +51,51 @@ void WINAPI Create_Dump(PEXCEPTION_POINTERS pException) // Remove the .exe from path path = path.substr(0, path.length() - 4); // Add the current time and .dmp - path += time + ".dmp"; + path += "dump" + time + ".dmp"; + + DWORD procId = GetCurrentProcessId(); + DWORD threadId = GetCurrentThreadId(); MINIDUMP_EXCEPTION_INFORMATION M; - M.ThreadId = GetCurrentThreadId(); + M.ThreadId = threadId; M.ExceptionPointers = pException; M.ClientPointers = TRUE; HANDLE hDump_File = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - DWORD curProId = GetCurrentProcessId(); - //HANDLE curPro = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_DUP_HANDLE, FALSE, curProId); - HANDLE curPro = GetCurrentProcess(); + HANDLE process = GetCurrentProcess(); - BOOL result = MiniDumpWriteDump_(curPro, curProId, hDump_File, - MiniDumpNormal, (pException) ? &M : NULL, NULL, NULL); + BOOL result = MiniDumpWriteDump_(process, procId, hDump_File + , (MINIDUMP_TYPE)(MiniDumpWithDataSegs | + MiniDumpWithHandleData | + MiniDumpScanMemory | + MiniDumpWithUnloadedModules | + MiniDumpWithIndirectlyReferencedMemory | + MiniDumpWithPrivateReadWriteMemory | + MiniDumpWithFullMemoryInfo | + MiniDumpWithThreadInfo | + MiniDumpIgnoreInaccessibleMemory) + , &M, NULL, NULL); HRESULT error = (HRESULT)GetLastError(); CloseHandle(hDump_File); if (!result) { _com_error cErr(error); HRESULT actualErrorCode = error & 0xFFFF; - char eBuf[16]; - std::sprintf(eBuf, "0x%x", actualErrorCode); + char hexErrBuf[16]; + std::sprintf(hexErrBuf, "0x%x", actualErrorCode); std::cout << "Bad memory dump at: \"" << path.c_str() << "\"" << std::endl - << "because MiniDumpWriteDump failed with error #" << actualErrorCode << " (" << eBuf << "): \"" << cErr.ErrorMessage() << "\"" << std::endl; + << "because MiniDumpWriteDump failed with error #" << actualErrorCode << " (" << hexErrBuf << "): \"" << cErr.ErrorMessage() << "\"" << std::endl; MessageBox(NULL, "Application crashed, memory dump failed, but file was created.", "MiniDump", MB_ICONHAND | MB_OK); } else { - std::cout << "Memory dumped to: \"" << path.c_str() << "\""; + std::cout << "Memory dumped to: \"" << path.c_str() << "\"" << std::endl; MessageBox(NULL, ("Application crashed, memory dumped to: " + path).c_str(), "MiniDump", MB_ICONHAND | MB_OK); } } else { - std::cout << "Memory dump failed because MiniDumpWriteDump is not available."; + std::cout << "Memory dump failed because MiniDumpWriteDump is not available." << std::endl; MessageBox(NULL, "Application crashed, could not create a memory dump.", "MiniDump", MB_ICONHAND | MB_OK); } + + // Basically, terminate the application. + return EXCEPTION_EXECUTE_HANDLER; } diff --git a/src/Game/main.cpp b/src/Game/main.cpp index aa76cc07..b94f0b97 100644 --- a/src/Game/main.cpp +++ b/src/Game/main.cpp @@ -7,104 +7,10 @@ int main(int argc, char* argv[]) Game game(argc, argv); while (game.Running()) { - PerformanceTimer::StartTimer("Game-Tick"); + PerformanceTimer::StartTimer("Game-Tick"); game.Tick(); - PerformanceTimer::StopTimer("Game-Tick"); + PerformanceTimer::StopTimer("Game-Tick"); } return 0; } - -/* -Inspired by Original Author: Vladimir Sedach. - -Purpose: demo of Call Stack creation by our own means, -and with MiniDumpWriteDump() function of DbgHelp.dll. -*/ - -#pragma optimize("y", off) //generate stack frame pointers for all functions - same as /Oy- in the project -#pragma warning(disable: 4200) //nonstandard extension used : zero-sized array in struct/union -#pragma warning(disable: 4100) //unreferenced formal parameter - -typedef BOOL(WINAPI * MINIDUMP_WRITE_DUMP)( - IN HANDLE hProcess, - IN DWORD ProcessId, - IN HANDLE hFile, - IN MINIDUMP_TYPE DumpType, - IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL - IN PVOID UserStreamParam, OPTIONAL - IN PVOID CallbackParam OPTIONAL - ); - - - -//************************************************************************************* -long WINAPI Create_Dump_Immediate(LPEXCEPTION_POINTERS pException) -//************************************************************************************* -// Create dump. -// pException can be either GetExceptionInformation() or NULL. -{ - // Try to get MiniDumpWriteDump() address. - HMODULE hDbgHelp = LoadLibrary("DBGHELP.DLL"); - MINIDUMP_WRITE_DUMP MiniDumpWriteDump_ = (MINIDUMP_WRITE_DUMP)GetProcAddress(hDbgHelp, "MiniDumpWriteDump"); - - // If MiniDumpWriteDump() of DbgHelp.dll available. - if (MiniDumpWriteDump_) { - // Get absolute path of current process: C:/ ... /name.exe - CHAR Dump_Path[MAX_PATH]; - GetModuleFileName(NULL, Dump_Path, sizeof(Dump_Path)); - std::string path(Dump_Path); - - // Get current time in a string. - std::time_t t = std::time(NULL); - char tStr[16]; - std::strftime(tStr, ARRAYSIZE(tStr), " %a %H-%M-%S", std::localtime(&t)); - std::string time(tStr); - // Remove the .exe from path - path = path.substr(0, path.length() - 4); - // Add the current time and .dmp - path += "dump" + time + ".dmp"; - - DWORD procId = GetCurrentProcessId(); - DWORD threadId = GetCurrentThreadId(); - - MINIDUMP_EXCEPTION_INFORMATION M; - M.ThreadId = threadId; - M.ExceptionPointers = pException; - M.ClientPointers = TRUE; - - HANDLE hDump_File = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - HANDLE process = GetCurrentProcess(); - - BOOL result = MiniDumpWriteDump_(process, procId, hDump_File, - (MINIDUMP_TYPE)(MiniDumpWithDataSegs | - MiniDumpWithHandleData | - MiniDumpScanMemory | - MiniDumpWithUnloadedModules | - MiniDumpWithIndirectlyReferencedMemory | - MiniDumpWithPrivateReadWriteMemory | - MiniDumpWithFullMemoryInfo | - MiniDumpWithThreadInfo | - MiniDumpIgnoreInaccessibleMemory) - , &M, NULL, NULL); - HRESULT error = (HRESULT)GetLastError(); - - CloseHandle(hDump_File); - if (!result) { - _com_error cErr(error); - HRESULT actualErrorCode = error & 0xFFFF; - char hexErrBuf[16]; - std::sprintf(hexErrBuf, "0x%x", actualErrorCode); - std::cout << "Bad memory dump at: \"" << path.c_str() << "\"" << std::endl - << "because MiniDumpWriteDump failed with error #" << actualErrorCode << " (" << hexErrBuf << "): \"" << cErr.ErrorMessage() << "\"" << std::endl; - MessageBox(NULL, "Application crashed, memory dump failed, but file was created.", "MiniDump", MB_ICONHAND | MB_OK); - } else { - std::cout << "Memory dumped to: \"" << path.c_str() << "\"" << std::endl; - MessageBox(NULL, ("Application crashed, memory dumped to: " + path).c_str(), "MiniDump", MB_ICONHAND | MB_OK); - } - } else { - std::cout << "Memory dump failed because MiniDumpWriteDump is not available." << std::endl; - MessageBox(NULL, "Application crashed, could not create a memory dump.", "MiniDump", MB_ICONHAND | MB_OK); - } - return 0; -}