diff options
author | StormBytePP <stormbyte@gmail.com> | 2015-08-19 19:02:10 +0200 |
---|---|---|
committer | StormBytePP <stormbyte@gmail.com> | 2015-08-21 17:52:42 +0200 |
commit | 1d2aafd39bcb79a67357d198ce9b2345642fdd39 (patch) | |
tree | c32cf1c3717625c60da59c82ba5a4fca2530119a /src/common/Debugging/WheatyExceptionReport.h | |
parent | 172293acee1607727ebd8070ab3e1390590d02a8 (diff) |
Core/Build: Merge common library and move database out of shared
Diffstat (limited to 'src/common/Debugging/WheatyExceptionReport.h')
-rw-r--r-- | src/common/Debugging/WheatyExceptionReport.h | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/src/common/Debugging/WheatyExceptionReport.h b/src/common/Debugging/WheatyExceptionReport.h new file mode 100644 index 00000000000..8c2479d5232 --- /dev/null +++ b/src/common/Debugging/WheatyExceptionReport.h @@ -0,0 +1,210 @@ +#ifndef _WHEATYEXCEPTIONREPORT_ +#define _WHEATYEXCEPTIONREPORT_ + +#if PLATFORM == PLATFORM_WINDOWS && !defined(__MINGW32__) + +#include <dbghelp.h> +#include <set> +#include <stdlib.h> +#include <stack> +#include <mutex> +#define countof _countof + +#define WER_MAX_ARRAY_ELEMENTS_COUNT 10 +#define WER_MAX_NESTING_LEVEL 5 +#define WER_LARGE_BUFFER_SIZE 1024 * 128 + +enum BasicType // Stolen from CVCONST.H in the DIA 2.0 SDK +{ + btNoType = 0, + btVoid = 1, + btChar = 2, + btWChar = 3, + btInt = 6, + btUInt = 7, + btFloat = 8, + btBCD = 9, + btBool = 10, + btLong = 13, + btULong = 14, + btCurrency = 25, + btDate = 26, + btVariant = 27, + btComplex = 28, + btBit = 29, + btBSTR = 30, + btHresult = 31, + + // Custom types + btStdString = 101 +}; + +enum DataKind // Stolen from CVCONST.H in the DIA 2.0 SDK +{ + DataIsUnknown, + DataIsLocal, + DataIsStaticLocal, + DataIsParam, + DataIsObjectPtr, + DataIsFileStatic, + DataIsGlobal, + DataIsMember, + DataIsStaticMember, + DataIsConstant +}; + +const char* const rgBaseType[] = +{ + "<user defined>", // btNoType = 0, + "void", // btVoid = 1, + "char",//char* // btChar = 2, + "wchar_t*", // btWChar = 3, + "signed char", + "unsigned char", + "int", // btInt = 6, + "unsigned int", // btUInt = 7, + "float", // btFloat = 8, + "<BCD>", // btBCD = 9, + "bool", // btBool = 10, + "short", + "unsigned short", + "long", // btLong = 13, + "unsigned long", // btULong = 14, + "int8", + "int16", + "int32", + "int64", + "int128", + "uint8", + "uint16", + "uint32", + "uint64", + "uint128", + "<currency>", // btCurrency = 25, + "<date>", // btDate = 26, + "VARIANT", // btVariant = 27, + "<complex>", // btComplex = 28, + "<bit>", // btBit = 29, + "BSTR", // btBSTR = 30, + "HRESULT" // btHresult = 31 +}; + +struct SymbolPair +{ + SymbolPair(DWORD type, DWORD_PTR offset) + { + _type = type; + _offset = offset; + } + + bool operator<(const SymbolPair& other) const + { + return _offset < other._offset || + (_offset == other._offset && _type < other._type); + } + + DWORD _type; + DWORD_PTR _offset; +}; +typedef std::set<SymbolPair> SymbolPairs; + +struct SymbolDetail +{ + SymbolDetail() : Prefix(), Type(), Suffix(), Name(), Value(), Logged(false), HasChildren(false) {} + + std::string ToString() + { + Logged = true; + std::string formatted = Prefix + Type + Suffix; + if (!Name.empty()) + { + if (!formatted.empty()) + formatted += " "; + formatted += Name; + } + if (!Value.empty()) + formatted += " = " + Value; + return formatted; + } + + bool empty() const + { + return Value.empty() && !HasChildren; + } + + std::string Prefix; + std::string Type; + std::string Suffix; + std::string Name; + std::string Value; + bool Logged; + bool HasChildren; +}; + +class WheatyExceptionReport +{ + public: + + WheatyExceptionReport(); + ~WheatyExceptionReport(); + + // entry point where control comes on an unhandled exception + static LONG WINAPI WheatyUnhandledExceptionFilter( + PEXCEPTION_POINTERS pExceptionInfo); + + static void printTracesForAllThreads(bool); + private: + // where report info is extracted and generated + static void GenerateExceptionReport(PEXCEPTION_POINTERS pExceptionInfo); + static void PrintSystemInfo(); + static BOOL _GetWindowsVersion(TCHAR* szVersion, DWORD cntMax); + static BOOL _GetProcessorName(TCHAR* sProcessorName, DWORD maxcount); + + // Helper functions + static LPTSTR GetExceptionString(DWORD dwCode); + static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, DWORD len, + DWORD& section, DWORD_PTR& offset); + + static void WriteStackDetails(PCONTEXT pContext, bool bWriteVariables, HANDLE pThreadHandle); + + static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO, ULONG, PVOID); + + static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME64 *, char * pszBuffer, unsigned cbBuffer); + + static char * DumpTypeIndex(char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool &, const char*, char*, bool, bool); + + static void FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress, size_t bufferSize, size_t countOverride = 0); + + static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase); + static DWORD_PTR DereferenceUnsafePointer(DWORD_PTR address); + + static int __cdecl _tprintf(const TCHAR * format, ...); + static int __cdecl stackprintf(const TCHAR * format, va_list argptr); + static int __cdecl heapprintf(const TCHAR * format, va_list argptr); + + static bool StoreSymbol(DWORD type , DWORD_PTR offset); + static void ClearSymbols(); + + // Variables used by the class + static TCHAR m_szLogFileName[MAX_PATH]; + static TCHAR m_szDumpFileName[MAX_PATH]; + static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter; + static HANDLE m_hReportFile; + static HANDLE m_hDumpFile; + static HANDLE m_hProcess; + static SymbolPairs symbols; + static std::stack<SymbolDetail> symbolDetails; + static bool stackOverflowException; + static bool alreadyCrashed; + static std::mutex alreadyCrashedLock; + + static char* PushSymbolDetail(char* pszCurrBuffer); + static char* PopSymbolDetail(char* pszCurrBuffer); + static char* PrintSymbolDetail(char* pszCurrBuffer); + +}; + +extern WheatyExceptionReport g_WheatyExceptionReport; // global instance of class +#endif // _WIN32 +#endif // _WHEATYEXCEPTIONREPORT_ + |