diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index e2f98c2f041..4d4a3cd7b2d 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -50,6 +50,9 @@ #include #include #include +#include +#include +#include #include #include @@ -70,6 +73,11 @@ #include #include +#if defined(Q_OS_LINUX) +#include +#include +#endif + #ifdef Q_OS_WIN #ifndef Q_OS_WINCE # if !defined(Q_CC_MINGW) || (defined(Q_CC_MINGW) && defined(__MINGW64_VERSION_MAJOR)) @@ -93,6 +101,28 @@ QT_BEGIN_NAMESPACE using QtMiscUtils::toHexUpper; using QtMiscUtils::fromHex; + +static void stackTrace() +{ + bool ok = false; + const int disableStackDump = qEnvironmentVariableIntValue("QTEST_DISABLE_STACK_DUMP", &ok); + if (ok && disableStackDump == 1) + return; +#ifdef Q_OS_LINUX + fprintf(stderr, "\n========= Received signal, dumping stack ==============\n"); + char cmd[512]; + qsnprintf(cmd, 512, "gdb --pid %d 2>/dev/null <= dataCount ? static_cast(0) : table.testData(curDataIndex)); + watchDog->beginTest(); qInvokeTestMethodDataEntry(slot); + watchDog->testFinished(); if (data) break; @@ -2359,6 +2440,8 @@ static void qInvokeTestMethods(QObject *testObject) QTestTable::globalTestTable(); invokeMethod(testObject, "initTestCase_data()"); + WatchDog watchDog; + if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) { invokeMethod(testObject, "initTestCase()"); @@ -2373,7 +2456,7 @@ static void qInvokeTestMethods(QObject *testObject) if (QTest::testFuncs) { for (int i = 0; i != QTest::testFuncCount; i++) { if (!qInvokeTestMethod(metaObject->method(QTest::testFuncs[i].function()).methodSignature().constData(), - QTest::testFuncs[i].data())) { + QTest::testFuncs[i].data(), &watchDog)) { break; } } @@ -2386,7 +2469,7 @@ static void qInvokeTestMethods(QObject *testObject) for (int i = 0; i != methodCount; i++) { if (!isValidSlot(testMethods[i])) continue; - if (!qInvokeTestMethod(testMethods[i].methodSignature().constData())) + if (!qInvokeTestMethod(testMethods[i].methodSignature().constData(), 0, &watchDog)) break; } delete[] testMethods; @@ -2422,6 +2505,8 @@ private: void FatalSignalHandler::signal(int signum) { + if (signum != SIGINT) + stackTrace(); qFatal("Received signal %d", signum); #if defined(Q_OS_INTEGRITY) { diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index 488b65c6576..a5840d16d22 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -566,7 +566,9 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge #endif QProcess proc; - static const QProcessEnvironment environment = processEnvironment(); + QProcessEnvironment environment = processEnvironment(); + if (crashes) + environment.insert("QTEST_DISABLE_STACK_DUMP", "1"); proc.setProcessEnvironment(environment); const QString path = subdir + QLatin1Char('/') + subdir; proc.start(path, arguments);