File indexing completed on 2024-04-28 16:44:13

0001 /*****************************************************************
0002  * drkonqi - The KDE Crash Handler
0003  *
0004  * SPDX-FileCopyrightText: 2000-2002 David Faure <faure@kde.org>
0005  * SPDX-FileCopyrightText: 2000-2002 Waldo Bastian <bastian@kde.org>
0006  *
0007  * SPDX-License-Identifier: BSD-2-Clause
0008  *****************************************************************/
0009 
0010 // Let's crash.
0011 #include <KAboutData>
0012 #include <KCrash>
0013 #include <QCommandLineParser>
0014 #include <QGuiApplication>
0015 #include <QtConcurrentMap>
0016 #include <assert.h>
0017 
0018 enum CrashType {
0019     Crash,
0020     Malloc,
0021     Div0,
0022     Assert,
0023     QAssert,
0024     Threads,
0025     FatalErrorMessage,
0026 };
0027 
0028 struct SomeStruct {
0029     int foo()
0030     {
0031         return ret;
0032     }
0033     int ret;
0034 };
0035 
0036 void do_crash()
0037 {
0038     SomeStruct *obj = nullptr;
0039     int ret = obj->foo();
0040     printf("result = %d\n", ret);
0041 }
0042 
0043 void do_malloc()
0044 {
0045     delete (char *)0xdead;
0046 }
0047 
0048 void do_div0()
0049 {
0050     volatile int a = 99;
0051     volatile int b = 10;
0052     volatile int c = a / (b - 10);
0053     printf("result = %d\n", c);
0054 }
0055 
0056 void do_assert()
0057 {
0058     assert(false);
0059 }
0060 
0061 void do_qassert()
0062 {
0063     Q_ASSERT(false);
0064 }
0065 
0066 void map_function(const QString &s)
0067 {
0068     while (s != QLatin1String("thread 4")) { }
0069     do_crash();
0070 }
0071 
0072 void do_threads()
0073 {
0074     QStringList foo;
0075     foo << QStringLiteral("thread 1") << QStringLiteral("thread 2") << QStringLiteral("thread 3") << QStringLiteral("thread 4") << QStringLiteral("thread 5");
0076     QThreadPool::globalInstance()->setMaxThreadCount(5);
0077     QtConcurrent::blockingMap(foo, map_function);
0078 }
0079 
0080 void do_fatalErrorMessage()
0081 {
0082     KCrash::setErrorMessage(QStringLiteral("So long, my friends..."));
0083     qFatal("So long!\n");
0084 }
0085 
0086 void level4(int t)
0087 {
0088     if (t == Malloc)
0089         do_malloc();
0090     else if (t == Div0)
0091         do_div0();
0092     else if (t == Assert)
0093         do_assert();
0094     else if (t == QAssert)
0095         do_qassert();
0096     else if (t == Threads)
0097         do_threads();
0098     else if (t == FatalErrorMessage)
0099         do_fatalErrorMessage();
0100     else
0101         do_crash();
0102 }
0103 
0104 void level3(int t)
0105 {
0106     level4(t);
0107 }
0108 
0109 void level2(int t)
0110 {
0111     level3(t);
0112 }
0113 
0114 void level1(int t)
0115 {
0116     level2(t);
0117 }
0118 
0119 int main(int argc, char *argv[])
0120 {
0121     QGuiApplication app(argc, argv);
0122     KAboutData aboutData(QStringLiteral("crashtest"),
0123                          QStringLiteral("Crash Test for DrKonqi"),
0124                          QStringLiteral("1.1"),
0125                          QStringLiteral("Crash Test for DrKonqi"),
0126                          KAboutLicense::GPL,
0127                          QStringLiteral("(c) 2000-2002 David Faure, Waldo Bastian"));
0128 
0129     QCommandLineParser parser;
0130     parser.addOption(QCommandLineOption(QStringLiteral("autorestart"), QStringLiteral("Automatically restart")));
0131     parser.addOption(QCommandLineOption(QStringLiteral("kdeinit"), QStringLiteral("Start DrKonqi using kdeinit")));
0132     parser.addPositionalArgument(QStringLiteral("type"), QStringLiteral("Type of crash."), QStringLiteral("crash|malloc|div0|assert|threads|fatal"));
0133     aboutData.setupCommandLine(&parser);
0134     parser.process(app);
0135     aboutData.processCommandLine(&parser);
0136 
0137     // Start drkonqi directly by default so that drkonqi's output goes to the console.
0138     KCrash::CrashFlags flags = KCrash::AlwaysDirectly;
0139     // This can be disabled to be able to test kcrash's real default behavior.
0140     if (parser.isSet(QStringLiteral("kdeinit")))
0141         flags &= ~KCrash::AlwaysDirectly;
0142     if (parser.isSet(QStringLiteral("autorestart")))
0143         flags |= KCrash::AutoRestart;
0144     KCrash::setFlags(flags);
0145 
0146     const QByteArray type = parser.positionalArguments().isEmpty() ? QByteArray() : parser.positionalArguments().constFirst().toUtf8();
0147     int crashtype = Crash;
0148     if (type == "malloc") {
0149         crashtype = Malloc;
0150     } else if (type == "div0") {
0151         crashtype = Div0;
0152     } else if (type == "assert") {
0153         crashtype = Assert;
0154     } else if (type == "qassert") {
0155         crashtype = QAssert;
0156     } else if (type == "threads") {
0157         crashtype = Threads;
0158     } else if (type == "fatal") {
0159         crashtype = FatalErrorMessage;
0160     }
0161     level1(crashtype);
0162     return app.exec();
0163 }