Handle exceptions and print stack traces.
This commit is contained in:
@@ -1,19 +1,95 @@
|
||||
#if defined(WIN32) && defined(SNMALLOC_CI_BUILD)
|
||||
# include <ds/bits.h>
|
||||
# include <iostream>
|
||||
# include <pal/pal.h>
|
||||
# include <signal.h>
|
||||
# include <stdlib.h>
|
||||
// Has to come after the PAL.
|
||||
# include <DbgHelp.h>
|
||||
# pragma comment(lib, "dbghelp.lib")
|
||||
|
||||
void print_stack_trace()
|
||||
{
|
||||
DWORD error;
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
|
||||
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
|
||||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_SYM_NAME;
|
||||
|
||||
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
|
||||
|
||||
if (!SymInitialize(hProcess, NULL, TRUE))
|
||||
{
|
||||
// SymInitialize failed
|
||||
error = GetLastError();
|
||||
printf("SymInitialize returned error : %d\n", error);
|
||||
return;
|
||||
}
|
||||
|
||||
void* stack[1024];
|
||||
DWORD count = CaptureStackBackTrace(0, 1024, stack, NULL);
|
||||
IMAGEHLP_LINE64 line;
|
||||
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
|
||||
for (int i = 0; count > 0; count--, i++)
|
||||
{
|
||||
DWORD64 dwDisplacement = 0;
|
||||
DWORD64 dwAddress = (DWORD64)stack[i];
|
||||
|
||||
if (SymFromAddr(hProcess, dwAddress, &dwDisplacement, pSymbol))
|
||||
{
|
||||
DWORD dwDisplacement2 = 0;
|
||||
if (SymGetLineFromAddr64(hProcess, dwAddress, &dwDisplacement2, &line))
|
||||
{
|
||||
std::cerr << "Frame: " << pSymbol->Name << " (" << line.FileName << ": "
|
||||
<< line.LineNumber << ")" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Frame: " << pSymbol->Name << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = GetLastError();
|
||||
std::cerr << "SymFromAddr returned error : " << error << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _cdecl error(int signal)
|
||||
{
|
||||
UNUSED(signal);
|
||||
puts("*****ABORT******");
|
||||
|
||||
print_stack_trace();
|
||||
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
# define CALL_LAST 0
|
||||
LONG WINAPI VectoredHandler(struct _EXCEPTION_POINTERS* ExceptionInfo)
|
||||
{
|
||||
UNUSED(ExceptionInfo);
|
||||
|
||||
puts("*****UNHANDLED EXCEPTION******");
|
||||
|
||||
print_stack_trace();
|
||||
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Disable abort dialog box in CI builds.
|
||||
_set_error_mode(_OUT_TO_STDERR);
|
||||
_set_abort_behavior(0, _WRITE_ABORT_MSG);
|
||||
signal(SIGABRT, error);
|
||||
|
||||
AddVectoredExceptionHandler(CALL_LAST, VectoredHandler);
|
||||
}
|
||||
#else
|
||||
void setup() {}
|
||||
|
||||
Reference in New Issue
Block a user