File indexing completed on 2025-02-16 04:37:46

0001 /*
0002     SPDX-FileCopyrightText: 2010 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include <QObject>
0008 #include <QTemporaryFile>
0009 #include <QtTest>
0010 #include <ctime>
0011 #include <setjmp.h>
0012 #include <signal.h>
0013 #include <sys/mman.h>
0014 #include <sys/types.h>
0015 #include <unistd.h>
0016 #include <util/fileops.h>
0017 #include <util/log.h>
0018 #include <util/signalcatcher.h>
0019 
0020 using namespace bt;
0021 
0022 /*
0023 static sigjmp_buf sj_env;
0024 
0025 static void signal_handler(int sig, siginfo_t *siginfo, void *ptr)
0026 {
0027     Q_UNUSED(siginfo);
0028     Q_UNUSED(ptr);
0029     Q_UNUSED(sig);
0030     // Jump to error handling code
0031     siglongjmp(sj_env, 1);
0032 }
0033 
0034 bool TestSigBusHandling()
0035 {
0036     struct sigaction act;
0037 
0038     memset(&act, 0, sizeof(act));
0039     act.sa_sigaction = signal_handler;
0040     act.sa_flags = SA_SIGINFO;
0041 
0042     if (sigaction(SIGBUS, &act, 0) == -1)
0043         return false;
0044 
0045     if (sigsetjmp(sj_env, 1))
0046     {
0047         return true;
0048     }
0049 
0050     kill(getpid(), SIGBUS);
0051     return false;
0052 }
0053 */
0054 
0055 class SignalCatcherTest : public QObject
0056 {
0057     Q_OBJECT
0058 private Q_SLOTS:
0059     void initTestCase()
0060     {
0061         bt::InitLog("signalcatchertest.log");
0062     }
0063 
0064     void cleanupTestCase()
0065     {
0066     }
0067 
0068     void testBus()
0069     {
0070         try {
0071             BUS_ERROR_WPROTECT();
0072             kill(getpid(), SIGBUS);
0073             QFAIL("Didn't catch SIGBUS");
0074         } catch (bt::BusError &e) {
0075             Out(SYS_GEN | LOG_DEBUG) << QString("Caught signal: %1").arg(e.toString()) << endl;
0076         } catch (...) {
0077             QFAIL("Didn't catch SIGBUS");
0078         }
0079     }
0080 
0081     void testMMap()
0082     {
0083         QTemporaryFile tmp;
0084         QVERIFY(tmp.open());
0085         int fd = tmp.handle();
0086         try {
0087             TruncateFile(fd, 4096, true);
0088         } catch (bt::Error &err) {
0089             QString msg = QString("Exception thrown: %s").arg(err.toString());
0090             QFAIL(msg.toLocal8Bit().constData());
0091         }
0092 
0093         char *ptr = (char *)mmap(nullptr, 4096, PROT_WRITE, MAP_SHARED, fd, 0);
0094         QVERIFY(ptr);
0095 
0096         // First try a write which should not fail
0097         try {
0098             BUS_ERROR_WPROTECT();
0099             memcpy(ptr, "Testing", 7);
0100         } catch (bt::BusError &e) {
0101             QString msg = QString("Caught signal: %s").arg(e.toString());
0102             QFAIL(msg.toLocal8Bit().constData());
0103         }
0104 
0105         // Lets try one which should fail
0106         try {
0107             BUS_ERROR_WPROTECT();
0108             TruncateFile(fd, 0, true);
0109             memcpy(ptr, "Testing", 7);
0110             QFAIL("Didn't catch SIGBUS");
0111         } catch (bt::BusError &e) {
0112             Out(SYS_GEN | LOG_DEBUG) << QString("Caught signal: %1").arg(e.toString()) << endl;
0113         }
0114     }
0115 };
0116 
0117 QTEST_MAIN(SignalCatcherTest)
0118 
0119 #include "signalcatchertest.moc"