mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-24 02:46:33 +01:00
Core/CrashHandler: Add more informations about locals
Handle SymTagData with inner type of SymTagPointerType. Increase buffer sizes to avoid buffer overflows. Avoid infinite loops by logging the children of each type only once. Avoid too deep nesting by adding a max nesting level. Print the address for arrays instead of just the name.
This commit is contained in:
@@ -51,6 +51,7 @@ LPTOP_LEVEL_EXCEPTION_FILTER WheatyExceptionReport::m_previousFilter;
|
||||
HANDLE WheatyExceptionReport::m_hReportFile;
|
||||
HANDLE WheatyExceptionReport::m_hDumpFile;
|
||||
HANDLE WheatyExceptionReport::m_hProcess;
|
||||
SymbolPairs WheatyExceptionReport::symbols;
|
||||
|
||||
// Declare global instance of class
|
||||
WheatyExceptionReport g_WheatyExceptionReport;
|
||||
@@ -78,6 +79,7 @@ WheatyExceptionReport::~WheatyExceptionReport()
|
||||
{
|
||||
if (m_previousFilter)
|
||||
SetUnhandledExceptionFilter(m_previousFilter);
|
||||
ClearSymbols();
|
||||
}
|
||||
|
||||
//===========================================================
|
||||
@@ -498,12 +500,12 @@ PEXCEPTION_POINTERS pExceptionInfo)
|
||||
WriteStackDetails(&trashableContext, true, NULL);
|
||||
printTracesForAllThreads(true);
|
||||
|
||||
_tprintf(_T("========================\r\n"));
|
||||
/*_tprintf(_T("========================\r\n"));
|
||||
_tprintf(_T("Global Variables\r\n"));
|
||||
|
||||
SymEnumSymbols(GetCurrentProcess(),
|
||||
(UINT_PTR)GetModuleHandle(szFaultingModule),
|
||||
0, EnumerateSymbolsCallback, 0);
|
||||
0, EnumerateSymbolsCallback, 0);*/
|
||||
// #endif // X86 Only!
|
||||
|
||||
SymCleanup(GetCurrentProcess());
|
||||
@@ -757,10 +759,11 @@ ULONG /*SymbolSize*/,
|
||||
PVOID UserContext)
|
||||
{
|
||||
|
||||
char szBuffer[8192];
|
||||
char szBuffer[1024 * 64];
|
||||
|
||||
__try
|
||||
{
|
||||
ClearSymbols();
|
||||
if (FormatSymbolValue(pSymInfo, (STACKFRAME64*)UserContext,
|
||||
szBuffer, sizeof(szBuffer)))
|
||||
_tprintf(_T("\t%s\r\n"), szBuffer);
|
||||
@@ -862,6 +865,9 @@ char* suffix)
|
||||
{
|
||||
bHandled = false;
|
||||
|
||||
if (!StoreSymbol(dwTypeIndex, offset))
|
||||
return pszCurrBuffer;
|
||||
|
||||
DWORD typeTag;
|
||||
if (!SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMTAG, &typeTag))
|
||||
return pszCurrBuffer;
|
||||
@@ -879,12 +885,16 @@ char* suffix)
|
||||
if (strlen(suffix) > 0)
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, "%s", suffix);
|
||||
|
||||
DWORD innerTypeID;
|
||||
switch (typeTag)
|
||||
{
|
||||
case SymTagPointerType:
|
||||
DWORD innerTypeID;
|
||||
if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &innerTypeID))
|
||||
{
|
||||
#define MAX_NESTING_LEVEL 5
|
||||
if (nestingLevel >= MAX_NESTING_LEVEL)
|
||||
break;
|
||||
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, " %s", Name);
|
||||
BOOL isReference;
|
||||
SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_IS_REFERENCE, &isReference);
|
||||
@@ -908,7 +918,7 @@ char* suffix)
|
||||
LocalFree(pwszTypeName);
|
||||
}
|
||||
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, "%s = NULL", addressStr);
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, "%s = NULL\r\n", addressStr);
|
||||
|
||||
bHandled = true;
|
||||
return pszCurrBuffer;
|
||||
@@ -921,6 +931,26 @@ char* suffix)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SymTagData:
|
||||
if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &innerTypeID))
|
||||
{
|
||||
DWORD innerTypeTag;
|
||||
if (!SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_SYMTAG, &innerTypeTag))
|
||||
break;
|
||||
|
||||
if (innerTypeTag == SymTagPointerType)
|
||||
{
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, " %s", Name);
|
||||
|
||||
pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1,
|
||||
offset, bHandled, "", "");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SymTagBaseType:
|
||||
break;
|
||||
case SymTagEnum:
|
||||
return pszCurrBuffer;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -937,7 +967,7 @@ char* suffix)
|
||||
// TI_FINDCHILDREN_PARAMS struct has. Use derivation to accomplish this.
|
||||
struct FINDCHILDREN : TI_FINDCHILDREN_PARAMS
|
||||
{
|
||||
ULONG MoreChildIds[1024];
|
||||
ULONG MoreChildIds[1024*2];
|
||||
FINDCHILDREN(){Count = sizeof(MoreChildIds) / sizeof(MoreChildIds[0]);}
|
||||
} children;
|
||||
|
||||
@@ -1058,6 +1088,14 @@ PVOID pAddress)
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X",
|
||||
*(DWORD64*)pAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if _WIN64
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X", (DWORD64*)pAddress);
|
||||
#else
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", (PDWORD)pAddress);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
@@ -1102,7 +1140,7 @@ WheatyExceptionReport::GetBasicType(DWORD typeIndex, DWORD64 modBase)
|
||||
//============================================================================
|
||||
int __cdecl WheatyExceptionReport::_tprintf(const TCHAR * format, ...)
|
||||
{
|
||||
TCHAR szBuff[8192];
|
||||
TCHAR szBuff[1024 * 64];
|
||||
int retValue;
|
||||
DWORD cbWritten;
|
||||
va_list argptr;
|
||||
@@ -1116,4 +1154,14 @@ int __cdecl WheatyExceptionReport::_tprintf(const TCHAR * format, ...)
|
||||
return retValue;
|
||||
}
|
||||
|
||||
bool WheatyExceptionReport::StoreSymbol(DWORD type, DWORD_PTR offset)
|
||||
{
|
||||
return symbols.insert(SymbolPair(type, offset)).second;
|
||||
}
|
||||
|
||||
void WheatyExceptionReport::ClearSymbols()
|
||||
{
|
||||
symbols.clear();
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#if PLATFORM == PLATFORM_WINDOWS && !defined(__MINGW32__)
|
||||
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include <set>
|
||||
#if _MSC_VER < 1400
|
||||
# define countof(array) (sizeof(array) / sizeof(array[0]))
|
||||
#else
|
||||
@@ -70,6 +70,25 @@ const char* const rgBaseType[] =
|
||||
" 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;
|
||||
|
||||
class WheatyExceptionReport
|
||||
{
|
||||
public:
|
||||
@@ -108,6 +127,9 @@ class WheatyExceptionReport
|
||||
|
||||
static int __cdecl _tprintf(const TCHAR * format, ...);
|
||||
|
||||
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];
|
||||
@@ -115,6 +137,7 @@ class WheatyExceptionReport
|
||||
static HANDLE m_hReportFile;
|
||||
static HANDLE m_hDumpFile;
|
||||
static HANDLE m_hProcess;
|
||||
static SymbolPairs symbols;
|
||||
};
|
||||
|
||||
extern WheatyExceptionReport g_WheatyExceptionReport; // global instance of class
|
||||
|
||||
Reference in New Issue
Block a user