bux API Reference 1.9.0
Static library of whatever are seen required in general purpose but not directly supported from Modern C++. Or whatever reusable originated from my side projects.
Loading...
Searching...
No Matches
XException.cpp
Go to the documentation of this file.
1#include "XException.h"
2#ifdef _WIN32
3#include "AtomiX.h" // buc::C_SpinLock
4#include <stdlib.h> // atexit()
5#include <windows.h>
6#endif
7
8namespace {
9
10#ifdef _WIN32
11/*
12 Use TLS API instead of __declspec(thread) because the latter doesn't work within dll.
13*/
14enum
15{
16 CATCH_SE_CALLED = 1,
17 USE_OLD_USER_SE_FIRST = 2
18};
19
20DWORD TLSInd_FlagsSE = TLS_OUT_OF_INDEXES;
21DWORD TLSInd_UserSE = TLS_OUT_OF_INDEXES;
22
23#if defined(__BORLANDC__)
24void _USERENTRY TLSInd_Free()
25#elif defined(_MSC_VER)
26void __cdecl TLSInd_Free()
27#else
28void TLSInd_Free()
29#endif
30{
31 TlsFree(TLSInd_FlagsSE);
32 TlsFree(TLSInd_UserSE);
33 TLSInd_FlagsSE = TLS_OUT_OF_INDEXES;
34 TLSInd_UserSE = TLS_OUT_OF_INDEXES;
35}
36
37LONG WINAPI usrSEH(_EXCEPTION_POINTERS *pInfo)
38{
39 LONG ret = EXCEPTION_CONTINUE_SEARCH;
40 if (size_t(TlsGetValue(TLSInd_FlagsSE)) &USE_OLD_USER_SE_FIRST)
41 {
42 if (auto oldHook = LPTOP_LEVEL_EXCEPTION_FILTER(TlsGetValue(TLSInd_UserSE)))
43 ret =oldHook(pInfo);
44 }
45
46 if (EXCEPTION_CONTINUE_SEARCH == ret)
47 {
48 if (const auto er =pInfo->ExceptionRecord)
49 RUNTIME_ERROR("code 0x{:x}, flags 0x{:x}, extra {}, ip {}, arg#{:x}",
50 er->ExceptionCode,
51 er->ExceptionFlags,
52 static_cast<void*>(er->ExceptionRecord),
53 static_cast<void*>(er->ExceptionAddress),
54 er->NumberParameters);
55 }
56 return EXCEPTION_CONTINUE_SEARCH;
57}
58#endif
59
60} // namespace
61
62namespace bux {
63
64//
65// Functions
66//
67#ifdef _WIN32
68void catchSE(bool useOldHookFirst)
76{
77 if (TLS_OUT_OF_INDEXES == TLSInd_FlagsSE)
78 {
79 static std::atomic_flag lock = ATOMIC_FLAG_INIT;
80 C_SpinLock _(lock);
81 if (TLS_OUT_OF_INDEXES == TLSInd_FlagsSE)
82 {
83 TLSInd_UserSE = TlsAlloc();
84 TLSInd_FlagsSE = TlsAlloc();
85 atexit(TLSInd_Free);
86 }
87 }
88
89 if (!TlsGetValue(TLSInd_FlagsSE))
90 {
91 TlsSetValue(TLSInd_UserSE, LPVOID(SetUnhandledExceptionFilter(usrSEH)));
92 size_t flags = CATCH_SE_CALLED;
93 if (useOldHookFirst)
94 flags |= USE_OLD_USER_SE_FIRST;
95
96 TlsSetValue(TLSInd_FlagsSE, LPVOID(flags));
97 }
98}
99#endif
100
101} // namespace bux
#define RUNTIME_ERROR(fmtStr,...)
Wrap FILE(DATE)#__LINE__ FUNCTION: msg into std::runtime_error.
Definition XException.h:32
THE common namespace of bux library.
Definition AtomiX.cpp:3