FatalSignalHandler: expand to more Unix OSes than just Linux and macOS
At least for my FreeBSD this makes sense. The default debugger search is gdb first then lldb on Linux-not-Android and for QNX (qcc is GCC after all), but lldb first everywhere else. With LLVM14 from Ports, I get: $ tests/auto/corelib/tools/qhashseed/tst_qhashseed | head -1 ********* Start testing of tst_QHashSeed ********* Config: Using QtTest library 6.4.0, Qt 6.4.0 (x86_64-little_endian-lp64 shared (dynamic) debug build; by Clang 14.0.0), freebsd 13.0 === Received signal at function time: 1ms, total time: 3ms, dumping stack === (lldb) process attach --pid 1782 Process 1782 stopped Executable module set to "/usr/home/tjmaciei/obj/qt/qt6/qtbase/tests/auto/corelib/tools/qhashseed/tst_qhashseed". Architecture set to: x86_64--freebsd13.0. (lldb) bt all * thread #1, name = 'tst_qhashseed' * frame #0: 0x0000000800f227c8 libc.so.7`_wait4 at _wait4.S:4 frame #1: 0x00000008003243bc libthr.so.3`__thr_wait4(pid=<unavailable>, status=<unavailable>, options=<unavailable>, rusage=<unavailable>) at thr_syscalls.c:581:8 frame #2: 0x00000008002b9c73 libQt6Test.t.so.6`(anonymous namespace)::StackTraceHandler::generate() at qtestcase.cpp:393:9 [...] === End of stack trace === Received signal 13 Function time: 1ms Total time: 3ms Support for Windows left as an exercise for later. The WindowsFaultHandler code doesn't even call generateStackTrace(). Change-Id: I5ff8e16fcdcb4ffd9ab6fffd16eba471f58ff3cb Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
d5f4f91c3c
commit
7ad8a2e8fe
@ -80,6 +80,9 @@
|
||||
#include <QtCore/private/qcore_unix_p.h>
|
||||
|
||||
#include <errno.h>
|
||||
#if __has_include(<paths.h>)
|
||||
# include <paths.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/mman.h>
|
||||
@ -89,6 +92,9 @@
|
||||
# if !defined(Q_OS_INTEGRITY)
|
||||
# include <sys/resource.h>
|
||||
# endif
|
||||
# ifndef _PATH_DEFPATH
|
||||
# define _PATH_DEFPATH "/usr/bin:/bin"
|
||||
# endif
|
||||
# ifndef SIGSTKSZ
|
||||
# define SIGSTKSZ 0 /* we have code to set the minimum */
|
||||
# endif
|
||||
@ -288,12 +294,52 @@ static void prepareStackTrace()
|
||||
return; // LLDB will fail to provide a valid stack trace
|
||||
#endif
|
||||
|
||||
// prepare the command to be run (our PID shouldn't change!)
|
||||
# ifdef Q_OS_LINUX
|
||||
debugger = Gdb;
|
||||
# elif defined(Q_OS_MACOS)
|
||||
debugger = Lldb;
|
||||
#ifdef Q_OS_UNIX
|
||||
// like QStandardPaths::findExecutable(), but simpler
|
||||
auto hasExecutable = [](const char *execname) {
|
||||
std::string candidate;
|
||||
std::string path;
|
||||
if (const char *p = getenv("PATH"); p && *p)
|
||||
path = p;
|
||||
else
|
||||
path = _PATH_DEFPATH;
|
||||
for (const char *p = std::strtok(&path[0], ":'"); p; p = std::strtok(nullptr, ":")) {
|
||||
candidate = p;
|
||||
candidate += '/';
|
||||
candidate += execname;
|
||||
if (QT_ACCESS(candidate.data(), X_OK) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
static constexpr DebuggerProgram debuggerSearchOrder[] = {
|
||||
# if defined(Q_OS_QNX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
Gdb, Lldb
|
||||
# else
|
||||
Lldb, Gdb
|
||||
# endif
|
||||
};
|
||||
for (DebuggerProgram candidate : debuggerSearchOrder) {
|
||||
switch (candidate) {
|
||||
case None:
|
||||
Q_UNREACHABLE();
|
||||
break;
|
||||
case Gdb:
|
||||
if (hasExecutable("gdb")) {
|
||||
debugger = Gdb;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case Lldb:
|
||||
if (hasExecutable("lldb")) {
|
||||
debugger = Lldb;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // Q_OS_UNIX
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void generateStackTrace()
|
||||
@ -301,7 +347,7 @@ static void prepareStackTrace()
|
||||
if (debugger == None || alreadyDebugging())
|
||||
return;
|
||||
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM) && !defined(Q_OS_INTEGRITY)
|
||||
const int msecsFunctionTime = qRound(QTestLog::msecsFunctionTime());
|
||||
const int msecsTotalTime = qRound(QTestLog::msecsTotalTime());
|
||||
writeToStderr("\n=== Received signal at function time: ", asyncSafeToString(msecsFunctionTime),
|
||||
@ -341,7 +387,7 @@ static void prepareStackTrace()
|
||||
EINTR_LOOP(ret, waitpid(pid, nullptr, 0));
|
||||
}
|
||||
writeToStderr("=== End of stack trace ===\n");
|
||||
#endif
|
||||
#endif // Q_OS_UNIX && !Q_OS_WASM
|
||||
}
|
||||
|
||||
static bool installCoverageTool(const char * appname, const char * testname)
|
||||
|
Loading…
Reference in New Issue
Block a user