CppCommon 1.0.5.0
C++ Common Library
Loading...
Searching...
No Matches
stack_trace_manager.cpp
Go to the documentation of this file.
1
10
12
13#if defined(_WIN32) || defined(_WIN64)
14#include <windows.h>
15#if defined(DBGHELP_SUPPORT)
16#if defined(_MSC_VER)
17#pragma warning(push)
18#pragma warning(disable:4091) // C4091: 'keyword' : ignored on left of 'type' when no variable is declared
19#endif
20#include <dbghelp.h>
21#if defined(_MSC_VER)
22#pragma warning(pop)
23#endif
24#endif
25#endif
26
27namespace CppCommon {
28
30
31class StackTraceManager::Impl
32{
33public:
34 Impl() : _initialized(false) {}
35
36 void Initialize()
37 {
38 // Check for double initialization
39 if (_initialized)
40 return;
41
42#if defined(_WIN32) || defined(_WIN64)
43#if defined(DBGHELP_SUPPORT)
44 // Provide required symbol options
45 SymSetOptions(SYMOPT_PUBLICS_ONLY);
46
47 // Get the current process handle
48 HANDLE hProcess = GetCurrentProcess();
49
50 // Initializes symbol handler for the current process
51 if (!InitializeSymbols(hProcess))
52 throwex SystemException("Cannot initialize symbol handler for the current process!");
53#endif
54#endif
55
56 _initialized = true;
57 }
58
59 void Cleanup()
60 {
61 // Check for double cleanup
62 if (!_initialized)
63 return;
64
65#if defined(_WIN32) || defined(_WIN64)
66#if defined(DBGHELP_SUPPORT)
67 // Get the current process handle
68 HANDLE hProcess = GetCurrentProcess();
69
70 // Cleanup symbol handler for the current process
71 if (!SymCleanup(hProcess))
72 throwex SystemException("Cannot cleanup symbol handler for the current process!");
73#endif
74#endif
75
76 _initialized = false;
77 }
78
79private:
80 bool _initialized;
81
82#if defined(_WIN32) || defined(_WIN64)
83#if defined(DBGHELP_SUPPORT)
84 bool InitializeSymbols(HANDLE hProcess)
85 {
86 const int attempts = 10;
87 const int sleep = 100;
88 for (int attempt = 0; attempt < attempts; ++attempt)
89 {
90 if (SymInitialize(hProcess, nullptr, TRUE))
91 return true;
92
93 Sleep(sleep);
94 }
95 return false;
96 }
97#endif
98#endif
99};
100
102
103StackTraceManager::StackTraceManager()
104{
105 // Check implementation storage parameters
106 [[maybe_unused]] ValidateAlignedStorage<sizeof(Impl), alignof(Impl), StorageSize, StorageAlign> _;
107 static_assert((StorageSize >= sizeof(Impl)), "StackTraceManager::StorageSize must be increased!");
108 static_assert(((StorageAlign % alignof(Impl)) == 0), "StackTraceManager::StorageAlign must be adjusted!");
109
110 // Create the implementation instance
111 new(&_storage)Impl();
112}
113
115{
116 // Delete the implementation instance
117 reinterpret_cast<Impl*>(&_storage)->~Impl();
118}
119
120void StackTraceManager::Initialize() { GetInstance().impl().Initialize(); }
121void StackTraceManager::Cleanup() { GetInstance().impl().Cleanup(); }
122
123} // namespace CppCommon
static StackTraceManager & GetInstance()
Get singleton instance.
Definition singleton.h:61
static void Initialize()
Initialize stack trace manager.
static void Cleanup()
Cleanup stack trace manager.
#define throwex
Throw extended exception macro.
Definition exceptions.h:23
C++ Common project definitions.
Stack trace manager definition.
Aligned storage validator definition.