15#ifndef QTESTCRASHHANDLER_H
16#define QTESTCRASHHANDLER_H
18#include <QtTest/qttestglobal.h>
20#include <QtCore/private/qtools_p.h>
31# if !defined(Q_CC_MINGW) || (defined(Q_CC_MINGW) && defined(__MINGW64_VERSION_MAJOR))
39namespace CrashHandler {
40#if defined(Q_OS_UNIX) && (!defined(Q_OS_WASM) || QT_CONFIG(thread))
41 struct iovec IoVec(struct iovec vec);
42 struct iovec IoVec(const char *
str);
44 template <
typename... Args>
static ssize_t writeToStderr(Args &&...
args)
46 struct iovec vec[] = { IoVec(std::forward<Args>(
args))... };
47 return ::writev(STDERR_FILENO, vec, std::size(vec));
51 struct AsyncSafeIntBuffer
56 static constexpr int Digits10 = std::numeric_limits<int>::digits10 + 3;
57 std::array<char, Digits10>
array;
58 constexpr AsyncSafeIntBuffer() :
array{} {}
63#elif defined(Q_OS_WIN)
65 template <
typename... Args>
static void writeToStderr(Args &&...
args)
67 (std::cerr << ... <<
args);
70 inline std::string asyncSafeToString(
int n)
72 return std::to_string(
n);
79#if !defined(Q_OS_WASM) || QT_CONFIG(thread)
89 class DebugSymbolResolver
91 Q_DISABLE_COPY_MOVE(DebugSymbolResolver)
101 explicit DebugSymbolResolver(HANDLE process);
102 ~DebugSymbolResolver() { cleanup(); }
104 bool isValid()
const {
return m_symFromAddr; }
110 struct DBGHELP_SYMBOL_INFO {
128 typedef BOOL (__stdcall *SymInitializeType)(
HANDLE, PCSTR, BOOL);
129 typedef BOOL (__stdcall *SymFromAddrType)(
HANDLE, DWORD64, PDWORD64, DBGHELP_SYMBOL_INFO *);
135 SymFromAddrType m_symFromAddr;
138 class Q_TESTLIB_EXPORT WindowsFaultHandler
141 WindowsFaultHandler();
144 static LONG WINAPI windowsFaultHandler(
struct _EXCEPTION_POINTERS *exInfo);
146 using FatalSignalHandler = WindowsFaultHandler;
147#elif defined(Q_OS_UNIX) && !defined(Q_OS_WASM)
148 class Q_TESTLIB_EXPORT FatalSignalHandler
151 # define OUR_SIGNALS(F) \
163 # define CASE_LABEL(S) case SIG ## S: return QT_STRINGIFY(S);
164 # define ENUMERATE_SIGNALS(S) SIG ## S,
165 static const char *signalName(
int signum)
noexcept
168 OUR_SIGNALS(CASE_LABEL)
171 # if defined(__GLIBC_MINOR__) && (__GLIBC_MINOR__ >= 32 || __GLIBC__ > 2)
174 if (
const char *
p = sigabbrev_np(signum))
179 static constexpr std::array fatalSignals = {
180 OUR_SIGNALS(ENUMERATE_SIGNALS)
183 # undef ENUMERATE_SIGNALS
185 static constexpr std::array crashingSignals = {
192 SIGILL, SIGBUS, SIGFPE, SIGSEGV
194 using OldActionsArray = std::array<
struct sigaction, fatalSignals.
size()>;
196 FatalSignalHandler();
197 ~FatalSignalHandler();
200 Q_DISABLE_COPY_MOVE(FatalSignalHandler)
202 static OldActionsArray &oldActions();
203 auto alternateStackSize();
204 int setupAlternateStack();
205 void freeAlternateStack();
207 template <
typename T>
static
208 std::enable_if_t<sizeof(std::declval<T>().si_pid) +
sizeof(std::declval<T>().si_uid) >= 1>
209 printSentSignalInfo(T *
info)
211 writeToStderr(
" sent by PID ", asyncSafeToString(
info->si_pid),
212 " UID ", asyncSafeToString(
info->si_uid));
214 static void printSentSignalInfo(...) {}
216 template <
typename T>
static
217 std::enable_if_t<sizeof(std::declval<T>().si_addr) >= 1> printCrashingSignalInfo(T *
info)
225 vec.iov_base =
r.data();
226 vec.iov_len =
r.size();
229 writeToStderr(
", code ", asyncSafeToString(
info->si_code),
230 ", for address 0x", toHexString(
quintptr(
info->si_addr)));
232 static void printCrashingSignalInfo(...) {}
233 static void actionHandler(
int signum, siginfo_t *
info,
void * );
235 [[maybe_unused]]
static void regularHandler(
int signum)
237 actionHandler(signum,
nullptr,
nullptr);
241 static bool pauseOnCrash;
std::list< QString >::iterator Name
Combined button and popup list for selecting options.
void maybeDisableCoreDump()
void generateStackTrace()
constexpr char toHexLower(char32_t value) noexcept
constexpr Initialization Uninitialized
static QT_WARNING_DISABLE_FLOAT_COMPARE ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qreal threshold)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLuint64EXT address