Handle exceptions and print stack traces.
This commit is contained in:
@@ -1,19 +1,95 @@
|
|||||||
#if defined(WIN32) && defined(SNMALLOC_CI_BUILD)
|
#if defined(WIN32) && defined(SNMALLOC_CI_BUILD)
|
||||||
# include <ds/bits.h>
|
# include <ds/bits.h>
|
||||||
|
# include <iostream>
|
||||||
|
# include <pal/pal.h>
|
||||||
# include <signal.h>
|
# include <signal.h>
|
||||||
# include <stdlib.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)
|
void _cdecl error(int signal)
|
||||||
{
|
{
|
||||||
UNUSED(signal);
|
UNUSED(signal);
|
||||||
puts("*****ABORT******");
|
puts("*****ABORT******");
|
||||||
|
|
||||||
|
print_stack_trace();
|
||||||
|
|
||||||
_exit(1);
|
_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()
|
void setup()
|
||||||
{
|
{
|
||||||
// Disable abort dialog box in CI builds.
|
// Disable abort dialog box in CI builds.
|
||||||
_set_error_mode(_OUT_TO_STDERR);
|
_set_error_mode(_OUT_TO_STDERR);
|
||||||
_set_abort_behavior(0, _WRITE_ABORT_MSG);
|
_set_abort_behavior(0, _WRITE_ABORT_MSG);
|
||||||
signal(SIGABRT, error);
|
signal(SIGABRT, error);
|
||||||
|
|
||||||
|
AddVectoredExceptionHandler(CALL_LAST, VectoredHandler);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void setup() {}
|
void setup() {}
|
||||||
|
|||||||
Reference in New Issue
Block a user