summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorPeter Varga <pvarga@inf.u-szeged.hu>2017-03-06 16:15:17 +0100
committerPeter Varga <pvarga@inf.u-szeged.hu>2017-03-08 09:37:10 +0000
commit44cb79ed88152d93d418b0ee1c101da8e05069a7 (patch)
tree09adced26232a936379243af28090127c989993e /tests/auto
parentd2b9edf8a94ef76ce2bcb0ff1cb32d62616df3e1 (diff)
Add SIGSEGV handler for the QML tests on Linux
The new handler prints stack trace if the browser process crashes due to segmentation fault while running QML tests. The solution is based on the QTestLib signal handler implementation. Change-Id: I5ccffc92043375fbf6fa5805a4592c61603efb3f Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/quick/qmltests/tst_qmltests.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/tests/auto/quick/qmltests/tst_qmltests.cpp b/tests/auto/quick/qmltests/tst_qmltests.cpp
index baffdbb57..5dc909709 100644
--- a/tests/auto/quick/qmltests/tst_qmltests.cpp
+++ b/tests/auto/quick/qmltests/tst_qmltests.cpp
@@ -31,8 +31,82 @@
#include <QtWebEngine/QQuickWebEngineProfile>
#include "qt_webengine_quicktest.h"
+#if defined(Q_OS_LINUX) && defined(QT_DEBUG)
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#endif
+
+#if defined(Q_OS_LINUX) && defined(QT_DEBUG)
+static bool debuggerPresent()
+{
+ int fd = open("/proc/self/status", O_RDONLY);
+ if (fd == -1)
+ return false;
+ char buffer[2048];
+ ssize_t size = read(fd, buffer, sizeof(buffer) - 1);
+ if (size == -1) {
+ close(fd);
+ return false;
+ }
+ buffer[size] = 0;
+ const char tracerPidToken[] = "\nTracerPid:";
+ char *tracerPid = strstr(buffer, tracerPidToken);
+ if (!tracerPid) {
+ close(fd);
+ return false;
+ }
+ tracerPid += sizeof(tracerPidToken);
+ long int pid = strtol(tracerPid, &tracerPid, 10);
+ close(fd);
+ return pid != 0;
+}
+
+static void stackTrace()
+{
+ bool ok = false;
+ const int disableStackDump = qEnvironmentVariableIntValue("QTEST_DISABLE_STACK_DUMP", &ok);
+ if (ok && disableStackDump == 1)
+ return;
+
+ if (debuggerPresent())
+ return;
+
+ fprintf(stderr, "\n========= Received signal, dumping stack ==============\n");
+ char cmd[512];
+ qsnprintf(cmd, 512, "gdb --pid %d 2>/dev/null <<EOF\n"
+ "set prompt\n"
+ "set height 0\n"
+ "thread apply all where full\n"
+ "detach\n"
+ "quit\n"
+ "EOF\n",
+ (int)getpid());
+
+ if (system(cmd) == -1)
+ fprintf(stderr, "calling gdb failed\n");
+ fprintf(stderr, "========= End of stack trace ==============\n");
+}
+
+static void sigSegvHandler(int signum)
+{
+ stackTrace();
+ qFatal("Received signal %d", signum);
+}
+#endif
+
int main(int argc, char **argv)
{
+#if defined(Q_OS_LINUX) && defined(QT_DEBUG)
+ struct sigaction sigAction;
+
+ sigemptyset(&sigAction.sa_mask);
+ sigAction.sa_handler = &sigSegvHandler;
+ sigAction.sa_flags = 0;
+
+ sigaction(SIGSEGV, &sigAction, 0);
+#endif
+
// Inject the mock ui delegates module
qputenv("QML2_IMPORT_PATH", QByteArray(TESTS_SOURCE_DIR "qmltests/mock-delegates"));
QScopedPointer<Application> app;