diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2022-05-02 18:22:11 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2022-05-20 12:01:33 -0700 |
commit | 3bd1aa09b62684cb7b715d5d5d5a6def20f27597 (patch) | |
tree | ad4e0f79ae584282db3f7193d5536b2967749d4e /src/testlib | |
parent | 4e8da8f1ec4cba95f9796b96b1d11d79cc82f0ee (diff) |
FatalSignalHandler: split the Windows and Unix contents
They're very different, so there's no point in having them even in the
same class body. I've renamed the Windows one because Windows does not
report crashes via signals anyway. If you have an IDE that can scan both
branches of the #if, it will help you find the Windows-specific code
too.
Pick-to: 6.3
Change-Id: I5ff8e16fcdcb4ffd9ab6fffd16eb73ba196cfb74
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'src/testlib')
-rw-r--r-- | src/testlib/qtestcase.cpp | 115 |
1 files changed, 58 insertions, 57 deletions
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index ca906f6d2b..8c40d111b8 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1771,20 +1771,70 @@ DebugSymbolResolver::Symbol DebugSymbolResolver::resolveSymbol(DWORD64 address) return result; } -#endif // Q_OS_WIN - -class FatalSignalHandler +class WindowsFaultHandler { public: - FatalSignalHandler() + WindowsFaultHandler() { -#if defined(Q_OS_WIN) # if !defined(Q_CC_MINGW) _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); # endif SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX); SetUnhandledExceptionFilter(windowsFaultHandler); + } + +private: + static LONG WINAPI windowsFaultHandler(struct _EXCEPTION_POINTERS *exInfo) + { + enum { maxStackFrames = 100 }; + char appName[MAX_PATH]; + if (!GetModuleFileNameA(NULL, appName, MAX_PATH)) + appName[0] = 0; + const int msecsFunctionTime = qRound(QTestLog::msecsFunctionTime()); + const int msecsTotalTime = qRound(QTestLog::msecsTotalTime()); + const void *exceptionAddress = exInfo->ExceptionRecord->ExceptionAddress; + printf("A crash occurred in %s.\n" + "Function time: %dms Total time: %dms\n\n" + "Exception address: 0x%p\n" + "Exception code : 0x%lx\n", + appName, msecsFunctionTime, msecsTotalTime, + exceptionAddress, exInfo->ExceptionRecord->ExceptionCode); + + DebugSymbolResolver resolver(GetCurrentProcess()); + if (resolver.isValid()) { + DebugSymbolResolver::Symbol exceptionSymbol = resolver.resolveSymbol(DWORD64(exceptionAddress)); + if (exceptionSymbol.name) { + printf("Nearby symbol : %s\n", exceptionSymbol.name); + delete [] exceptionSymbol.name; + } + void *stack[maxStackFrames]; + fputs("\nStack:\n", stdout); + const unsigned frameCount = CaptureStackBackTrace(0, DWORD(maxStackFrames), stack, NULL); + for (unsigned f = 0; f < frameCount; ++f) { + DebugSymbolResolver::Symbol symbol = resolver.resolveSymbol(DWORD64(stack[f])); + if (symbol.name) { + printf("#%3u: %s() - 0x%p\n", f + 1, symbol.name, (const void *)symbol.address); + delete [] symbol.name; + } else { + printf("#%3u: Unable to obtain symbol\n", f + 1); + } + } + } + + fputc('\n', stdout); + fflush(stdout); + + return EXCEPTION_EXECUTE_HANDLER; + } +}; +using FatalSignalHandler = WindowsFaultHandler; + #elif defined(Q_OS_UNIX) && !defined(Q_OS_WASM) +class FatalSignalHandler +{ +public: + FatalSignalHandler() + { pauseOnCrash = qEnvironmentVariableIsSet("QTEST_PAUSE_ON_CRASH"); sigemptyset(&handledSignals); @@ -1854,12 +1904,10 @@ public: else // Restore non-default handler: sigaction(signal, &oldact, nullptr); } -#endif // defined(Q_OS_UNIX) && !defined(Q_OS_WASM) } ~FatalSignalHandler() { -#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM) // Restore the default signal handler in place of ours. // If ours has been replaced, leave the replacement alone. struct sigaction act; @@ -1884,56 +1932,9 @@ public: if (isOurs(action)) sigaction(signum, &act, nullptr); } -#endif } private: -#if defined(Q_OS_WIN) - static LONG WINAPI windowsFaultHandler(struct _EXCEPTION_POINTERS *exInfo) - { - enum { maxStackFrames = 100 }; - char appName[MAX_PATH]; - if (!GetModuleFileNameA(NULL, appName, MAX_PATH)) - appName[0] = 0; - const int msecsFunctionTime = qRound(QTestLog::msecsFunctionTime()); - const int msecsTotalTime = qRound(QTestLog::msecsTotalTime()); - const void *exceptionAddress = exInfo->ExceptionRecord->ExceptionAddress; - printf("A crash occurred in %s.\n" - "Function time: %dms Total time: %dms\n\n" - "Exception address: 0x%p\n" - "Exception code : 0x%lx\n", - appName, msecsFunctionTime, msecsTotalTime, - exceptionAddress, exInfo->ExceptionRecord->ExceptionCode); - - DebugSymbolResolver resolver(GetCurrentProcess()); - if (resolver.isValid()) { - DebugSymbolResolver::Symbol exceptionSymbol = resolver.resolveSymbol(DWORD64(exceptionAddress)); - if (exceptionSymbol.name) { - printf("Nearby symbol : %s\n", exceptionSymbol.name); - delete [] exceptionSymbol.name; - } - void *stack[maxStackFrames]; - fputs("\nStack:\n", stdout); - const unsigned frameCount = CaptureStackBackTrace(0, DWORD(maxStackFrames), stack, NULL); - for (unsigned f = 0; f < frameCount; ++f) { - DebugSymbolResolver::Symbol symbol = resolver.resolveSymbol(DWORD64(stack[f])); - if (symbol.name) { - printf("#%3u: %s() - 0x%p\n", f + 1, symbol.name, (const void *)symbol.address); - delete [] symbol.name; - } else { - printf("#%3u: Unable to obtain symbol\n", f + 1); - } - } - } - - fputc('\n', stdout); - fflush(stdout); - - return EXCEPTION_EXECUTE_HANDLER; - } -#endif // defined(Q_OS_WIN) - -#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM) # ifdef SA_SIGINFO static void signal(int signum, siginfo_t * /* info */, void * /* ucontext */) # else @@ -1967,11 +1968,11 @@ private: sigset_t handledSignals; static bool pauseOnCrash; -#endif // defined(Q_OS_UNIX) && !defined(Q_OS_WASM) }; -#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM) bool FatalSignalHandler::pauseOnCrash = false; -#endif // defined(Q_OS_UNIX) && !defined(Q_OS_WASM) +#else // Q_OS_WASM or weird systems +class FatalSignalHandler {}; +#endif // Q_OS_* choice } // unnamed namespace |