1 #include "../../stdafx.h"
3 #include "win32_exception.h"
5 #include <boost/thread.hpp>
9 namespace caspar { namespace detail {
11 typedef struct tagTHREADNAME_INFO
13 DWORD dwType; // must be 0x1000
14 LPCSTR szName; // pointer to name (in user addr space)
15 DWORD dwThreadID; // thread ID (-1=caller thread)
16 DWORD dwFlags; // reserved for future use, must be zero
19 inline void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)
24 info.szName = szThreadName;
25 info.dwThreadID = dwThreadID;
30 RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
32 __except (EXCEPTION_CONTINUE_EXECUTION){}
37 bool& installed_for_thread()
39 static boost::thread_specific_ptr<bool> installed;
41 auto for_thread = installed.get();
45 for_thread = new bool(false);
46 installed.reset(for_thread);
52 void install_gpf_handler()
55 _set_se_translator(win32_exception::Handler);
56 installed_for_thread() = true;
60 void ensure_gpf_handler_installed_for_thread(
61 const char* thread_description)
63 if (!installed_for_thread())
65 install_gpf_handler();
67 if (thread_description)
68 detail::SetThreadName(GetCurrentThreadId(), thread_description);
72 void win32_exception::Handler(unsigned int errorCode, EXCEPTION_POINTERS* pInfo) {
75 case EXCEPTION_ACCESS_VIOLATION:
76 throw win32_access_violation(*(pInfo->ExceptionRecord));
80 throw win32_exception(*(pInfo->ExceptionRecord));
84 win32_exception::win32_exception(const EXCEPTION_RECORD& info) : message_("Win32 exception"), location_(info.ExceptionAddress), errorCode_(info.ExceptionCode)
86 switch(info.ExceptionCode)
88 case EXCEPTION_ACCESS_VIOLATION:
89 message_ = "Access violation";
91 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
92 case EXCEPTION_INT_DIVIDE_BY_ZERO:
93 message_ = "Divide by zero";
98 win32_access_violation::win32_access_violation(const EXCEPTION_RECORD& info) : win32_exception(info), isWrite_(false), badAddress_(0)
100 isWrite_ = info.ExceptionInformation[0] == 1;
101 badAddress_ = reinterpret_cast<win32_exception::address>(info.ExceptionInformation[1]);
104 const char* win32_access_violation::what() const
106 sprintf_s<>(messageBuffer_, "Access violation at %p, trying to %s %p", location(), isWrite_?"write":"read", badAddress_);
108 return messageBuffer_;