TrinityCore
Loading...
Searching...
No Matches
WheatyExceptionReport.h
Go to the documentation of this file.
1#ifndef _WHEATYEXCEPTIONREPORT_
2#define _WHEATYEXCEPTIONREPORT_
3
4#define _NO_CVCONST_H
5
6#include "Define.h"
7#include "Optional.h"
8#include <windows.h>
9#include <winnt.h>
10#include <winternl.h>
11#include <dbghelp.h>
12#include <compare>
13#include <set>
14#include <cstdlib>
15#include <cstdio>
16#include <stack>
17#include <mutex>
18
19#define WER_MAX_ARRAY_ELEMENTS_COUNT 10
20#define WER_MAX_NESTING_LEVEL 4
21#define WER_SMALL_BUFFER_SIZE 1024
22#define WER_LARGE_BUFFER_SIZE WER_SMALL_BUFFER_SIZE * 16
23
24enum BasicType // Stolen from CVCONST.H in the DIA 2.0 SDK
25{
27 btVoid = 1,
28 btChar = 2,
30 btInt = 6,
31 btUInt = 7,
33 btBCD = 9,
34 btBool = 10,
35 btLong = 13,
36 btULong = 14,
38 btDate = 26,
41 btBit = 29,
42 btBSTR = 30,
44
45 // Custom types
46 btStdString = 101
47};
48
62
63enum CpuRegister // Stolen from CVCONST.H in the DIA SDK
64{
66
67 //
68 // Register set for the Intel 80x86 and ix86 processor series
69 //
96
97 //
98 // AMD64 registers
99 //
125
126 // Low byte forms of some standard registers
131
132 // 64-bit regular registers
141
142 // 64-bit integer registers with 8-, 16-, and 32-bit forms (B, W, and D)
151
160
169
178
179 //
180 // Register set for ARM64
181 //
183
184 // General purpose 32-bit integer registers
217
218 // General purpose 64-bit integer registers
252};
253
254char const* const rgBaseType[] =
255{
256 "<user defined>", // btNoType = 0,
257 "void", // btVoid = 1,
258 "char",//char* // btChar = 2,
259 "wchar_t*", // btWChar = 3,
260 "signed char",
261 "unsigned char",
262 "int", // btInt = 6,
263 "unsigned int", // btUInt = 7,
264 "float", // btFloat = 8,
265 "<BCD>", // btBCD = 9,
266 "bool", // btBool = 10,
267 "short",
268 "unsigned short",
269 "long", // btLong = 13,
270 "unsigned long", // btULong = 14,
271 "int8",
272 "int16",
273 "int32",
274 "int64",
275 "int128",
276 "uint8",
277 "uint16",
278 "uint32",
279 "uint64",
280 "uint128",
281 "<currency>", // btCurrency = 25,
282 "<date>", // btDate = 26,
283 "VARIANT", // btVariant = 27,
284 "<complex>", // btComplex = 28,
285 "<bit>", // btBit = 29,
286 "BSTR", // btBSTR = 30,
287 "HRESULT" // btHresult = 31
288};
289
291{
292 SymbolPair(DWORD type, DWORD_PTR offset)
293 {
294 _type = type;
295 _offset = offset;
296 }
297
298 bool operator==(SymbolPair const& other) const = default;
299 std::strong_ordering operator<=>(SymbolPair const& other) const = default;
300
301 DWORD _type;
302 DWORD_PTR _offset;
303};
304typedef std::set<SymbolPair> SymbolPairs;
305
307{
308 SymbolDetail() : Prefix(), Type(), Suffix(), Name(), Value(), Logged(false), HasChildren(false) {}
309
310 std::string ToString();
311
312 bool empty() const
313 {
314 return Value.empty() && !HasChildren;
315 }
316
317 std::string Prefix;
318 std::string Type;
319 std::string Suffix;
320 std::string Name;
321 std::string Value;
322 bool Logged;
324};
325
327{
328 public:
329
332
333 // entry point where control comes on an unhandled exception
334 static LONG WINAPI WheatyUnhandledExceptionFilter(
335 PEXCEPTION_POINTERS pExceptionInfo);
336
337 static void __cdecl WheatyCrtHandler(wchar_t const* expression, wchar_t const* function, wchar_t const* file, unsigned int line, uintptr_t pReserved);
338
339 static void printTracesForAllThreads(bool);
340 private:
341 // where report info is extracted and generated
342 static void GenerateExceptionReport(PEXCEPTION_POINTERS pExceptionInfo);
343 static void PrintSystemInfo();
344 static BOOL _GetWindowsVersion(TCHAR* szVersion, DWORD cntMax);
345 static BOOL _GetWindowsVersionFromWMI(TCHAR* szVersion, DWORD cntMax);
346 static BOOL _GetProcessorName(TCHAR* sProcessorName, DWORD maxcount);
347
348 // Helper functions
349 static LPCTSTR GetExceptionString(DWORD dwCode);
350 static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, DWORD len,
351 DWORD& section, DWORD_PTR& offset);
352
353 static void WriteStackDetails(PCONTEXT pContext, bool bWriteVariables, HANDLE pThreadHandle);
354
356 {
357 LPSTACKFRAME64 sf;
358 PCONTEXT context;
359 };
360
361 static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO, ULONG, PVOID);
362
363 static bool FormatSymbolValue(PSYMBOL_INFO, EnumerateSymbolsCallbackContext*);
364
365 static void DumpTypeIndex(DWORD64, DWORD, DWORD_PTR, bool &, char const*, char const*, bool, bool);
366
367 static void FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress, size_t bufferSize, size_t countOverride = 0);
368
369 static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase);
370 static DWORD_PTR DereferenceUnsafePointer(DWORD_PTR address);
371
372 static int __cdecl Log(const TCHAR * format, ...);
373
374 static bool StoreSymbol(DWORD type , DWORD_PTR offset);
375 static void ClearSymbols();
376
377 static Optional<DWORD_PTR> GetIntegerRegisterValue(PCONTEXT context, ULONG registerId);
378
379 // Variables used by the class
380 static TCHAR m_szLogFileName[MAX_PATH];
381 static TCHAR m_szDumpFileName[MAX_PATH];
382 static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter;
383 static _invalid_parameter_handler m_previousCrtHandler;
384 static FILE* m_hReportFile;
385 static HANDLE m_hDumpFile;
386 static HANDLE m_hProcess;
388 static std::stack<SymbolDetail> symbolDetails;
389 static bool alreadyCrashed;
390 static std::mutex alreadyCrashedLock;
391 typedef NTSTATUS(NTAPI* pRtlGetVersion)(PRTL_OSVERSIONINFOW lpVersionInformation);
392 static pRtlGetVersion RtlGetVersion;
393
394 static void PushSymbolDetail();
395 static void PopSymbolDetail();
396 static void PrintSymbolDetail();
397
398};
399
400#define INIT_CRASH_HANDLER() \
401 __pragma(warning(push)) \
402 __pragma(warning(disable:4073)) /* C4073: initializers put in library initialization area */ \
403 __pragma(init_seg(lib)) \
404 WheatyExceptionReport g_WheatyExceptionReport; \
405 __pragma(warning(pop))
406
407#endif // _WHEATYEXCEPTIONREPORT_
#define TC_COMMON_API
Definition Define.h:96
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
const size_t bufferSize
Definition RASession.h:31
char const *const rgBaseType[]
std::set< SymbolPair > SymbolPairs
@ CV_ALLREG_VFRAME
@ DataIsUnknown
@ DataIsStaticMember
@ DataIsStaticLocal
@ DataIsObjectPtr
@ DataIsConstant
@ DataIsFileStatic
Definition Log.h:53
static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter
static _invalid_parameter_handler m_previousCrtHandler
static std::mutex alreadyCrashedLock
static pRtlGetVersion RtlGetVersion
static std::stack< SymbolDetail > symbolDetails
std::strong_ordering operator<=>(SymbolPair const &other) const =default
bool operator==(SymbolPair const &other) const =default
SymbolPair(DWORD type, DWORD_PTR offset)