Skip to content

Commit

Permalink
Handle exceptions and print stack traces.
Browse files Browse the repository at this point in the history
  • Loading branch information
mjp41 committed Aug 14, 2019
1 parent 2c74ee9 commit db4d203
Showing 1 changed file with 76 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/test/setup.h
Original file line number Diff line number Diff line change
@@ -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() {}
Expand Down

0 comments on commit db4d203

Please sign in to comment.