]> git.sesse.net Git - casparcg/blob - common/os/windows/win32_exception.cpp
Removed unused library
[casparcg] / common / os / windows / win32_exception.cpp
1 #include "../../stdafx.h"
2
3 #include "win32_exception.h"
4
5 #include <boost/thread.hpp>
6
7 #include "os/windows/windows.h"
8
9 namespace caspar { namespace detail {
10
11 typedef struct tagTHREADNAME_INFO
12 {
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
17 } THREADNAME_INFO;
18
19 inline void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)
20 {
21         THREADNAME_INFO info;
22         {
23                 info.dwType = 0x1000;
24                 info.szName = szThreadName;
25                 info.dwThreadID = dwThreadID;
26                 info.dwFlags = 0;
27         }
28         __try
29         {
30                 RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
31         }
32         __except (EXCEPTION_CONTINUE_EXECUTION){}       
33 }
34
35 } // namespace detail
36
37 bool& installed_for_thread()
38 {
39         static boost::thread_specific_ptr<bool> installed;
40
41         auto for_thread = installed.get();
42         
43         if (!for_thread)
44         {
45                 for_thread = new bool(false);
46                 installed.reset(for_thread);
47         }
48
49         return *for_thread;
50 }
51
52 void install_gpf_handler()
53 {
54 //#ifndef _DEBUG
55         _set_se_translator(win32_exception::Handler);
56         installed_for_thread() = true;
57 //#endif
58 }
59
60 void ensure_gpf_handler_installed_for_thread(
61                 const char* thread_description)
62 {
63         if (!installed_for_thread())
64         {
65                 install_gpf_handler();
66
67                 if (thread_description)
68                         detail::SetThreadName(GetCurrentThreadId(), thread_description);
69         }
70 }
71
72 void win32_exception::Handler(unsigned int errorCode, EXCEPTION_POINTERS* pInfo) {
73         switch(errorCode)
74         {
75         case EXCEPTION_ACCESS_VIOLATION:
76                 throw win32_access_violation(*(pInfo->ExceptionRecord));
77                 break;
78
79         default:
80                 throw win32_exception(*(pInfo->ExceptionRecord));
81         }
82 }
83
84 win32_exception::win32_exception(const EXCEPTION_RECORD& info) : message_("Win32 exception"), location_(info.ExceptionAddress), errorCode_(info.ExceptionCode)
85 {
86         switch(info.ExceptionCode)
87         {
88         case EXCEPTION_ACCESS_VIOLATION:
89                 message_ = "Access violation";
90                 break;
91         case EXCEPTION_FLT_DIVIDE_BY_ZERO:
92         case EXCEPTION_INT_DIVIDE_BY_ZERO:
93                 message_ = "Divide by zero";
94                 break;
95         }
96 }
97
98 win32_access_violation::win32_access_violation(const EXCEPTION_RECORD& info) : win32_exception(info), isWrite_(false), badAddress_(0) 
99 {
100         isWrite_ = info.ExceptionInformation[0] == 1;
101         badAddress_ = reinterpret_cast<win32_exception::address>(info.ExceptionInformation[1]);
102 }
103
104 const char* win32_access_violation::what() const
105 {
106         sprintf_s<>(messageBuffer_, "Access violation at %p, trying to %s %p", location(), isWrite_?"write":"read", badAddress_);
107
108         return messageBuffer_;
109 }
110
111 }