From 5c72c78a716bcf112a92af3fff085ab1eedfb9dc Mon Sep 17 00:00:00 2001 From: WiSo Date: Mon, 13 Aug 2012 18:48:08 +0200 Subject: [PATCH 1/3] [WIN32] added new EXCEPTION_POINTERS member in exception handling. --- xbmc/threads/platform/win/Win32Exception.cpp | 68 ++++++++++---------- xbmc/threads/platform/win/Win32Exception.h | 5 +- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/xbmc/threads/platform/win/Win32Exception.cpp b/xbmc/threads/platform/win/Win32Exception.cpp index 7f80cba710ba6..b8d74a7fd3467 100644 --- a/xbmc/threads/platform/win/Win32Exception.cpp +++ b/xbmc/threads/platform/win/Win32Exception.cpp @@ -26,34 +26,36 @@ void win32_exception::install_handler() { - _set_se_translator(win32_exception::translate); + _set_se_translator(win32_exception::translate); } void win32_exception::translate(unsigned code, EXCEPTION_POINTERS* info) { - // Windows guarantees that *(info->ExceptionRecord) is valid - switch (code) { + switch (code) + { case EXCEPTION_ACCESS_VIOLATION: - throw access_violation(*(info->ExceptionRecord)); - break; + throw access_violation(info); + break; default: - throw win32_exception(*(info->ExceptionRecord)); - } + throw win32_exception(info); + } } -win32_exception::win32_exception(const EXCEPTION_RECORD& info, const char* classname) : +win32_exception::win32_exception(EXCEPTION_POINTERS* info, const char* classname) : XbmcCommons::Exception(classname ? classname : "win32_exception"), -mWhat("Win32 exception"), mWhere(info.ExceptionAddress), mCode(info.ExceptionCode) + mWhat("Win32 exception"), mWhere(info->ExceptionRecord->ExceptionAddress), mCode(info->ExceptionRecord->ExceptionCode), mExceptionPointers(info) { - switch (info.ExceptionCode) { - case EXCEPTION_ACCESS_VIOLATION: - mWhat = "Access violation"; - break; - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - case EXCEPTION_INT_DIVIDE_BY_ZERO: - mWhat = "Division by zero"; - break; - } + // Windows guarantees that *(info->ExceptionRecord) is valid + switch (info->ExceptionRecord->ExceptionCode) + { + case EXCEPTION_ACCESS_VIOLATION: + mWhat = "Access violation"; + break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_INT_DIVIDE_BY_ZERO: + mWhat = "Division by zero"; + break; + } } void win32_exception::LogThrowMessage(const char *prefix) const @@ -64,22 +66,22 @@ void win32_exception::LogThrowMessage(const char *prefix) const LOG(LOGERROR, "%s (code:0x%08x) at 0x%08x", what(), code(), where()); } -access_violation::access_violation(const EXCEPTION_RECORD& info) -: win32_exception(info,"access_voilation"), mAccessType(Invalid), mBadAddress(0) +access_violation::access_violation(EXCEPTION_POINTERS* info) : + win32_exception(info,"access_voilation"), mAccessType(Invalid), mBadAddress(0) { - switch(info.ExceptionInformation[0]) - { - case 0: - mAccessType = Read; - break; - case 1: - mAccessType = Write; - break; - case 8: - mAccessType = DEP; - break; - } - mBadAddress = reinterpret_cast(info.ExceptionInformation[1]); + switch(info->ExceptionRecord->ExceptionInformation[0]) + { + case 0: + mAccessType = Read; + break; + case 1: + mAccessType = Write; + break; + case 8: + mAccessType = DEP; + break; + } + mBadAddress = reinterpret_cast(info->ExceptionRecord->ExceptionInformation[1]); } void access_violation::LogThrowMessage(const char *prefix) const diff --git a/xbmc/threads/platform/win/Win32Exception.h b/xbmc/threads/platform/win/Win32Exception.h index 9b957513e9d11..29901102c4cbd 100644 --- a/xbmc/threads/platform/win/Win32Exception.h +++ b/xbmc/threads/platform/win/Win32Exception.h @@ -36,12 +36,13 @@ class win32_exception: public XbmcCommons::Exception unsigned code() const { return mCode; }; virtual void LogThrowMessage(const char *prefix) const; protected: - win32_exception(const EXCEPTION_RECORD& info, const char* classname = NULL); + win32_exception(EXCEPTION_POINTERS*, const char* classname = NULL); static void translate(unsigned code, EXCEPTION_POINTERS* info); private: const char* mWhat; Address mWhere; unsigned mCode; + EXCEPTION_POINTERS *mExceptionPointers; }; class access_violation: public win32_exception @@ -62,5 +63,5 @@ class access_violation: public win32_exception private: access_type mAccessType; Address mBadAddress; - access_violation(const EXCEPTION_RECORD& info); + access_violation(EXCEPTION_POINTERS* info); }; From 240b0ef033225a1d31bec6bf39be46e5973184ee Mon Sep 17 00:00:00 2001 From: WiSo Date: Mon, 13 Aug 2012 19:07:39 +0200 Subject: [PATCH 2/3] [WIN32] move minidump writing function to Win32Exception --- xbmc/threads/platform/win/Win32Exception.cpp | 78 ++++++++++++++++++++ xbmc/threads/platform/win/Win32Exception.h | 3 + xbmc/win32/XBMC_PC.cpp | 68 +---------------- 3 files changed, 85 insertions(+), 64 deletions(-) diff --git a/xbmc/threads/platform/win/Win32Exception.cpp b/xbmc/threads/platform/win/Win32Exception.cpp index b8d74a7fd3467..d8e77552e5b69 100644 --- a/xbmc/threads/platform/win/Win32Exception.cpp +++ b/xbmc/threads/platform/win/Win32Exception.cpp @@ -21,9 +21,19 @@ #include "Win32Exception.h" #include +#include +#include "Util.h" +#include "WIN32Util.h" #define LOG if(logger) logger->Log +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); + +std::string win32_exception::mVersion; + void win32_exception::install_handler() { _set_se_translator(win32_exception::translate); @@ -66,6 +76,74 @@ void win32_exception::LogThrowMessage(const char *prefix) const LOG(LOGERROR, "%s (code:0x%08x) at 0x%08x", what(), code(), where()); } +bool win32_exception::write_minidump(EXCEPTION_POINTERS* pEp) +{ + // Create the dump file where the xbmc.exe resides + CStdString errorMsg; + bool returncode = false; + CStdString dumpFileName; + SYSTEMTIME stLocalTime; + GetLocalTime(&stLocalTime); + + dumpFileName.Format("xbmc_crashlog-%s-%04d%02d%02d-%02d%02d%02d.dmp", + mVersion.c_str(), + stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, + stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond); + + dumpFileName.Format("%s\\%s", CWIN32Util::GetProfilePath().c_str(), CUtil::MakeLegalFileName(dumpFileName)); + + HANDLE hDumpFile = CreateFile(dumpFileName.c_str(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); + + if (hDumpFile == INVALID_HANDLE_VALUE) + { + LOG(LOGERROR, "CreateFile '%s' failed with error id %d", dumpFileName.c_str(), GetLastError()); + goto cleanup; + } + + // Load the DBGHELP DLL + HMODULE hDbgHelpDll = ::LoadLibrary("DBGHELP.DLL"); + if (!hDbgHelpDll) + { + LOG(LOGERROR, "LoadLibrary 'DBGHELP.DLL' failed with error id %d", GetLastError()); + goto cleanup; + } + + MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(hDbgHelpDll, "MiniDumpWriteDump"); + if (!pDump) + { + LOG(LOGERROR, "Failed to locate MiniDumpWriteDump with error id %d", GetLastError()); + goto cleanup; + } + + // Initialize minidump structure + MINIDUMP_EXCEPTION_INFORMATION mdei; + mdei.ThreadId = GetCurrentThreadId(); + mdei.ExceptionPointers = pEp; + mdei.ClientPointers = FALSE; + + // Call the minidump api with normal dumping + // We can get more detail information by using other minidump types but the dump file will be + // extremely large. + BOOL bMiniDumpSuccessful = pDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &mdei, 0, NULL); + if( !bMiniDumpSuccessful ) + { + LOG(LOGERROR, "MiniDumpWriteDump failed with error id %d", GetLastError()); + goto cleanup; + } + + returncode = true; + +cleanup: + + if (hDumpFile != INVALID_HANDLE_VALUE) + CloseHandle(hDumpFile); + + if (hDbgHelpDll) + FreeLibrary(hDbgHelpDll); + + return returncode; +} + access_violation::access_violation(EXCEPTION_POINTERS* info) : win32_exception(info,"access_voilation"), mAccessType(Invalid), mBadAddress(0) { diff --git a/xbmc/threads/platform/win/Win32Exception.h b/xbmc/threads/platform/win/Win32Exception.h index 29901102c4cbd..cc5e7de1456f5 100644 --- a/xbmc/threads/platform/win/Win32Exception.h +++ b/xbmc/threads/platform/win/Win32Exception.h @@ -31,10 +31,12 @@ class win32_exception: public XbmcCommons::Exception typedef const void* Address; // OK on Win32 platform static void install_handler(); + static void set_version(std::string version) { mVersion = version; }; virtual const char* what() const { return mWhat; }; Address where() const { return mWhere; }; unsigned code() const { return mCode; }; virtual void LogThrowMessage(const char *prefix) const; + static bool write_minidump(EXCEPTION_POINTERS* pEp); protected: win32_exception(EXCEPTION_POINTERS*, const char* classname = NULL); static void translate(unsigned code, EXCEPTION_POINTERS* info); @@ -43,6 +45,7 @@ class win32_exception: public XbmcCommons::Exception Address mWhere; unsigned mCode; EXCEPTION_POINTERS *mExceptionPointers; + static std::string mVersion; }; class access_violation: public win32_exception diff --git a/xbmc/win32/XBMC_PC.cpp b/xbmc/win32/XBMC_PC.cpp index 2cf9f4b72a97d..6d6c3e321c802 100644 --- a/xbmc/win32/XBMC_PC.cpp +++ b/xbmc/win32/XBMC_PC.cpp @@ -23,80 +23,19 @@ #include "settings/AppParamParser.h" #include "utils/CharsetConverter.h" #include "utils/log.h" -#include "WIN32Util.h" +#include "threads/platform/win/Win32Exception.h" #include "shellapi.h" #include "dbghelp.h" #include "XBDateTime.h" #include "threads/Thread.h" #include "Application.h" #include "XbmcContext.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); - +#include "GUIInfoManager.h" // Minidump creation function LONG WINAPI CreateMiniDump( EXCEPTION_POINTERS* pEp ) { - // Create the dump file where the xbmc.exe resides - CStdString errorMsg; - CStdString dumpFile; - CDateTime now(CDateTime::GetCurrentDateTime()); - dumpFile.Format("%s\\xbmc_crashlog-%s-%04i%02i%02i-%02i%02i%02i.dmp", CWIN32Util::GetProfilePath().c_str(), GIT_REV, now.GetYear(), now.GetMonth(), now.GetDay(), now.GetHour(), now.GetMinute(), now.GetSecond()); - HANDLE hFile = CreateFile(dumpFile.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); - - // Call MiniDumpWriteDump api with the dump file - if ( hFile && ( hFile != INVALID_HANDLE_VALUE ) ) - { - // Load the DBGHELP DLL - HMODULE hDbgHelpDll = ::LoadLibrary("DBGHELP.DLL"); - if (hDbgHelpDll) - { - MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(hDbgHelpDll, "MiniDumpWriteDump"); - if (pDump) - { - // Initialize minidump structure - MINIDUMP_EXCEPTION_INFORMATION mdei; - mdei.ThreadId = CThread::GetCurrentThreadId(); - mdei.ExceptionPointers = pEp; - mdei.ClientPointers = FALSE; - - // Call the minidump api with normal dumping - // We can get more detail information by using other minidump types but the dump file will be - // extermely large. - BOOL rv = pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &mdei, 0, NULL); - if( !rv ) - { - errorMsg.Format("MiniDumpWriteDump failed with error id %d", GetLastError()); - MessageBox(NULL, errorMsg.c_str(), "XBMC: Error", MB_OK|MB_ICONERROR); - } - } - else - { - errorMsg.Format("MiniDumpWriteDump failed to load with error id %d", GetLastError()); - MessageBox(NULL, errorMsg.c_str(), "XBMC: Error", MB_OK|MB_ICONERROR); - } - - // Close the DLL - FreeLibrary(hDbgHelpDll); - } - else - { - errorMsg.Format("LoadLibrary 'DBGHELP.DLL' failed with error id %d", GetLastError()); - MessageBox(NULL, errorMsg.c_str(), "XBMC: Error", MB_OK|MB_ICONERROR); - } - - // Close the file - CloseHandle( hFile ); - } - else - { - errorMsg.Format("CreateFile '%s' failed with error id %d", dumpFile.c_str(), GetLastError()); - MessageBox(NULL, errorMsg.c_str(), "XBMC: Error", MB_OK|MB_ICONERROR); - } - + win32_exception::write_minidump(pEp); return pEp->ExceptionRecord->ExceptionCode;; } @@ -121,6 +60,7 @@ INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT ) CLog::SetLogLevel(g_advancedSettings.m_logLevel); // Initializes CreateMiniDump to handle exceptions. + win32_exception::set_version(g_infoManager.GetVersion()); SetUnhandledExceptionFilter( CreateMiniDump ); // check if XBMC is already running From f6f1884a35d6d7294c3d3172fbdd3f041fa29794 Mon Sep 17 00:00:00 2001 From: WiSo Date: Mon, 13 Aug 2012 19:49:50 +0200 Subject: [PATCH 3/3] Use the Exception abstractions to manage the handling of platform specific exceptions. --- xbmc/XBApplicationEx.cpp | 53 +++++++++++++++++--- xbmc/threads/Thread.cpp | 3 +- xbmc/threads/platform/win/ThreadImpl.cpp | 2 + xbmc/threads/platform/win/Win32Exception.cpp | 26 +++++----- xbmc/threads/platform/win/Win32Exception.h | 4 +- 5 files changed, 66 insertions(+), 22 deletions(-) diff --git a/xbmc/XBApplicationEx.cpp b/xbmc/XBApplicationEx.cpp index 0a73343a3e5da..2e830262f720c 100644 --- a/xbmc/XBApplicationEx.cpp +++ b/xbmc/XBApplicationEx.cpp @@ -27,6 +27,12 @@ #else #define MEASURE_FUNCTION #endif +#include "commons/Exception.h" + +// Put this here for easy enable and disable +#ifndef _DEBUG +#define XBMC_TRACK_EXCEPTIONS +#endif CXBApplicationEx::CXBApplicationEx() { @@ -77,7 +83,7 @@ INT CXBApplicationEx::Run(bool renderGUI) unsigned int frameTime = 0; const unsigned int noRenderFrameTime = 15; // Simulates ~66fps -#ifndef _DEBUG +#ifdef XBMC_TRACK_EXCEPTIONS BYTE processExceptionCount = 0; BYTE frameMoveExceptionCount = 0; BYTE renderExceptionCount = 0; @@ -93,17 +99,28 @@ INT CXBApplicationEx::Run(bool renderGUI) //----------------------------------------- // Animate and render a frame //----------------------------------------- -#ifndef _DEBUG +#ifdef XBMC_TRACK_EXCEPTIONS try { #endif lastFrameTime = XbmcThreads::SystemClockMillis(); Process(); //reset exception count -#ifndef _DEBUG +#ifdef XBMC_TRACK_EXCEPTIONS processExceptionCount = 0; } + catch (const XbmcCommons::UncheckedException &e) + { + e.LogThrowMessage("CApplication::Process()"); + processExceptionCount++; + //MAX_EXCEPTION_COUNT exceptions in a row? -> bail out + if (processExceptionCount > MAX_EXCEPTION_COUNT) + { + CLog::Log(LOGERROR, "CApplication::Process(), too many exceptions"); + throw; + } + } catch (...) { CLog::Log(LOGERROR, "exception in CApplication::Process()"); @@ -117,16 +134,27 @@ INT CXBApplicationEx::Run(bool renderGUI) } #endif // Frame move the scene -#ifndef _DEBUG +#ifdef XBMC_TRACK_EXCEPTIONS try { #endif if (!m_bStop) FrameMove(true, renderGUI); //reset exception count -#ifndef _DEBUG +#ifdef XBMC_TRACK_EXCEPTIONS frameMoveExceptionCount = 0; } + catch (const XbmcCommons::UncheckedException &e) + { + e.LogThrowMessage("CApplication::FrameMove()"); + frameMoveExceptionCount++; + //MAX_EXCEPTION_COUNT exceptions in a row? -> bail out + if (frameMoveExceptionCount > MAX_EXCEPTION_COUNT) + { + CLog::Log(LOGERROR, "CApplication::FrameMove(), too many exceptions"); + throw; + } + } catch (...) { CLog::Log(LOGERROR, "exception in CApplication::FrameMove()"); @@ -141,7 +169,7 @@ INT CXBApplicationEx::Run(bool renderGUI) #endif // Render the scene -#ifndef _DEBUG +#ifdef XBMC_TRACK_EXCEPTIONS try { #endif @@ -152,11 +180,22 @@ INT CXBApplicationEx::Run(bool renderGUI) if(frameTime < noRenderFrameTime) Sleep(noRenderFrameTime - frameTime); } -#ifndef _DEBUG +#ifdef XBMC_TRACK_EXCEPTIONS //reset exception count renderExceptionCount = 0; } + catch (const XbmcCommons::UncheckedException &e) + { + e.LogThrowMessage("CApplication::Render()"); + renderExceptionCount++; + //MAX_EXCEPTION_COUNT exceptions in a row? -> bail out + if (renderExceptionCount > MAX_EXCEPTION_COUNT) + { + CLog::Log(LOGERROR, "CApplication::Render(), too many exceptions"); + throw; + } + } catch (...) { CLog::Log(LOGERROR, "exception in CApplication::Render()"); diff --git a/xbmc/threads/Thread.cpp b/xbmc/threads/Thread.cpp index 9faac80e5fc11..91eb02389bd42 100644 --- a/xbmc/threads/Thread.cpp +++ b/xbmc/threads/Thread.cpp @@ -196,7 +196,6 @@ void CThread::Sleep(unsigned int milliseconds) void CThread::Action() { - try { OnStartup(); @@ -237,7 +236,7 @@ void CThread::Action() } catch (...) { - LOG(LOGERROR, "%s - thread %s, Unhandled exception caught in thread process, aborting. auto delete: %d", __FUNCTION__, m_ThreadName.c_str(), IsAutoDelete()); + LOG(LOGERROR, "%s - thread %s, Unhandled exception caught in thread OnExit, aborting. auto delete: %d", __FUNCTION__, m_ThreadName.c_str(), IsAutoDelete()); } } diff --git a/xbmc/threads/platform/win/ThreadImpl.cpp b/xbmc/threads/platform/win/ThreadImpl.cpp index 967bff97bc7de..df084900c3729 100644 --- a/xbmc/threads/platform/win/ThreadImpl.cpp +++ b/xbmc/threads/platform/win/ThreadImpl.cpp @@ -70,6 +70,8 @@ void CThread::SetThreadInfo() __except(EXCEPTION_EXECUTE_HANDLER) { } + + win32_exception::install_handler(); } ThreadIdentifier CThread::GetCurrentThreadId() diff --git a/xbmc/threads/platform/win/Win32Exception.cpp b/xbmc/threads/platform/win/Win32Exception.cpp index d8e77552e5b69..d9f3bc425c446 100644 --- a/xbmc/threads/platform/win/Win32Exception.cpp +++ b/xbmc/threads/platform/win/Win32Exception.cpp @@ -52,7 +52,7 @@ void win32_exception::translate(unsigned code, EXCEPTION_POINTERS* info) } win32_exception::win32_exception(EXCEPTION_POINTERS* info, const char* classname) : - XbmcCommons::Exception(classname ? classname : "win32_exception"), + XbmcCommons::UncheckedException(classname ? classname : "win32_exception"), mWhat("Win32 exception"), mWhere(info->ExceptionRecord->ExceptionAddress), mCode(info->ExceptionRecord->ExceptionCode), mExceptionPointers(info) { // Windows guarantees that *(info->ExceptionRecord) is valid @@ -71,15 +71,15 @@ win32_exception::win32_exception(EXCEPTION_POINTERS* info, const char* classname void win32_exception::LogThrowMessage(const char *prefix) const { if( prefix ) - LOG(LOGERROR, "%s : %s (code:0x%08x) at 0x%08x", prefix, (unsigned int) what(), code(), where()); + LOG(LOGERROR, "Unhandled exception in %s : %s (code:0x%08x) at 0x%08x", prefix, (unsigned int) what(), code(), where()); else - LOG(LOGERROR, "%s (code:0x%08x) at 0x%08x", what(), code(), where()); + LOG(LOGERROR, "Unhandled exception in %s (code:0x%08x) at 0x%08x", what(), code(), where()); + write_minidump(); } bool win32_exception::write_minidump(EXCEPTION_POINTERS* pEp) { // Create the dump file where the xbmc.exe resides - CStdString errorMsg; bool returncode = false; CStdString dumpFileName; SYSTEMTIME stLocalTime; @@ -166,20 +166,22 @@ void access_violation::LogThrowMessage(const char *prefix) const { if( prefix ) if( mAccessType == Write) - LOG(LOGERROR, "%s : %s at 0x%08x: Writing location 0x%08x", prefix, what(), where(), address()); + LOG(LOGERROR, "Unhandled exception in %s : %s at 0x%08x: Writing location 0x%08x", prefix, what(), where(), address()); else if( mAccessType == Read) - LOG(LOGERROR, "%s : %s at 0x%08x: Reading location 0x%08x", prefix, what(), where(), address()); + LOG(LOGERROR, "Unhandled exception in %s : %s at 0x%08x: Reading location 0x%08x", prefix, what(), where(), address()); else if( mAccessType == DEP) - LOG(LOGERROR, "%s : %s at 0x%08x: DEP violation, location 0x%08x", prefix, what(), where(), address()); + LOG(LOGERROR, "Unhandled exception in %s : %s at 0x%08x: DEP violation, location 0x%08x", prefix, what(), where(), address()); else - LOG(LOGERROR, "%s : %s at 0x%08x: unknown access type, location 0x%08x", prefix, what(), where(), address()); + LOG(LOGERROR, "Unhandled exception in %s : %s at 0x%08x: unknown access type, location 0x%08x", prefix, what(), where(), address()); else if( mAccessType == Write) - LOG(LOGERROR, "%s at 0x%08x: Writing location 0x%08x", what(), where(), address()); + LOG(LOGERROR, "Unhandled exception in %s at 0x%08x: Writing location 0x%08x", what(), where(), address()); else if( mAccessType == Read) - LOG(LOGERROR, "%s at 0x%08x: Reading location 0x%08x", what(), where(), address()); + LOG(LOGERROR, "Unhandled exception in %s at 0x%08x: Reading location 0x%08x", what(), where(), address()); else if( mAccessType == DEP) - LOG(LOGERROR, "%s at 0x%08x: DEP violation, location 0x%08x", what(), where(), address()); + LOG(LOGERROR, "Unhandled exception in %s at 0x%08x: DEP violation, location 0x%08x", what(), where(), address()); else - LOG(LOGERROR, "%s at 0x%08x: unknown access type, location 0x%08x", what(), where(), address()); + LOG(LOGERROR, "Unhandled exception in %s at 0x%08x: unknown access type, location 0x%08x", what(), where(), address()); + + write_minidump(); } diff --git a/xbmc/threads/platform/win/Win32Exception.h b/xbmc/threads/platform/win/Win32Exception.h index cc5e7de1456f5..53506d48f4959 100644 --- a/xbmc/threads/platform/win/Win32Exception.h +++ b/xbmc/threads/platform/win/Win32Exception.h @@ -25,7 +25,7 @@ #include #include "commons/Exception.h" -class win32_exception: public XbmcCommons::Exception +class win32_exception: public XbmcCommons::UncheckedException { public: typedef const void* Address; // OK on Win32 platform @@ -40,6 +40,8 @@ class win32_exception: public XbmcCommons::Exception protected: win32_exception(EXCEPTION_POINTERS*, const char* classname = NULL); static void translate(unsigned code, EXCEPTION_POINTERS* info); + + inline bool write_minidump() const { return write_minidump(mExceptionPointers); }; private: const char* mWhat; Address mWhere;