diff options
Diffstat (limited to 'zen/debug_minidump.cpp')
-rw-r--r-- | zen/debug_minidump.cpp | 143 |
1 files changed, 0 insertions, 143 deletions
diff --git a/zen/debug_minidump.cpp b/zen/debug_minidump.cpp deleted file mode 100644 index 29500ae4..00000000 --- a/zen/debug_minidump.cpp +++ /dev/null @@ -1,143 +0,0 @@ -// ************************************************************************** -// * This file is part of the FreeFileSync project. It is distributed under * -// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * -// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * -// ************************************************************************** - -#include "debug_minidump.h" -#include <string> -#include <sstream> -#include <cassert> -#include <cstdlib> //malloc(), free() -#include <zen/file_error.h> -#include <zen/scope_guard.h> -#include <zen/time.h> -#include "win.h" //includes "windows.h" -#include "DbgHelp.h" //available for MSC only -#pragma comment(lib, "Dbghelp.lib") - -using namespace zen; - - -namespace -{ -LONG WINAPI writeDumpOnException(EXCEPTION_POINTERS* pExceptionInfo) //blocks showing message boxes on success and error! -{ - assert(false); - - const Zstring filename = L"CrashDump " + formatTime<Zstring>(L"%Y-%m-%d %H%M%S") + L".dmp"; - - { - HANDLE hFile = ::CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr); - if (hFile == INVALID_HANDLE_VALUE) - { - ::MessageBox(nullptr, (replaceCpy<std::wstring>(L"Cannot write file %x.", L"%x", fmtFileName(filename)) + L"\n\n" + formatSystemError(L"CreateFile", ::GetLastError())).c_str(), L"Application Crash", MB_SERVICE_NOTIFICATION | MB_ICONERROR); - std::terminate(); - } - ZEN_ON_SCOPE_EXIT(::CloseHandle(hFile)); - - MINIDUMP_EXCEPTION_INFORMATION exInfo = {}; - exInfo.ThreadId = ::GetCurrentThreadId(); - exInfo.ExceptionPointers = pExceptionInfo; - exInfo.ClientPointers = FALSE; - - MINIDUMP_EXCEPTION_INFORMATION* exceptParam = pExceptionInfo ? &exInfo : nullptr; - - if (!::MiniDumpWriteDump(::GetCurrentProcess (), //__in HANDLE hProcess, - ::GetCurrentProcessId(), //__in DWORD ProcessId, - hFile, //__in HANDLE hFile, - MiniDumpWithDataSegs, //__in MINIDUMP_TYPE DumpType, ->Standard: MiniDumpNormal, Medium: MiniDumpWithDataSegs, Full: MiniDumpWithFullMemory - exceptParam, //__in PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, - nullptr, //__in PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, - nullptr)) //__in PMINIDUMP_CALLBACK_INFORMATION CallbackParam - { - ::MessageBox(nullptr, (replaceCpy<std::wstring>(L"Cannot write file %x.", L"%x", fmtFileName(filename)) + L"\n\n" + formatSystemError(L"MiniDumpWriteDump", ::GetLastError())).c_str(), L"Application Crash", MB_SERVICE_NOTIFICATION | MB_ICONERROR); - std::terminate(); - } - } //close file before showing success message - - //attention: the app has not yet officially crashed! => use MB_SERVICE_NOTIFICATION to avoid Win32 GUI callbacks while message box is shown! - ::MessageBox(nullptr, replaceCpy<std::wstring>(L"Crash dump file %x written!", L"%x", fmtFileName(filename)).c_str(), L"Application Crash", MB_SERVICE_NOTIFICATION | MB_ICONERROR); - std::terminate(); - - return EXCEPTION_EXECUTE_HANDLER; -} - -//ensure that a dump-file is written for uncaught exceptions -struct OnStartup { - OnStartup() - { - /*LPTOP_LEVEL_EXCEPTION_FILTER oldFilter = */ ::SetUnhandledExceptionFilter(writeDumpOnException); - //oldFilter == &__CxxUnhandledExceptionFilter() by default! - }} dummy; -} - - -void debug_tools::writeMinidump() -{ - //force exception to catch the state of this thread and hopefully get a valid call stack - __try - { - ::RaiseException(EXCEPTION_BREAKPOINT, 0, 0, nullptr); - } - __except (writeDumpOnException(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) {} - //don't use EXCEPTION_CONTINUE_EXECUTION: although used in most minidump examples this resulted in an infinite loop in tests - //although it really should not: http://msdn.microsoft.com/en-us/library/c34eyfac.aspx -} - - -/* -No need to include the "operator new" declarations into every compilation unit: - -[basic.stc.dynamic] -"A C++ program shall provide at most one definition of a replaceable allocation or deallocation function. -Any such function definition replaces the default version provided in the library (17.6.4.6). -The following allocation and deallocation functions (18.6) are implicitly declared in global scope in each translation unit of a program. -void* operator new(std::size_t); -void* operator new[](std::size_t); -void operator delete(void*); -void operator delete[](void*);" -*/ - -namespace -{ -class BadAllocDetailed : public std::bad_alloc -{ -public: - explicit BadAllocDetailed(size_t allocSize) - { - errorMsg = "Memory allocation failed: "; - errorMsg += numberToString(allocSize); - } - - virtual const char* what() const throw() - { - return errorMsg.c_str(); - } - -private: - template <class T> - static std::string numberToString(const T& number) //convert number to string the (slow) C++ way - { - std::ostringstream ss; - ss << number; - return ss.str(); - } - - std::string errorMsg; -}; -} - -void* operator new(size_t size) -{ - if (void* ptr = ::malloc(size)) - return ptr; - - debug_tools::writeMinidump(); - throw ::BadAllocDetailed(size); -} - -void operator delete(void* ptr) { ::free(ptr); } - -void* operator new[](size_t size) { return operator new(size); } -void operator delete[](void* ptr) { operator delete(ptr); } |