#if defined(SNMALLOC_CI_BUILD) # if defined(WIN32) # include # include # include # include # include // Has to come after the PAL. # include # 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 : %lu\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) { snmalloc::UNUSED(signal); puts("*****ABORT******"); print_stack_trace(); _exit(1); } LONG WINAPI VectoredHandler(struct _EXCEPTION_POINTERS* ExceptionInfo) { snmalloc::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); // If we have an unhandled exception print a stack trace. SetUnhandledExceptionFilter(VectoredHandler); // Disable OS level dialog boxes during CI. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); } # else # include # include void error_handle(int signal) { snmalloc::UNUSED(signal); snmalloc::error("Seg Fault"); _exit(1); } void setup() { signal(SIGSEGV, error_handle); } # endif #else void setup() {} #endif