[prev in list] [next in list] [prev in thread] [next in thread]
List: kfm-devel
Subject: [patch] make test_regression SIGSEGV safe
From: Leo Savernik <l.savernik () aon ! at>
Date: 2004-02-09 20:20:40
Message-ID: 200402092120.42092.l.savernik () aon ! at
[Download RAW message or body]
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hello,
I had crashes when running test_regression (which look like a configuration
problem on my side, not in khtml code), and I couldn't figure out the source
of them.
Therefore, I made test_regression catch SIGSEGV, SIGABRT, SIGILL, and SIGFPE,
skip the testcase that caused it (printing an appropriate error msg), and
continue with the next one.
The rationale behind this is that test_regression should *always* attempt to
finish all tests, whatever may happen within a dedicated testcase.
The implementation relies on set/longjmp hackery (but one cannot throw
exceptions within a signal handler and catch them outside of it), and will
leak memory, but it's still better than keeping test_regression from handling
all testcases in case of crashes (The leaks should pose minor problems, as
crashes should only occur very infrequently).
What do you think of it?
mfg
Leo
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org
iD8DBQFAJ+uYj5jssenUYTsRAmK/AJ9DABgKNIOgoiguyr0n7nGQCXgJ8gCeMAHk
q1QvkjDoK2mlLYjJTfU9QfI=
=rc7T
-----END PGP SIGNATURE-----
["khtml_testregression_1.diff" (text/x-diff)]
Index: test_regression.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/test_regression.cpp,v
retrieving revision 1.60
diff -u -p -r1.60 test_regression.cpp
--- test_regression.cpp 31 Jan 2004 17:15:26 -0000 1.60
+++ test_regression.cpp 9 Feb 2004 19:36:35 -0000
@@ -24,6 +24,8 @@
#include <stdlib.h>
#include <kapplication.h>
#include <qfile.h>
+#include <setjmp.h>
+#include <signal.h>
// to be able to delete a static protected member pointer in kbrowser...
// just for memory debugging
#define protected public
@@ -86,6 +88,8 @@ using namespace KJS;
bool visual = false;
+static sigjmp_buf *cur_label = 0;
+
// -------------------------------------------------------------------------
PartMonitor::PartMonitor(KHTMLPart *_part)
@@ -329,6 +333,24 @@ Value KHTMLPartFunction::call(ExecState
return result;
}
+
+// signal handler
+static void sighandler(int sig) {
+ signal(SIGSEGV, sighandler);
+ signal(SIGILL, sighandler);
+ signal(SIGFPE, sighandler);
+ if (cur_label) {
+ signal(SIGABRT, sighandler);
+ siglongjmp(*cur_label, sig);
+ }
+
+ signal(SIGABRT, SIG_DFL);
+ const char msg[]="Signal %d occurred. Aborting\n";
+ fflush(stdout); fflush(stderr);
+ printf(msg, sig);
+ fprintf(stderr, msg, sig);
+ abort();
+}
// -------------------------------------------------------------------------
@@ -416,6 +438,11 @@ int main(int argc, char *argv[])
if ( visual )
toplevel->show();
+ signal(SIGSEGV, sighandler);
+ signal(SIGABRT, sighandler);
+ signal(SIGILL, sighandler);
+ signal(SIGFPE, sighandler);
+
// run the tests
RegressionTest *regressionTest = new RegressionTest(part,
args->arg(0),
@@ -563,6 +590,18 @@ bool RegressionTest::runTests(QString re
}
}
else if (info.isFile()) {
+ sigjmp_buf recover_label;
+ int signum = sigsetjmp(recover_label, true);
+ if (signum) {
+ cur_label = 0;
+ reportResult(false, QString("Signal %1 caught").arg(signum), true);
+ fprintf(stderr, "!!! SIGNAL %d caught while processing %s !!!\n",
+ signum, info.fileName().latin1());
+ return false;
+ }
+
+ cur_label = &recover_label;
+
khtml::Cache::init();
QString relativeDir = QFileInfo(relPath).dirPath();
@@ -579,8 +618,11 @@ bool RegressionTest::runTests(QString re
}
else if (mustExist) {
fprintf(stderr,"%s: Not a valid test file (must be .htm(l) or .js)\n",relPath.latin1());
+ cur_label = 0;
return false;
}
+
+ cur_label = 0;
} else if (mustExist) {
fprintf(stderr,"%s: Not a regular file\n",relPath.latin1());
return false;
@@ -923,12 +965,15 @@ bool RegressionTest::checkOutput(const Q
return result;
}
-bool RegressionTest::reportResult(bool passed, const QString & description)
+bool RegressionTest::reportResult(bool passed, const QString & description, bool error)
{
if (m_genOutput)
return true;
- if (passed) {
+ if (error) {
+ printf("ERROR: ");
+ m_errors++;
+ } else if (passed) {
if ( m_known_failures & AllFailure ) {
printf("PASS (unexpected!): ");
m_passes_fail++;
@@ -959,7 +1004,8 @@ bool RegressionTest::reportResult(bool p
}
printf("\n");
- return passed;
+ fflush(stdout);
+ return passed && !error;
}
void RegressionTest::createMissingDirs(QString path)
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic