CppCommon  1.0.4.1
C++ Common Library
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 
27 namespace CppCommon {
28 
30 
31 class StackTraceManager::Impl
32 {
33 public:
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 
79 private:
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 
103 StackTraceManager::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 
120 void StackTraceManager::Initialize() { GetInstance().impl().Initialize(); }
121 void 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.
Definition: token_bucket.h:15
Stack trace manager definition.
Aligned storage validator definition.