Warning, file /plasma/drkonqi/src/crashedapplication.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2009 George Kiagiadakis <gkiagia@users.sourceforge.net> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <config-drkonqi.h> 0008 0009 #include "crashedapplication.h" 0010 0011 #if HAVE_STRSIGNAL && defined(Q_OS_UNIX) 0012 #include <clocale> 0013 #include <cstdlib> 0014 #include <cstring> 0015 #else 0016 #if defined(Q_OS_UNIX) 0017 #include <signal.h> 0018 #else 0019 #include <windows.h> 0020 #endif 0021 #endif 0022 0023 #include <KIO/CommandLauncherJob> 0024 0025 CrashedApplication::CrashedApplication(int pid, 0026 int thread, 0027 int signalNumber, 0028 const QFileInfo &executable, 0029 const QString &version, 0030 const BugReportAddress &reportAddress, 0031 const QString &name, 0032 const QString &productName, 0033 const QDateTime &datetime, 0034 bool restarted, 0035 bool hasDeletedFiles, 0036 const QString &fakeBaseName, 0037 QObject *parent) 0038 0039 : QObject(parent) 0040 , m_pid(pid) 0041 , m_signalNumber(signalNumber) 0042 , m_name(name) 0043 , m_executable(executable) 0044 , m_fakeBaseName(fakeBaseName) 0045 , m_version(version) 0046 , m_reportAddress(reportAddress) 0047 , m_productName(productName) 0048 , m_restarted(restarted) 0049 , m_thread(thread) 0050 , m_datetime(datetime) 0051 , m_hasDeletedFiles(hasDeletedFiles) 0052 0053 { 0054 } 0055 0056 CrashedApplication::~CrashedApplication() = default; 0057 0058 QString CrashedApplication::name() const 0059 { 0060 return m_name.isEmpty() ? fakeExecutableBaseName() : m_name; 0061 } 0062 0063 QFileInfo CrashedApplication::executable() const 0064 { 0065 return m_executable; 0066 } 0067 0068 QString CrashedApplication::fakeExecutableBaseName() const 0069 { 0070 if (!m_fakeBaseName.isEmpty()) { 0071 return m_fakeBaseName; 0072 } else { 0073 return m_executable.baseName(); 0074 } 0075 } 0076 0077 QString CrashedApplication::version() const 0078 { 0079 return m_version; 0080 } 0081 0082 BugReportAddress CrashedApplication::bugReportAddress() const 0083 { 0084 return m_reportAddress; 0085 } 0086 0087 QString CrashedApplication::productName() const 0088 { 0089 return m_productName; 0090 } 0091 0092 int CrashedApplication::pid() const 0093 { 0094 return m_pid; 0095 } 0096 0097 int CrashedApplication::signalNumber() const 0098 { 0099 return m_signalNumber; 0100 } 0101 0102 QString CrashedApplication::signalName() const 0103 { 0104 #if HAVE_STRSIGNAL && defined(Q_OS_UNIX) 0105 const QByteArray originalLocale(std::setlocale(LC_MESSAGES, nullptr)); 0106 std::setlocale(LC_MESSAGES, "C"); 0107 const char *name = strsignal(m_signalNumber); 0108 std::setlocale(LC_MESSAGES, originalLocale.data() /* empty string if we got a nullptr */); 0109 return QString::fromLocal8Bit(name ? name : "Unknown"); 0110 #else 0111 switch (m_signalNumber) { 0112 #if defined(Q_OS_UNIX) 0113 case SIGILL: 0114 return QLatin1String("SIGILL"); 0115 case SIGABRT: 0116 return QLatin1String("SIGABRT"); 0117 case SIGFPE: 0118 return QLatin1String("SIGFPE"); 0119 case SIGSEGV: 0120 return QLatin1String("SIGSEGV"); 0121 case SIGBUS: 0122 return QLatin1String("SIGBUS"); 0123 #else 0124 case EXCEPTION_ACCESS_VIOLATION: 0125 return QLatin1String("EXCEPTION_ACCESS_VIOLATION"); 0126 case EXCEPTION_DATATYPE_MISALIGNMENT: 0127 return QLatin1String("EXCEPTION_DATATYPE_MISALIGNMENT"); 0128 case EXCEPTION_BREAKPOINT: 0129 return QLatin1String("EXCEPTION_BREAKPOINT"); 0130 case EXCEPTION_SINGLE_STEP: 0131 return QLatin1String("EXCEPTION_SINGLE_STEP"); 0132 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: 0133 return QLatin1String("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"); 0134 case EXCEPTION_FLT_DENORMAL_OPERAND: 0135 return QLatin1String("EXCEPTION_FLT_DENORMAL_OPERAND"); 0136 case EXCEPTION_FLT_DIVIDE_BY_ZERO: 0137 return QLatin1String("EXCEPTION_FLT_DIVIDE_BY_ZERO"); 0138 case EXCEPTION_FLT_INEXACT_RESULT: 0139 return QLatin1String("EXCEPTION_FLT_INEXACT_RESULT"); 0140 case EXCEPTION_FLT_INVALID_OPERATION: 0141 return QLatin1String("EXCEPTION_FLT_INVALID_OPERATION"); 0142 case EXCEPTION_FLT_OVERFLOW: 0143 return QLatin1String("EXCEPTION_FLT_OVERFLOW"); 0144 case EXCEPTION_FLT_STACK_CHECK: 0145 return QLatin1String("EXCEPTION_FLT_STACK_CHECK"); 0146 case EXCEPTION_FLT_UNDERFLOW: 0147 return QLatin1String("EXCEPTION_FLT_UNDERFLOW"); 0148 case EXCEPTION_INT_DIVIDE_BY_ZERO: 0149 return QLatin1String("EXCEPTION_INT_DIVIDE_BY_ZERO"); 0150 case EXCEPTION_INT_OVERFLOW: 0151 return QLatin1String("EXCEPTION_INT_OVERFLOW"); 0152 case EXCEPTION_PRIV_INSTRUCTION: 0153 return QLatin1String("EXCEPTION_PRIV_INSTRUCTION"); 0154 case EXCEPTION_IN_PAGE_ERROR: 0155 return QLatin1String("EXCEPTION_IN_PAGE_ERROR"); 0156 case EXCEPTION_ILLEGAL_INSTRUCTION: 0157 return QLatin1String("EXCEPTION_ILLEGAL_INSTRUCTION"); 0158 case EXCEPTION_NONCONTINUABLE_EXCEPTION: 0159 return QLatin1String("EXCEPTION_NONCONTINUABLE_EXCEPTION"); 0160 case EXCEPTION_STACK_OVERFLOW: 0161 return QLatin1String("EXCEPTION_STACK_OVERFLOW"); 0162 case EXCEPTION_INVALID_DISPOSITION: 0163 return QLatin1String("EXCEPTION_INVALID_DISPOSITION"); 0164 #endif 0165 default: 0166 return QLatin1String("Unknown"); 0167 } 0168 #endif 0169 } 0170 0171 bool CrashedApplication::hasBeenRestarted() const 0172 { 0173 return m_restarted; 0174 } 0175 0176 int CrashedApplication::thread() const 0177 { 0178 return m_thread; 0179 } 0180 0181 const QDateTime &CrashedApplication::datetime() const 0182 { 0183 return m_datetime; 0184 } 0185 0186 bool CrashedApplication::hasDeletedFiles() const 0187 { 0188 return m_hasDeletedFiles; 0189 } 0190 0191 void CrashedApplication::restart() 0192 { 0193 if (m_restarted) { 0194 return; 0195 } 0196 0197 // start the application via CommandLauncherJob so it runs in a new cgroup if possible. 0198 // if m_fakeBaseName is set, this means m_executable is the path to kdeinit4 0199 // so we need to use the fakeBaseName to restart the app 0200 auto job = new KIO::CommandLauncherJob(!m_fakeBaseName.isEmpty() ? m_fakeBaseName : m_executable.absoluteFilePath()); 0201 if (const QString &id = DrKonqi::startupId(); !id.isEmpty()) { 0202 job->setStartupId(id.toUtf8()); 0203 } 0204 connect(job, &KIO::CommandLauncherJob::result, this, [job, this] { 0205 m_restarted = (job->error() == KJob::NoError); 0206 Q_EMIT restarted(m_restarted); 0207 }); 0208 job->start(); 0209 } 0210 0211 QString getSuggestedKCrashFilename(const CrashedApplication *app) 0212 { 0213 QString filename = 0214 app->fakeExecutableBaseName() + QLatin1Char('-') + app->datetime().toString(QStringLiteral("yyyyMMdd-hhmmss")) + QStringLiteral(".kcrash"); 0215 0216 if (filename.contains(QLatin1Char('/'))) { 0217 filename = filename.mid(filename.lastIndexOf(QLatin1Char('/')) + 1); 0218 } 0219 0220 return filename; 0221 }