File indexing completed on 2024-04-14 15:32:42

0001 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0002 // SPDX-FileCopyrightText: 2020-2022 Harald Sitter <sitter@kde.org>
0003 
0004 #include "Patient.h"
0005 
0006 #include <QDebug>
0007 #include <QFileInfo>
0008 #include <QProcess>
0009 
0010 #include <KShell>
0011 #include <KTerminalLauncherJob>
0012 
0013 #include "../coredump/coredump.h"
0014 #include <KApplicationTrader>
0015 
0016 Patient::Patient(const Coredump &dump)
0017     : m_signal(dump.m_rawData["COREDUMP_SIGNAL"].toInt())
0018     , m_appName(QFileInfo(dump.exe).fileName())
0019     , m_pid(dump.pid)
0020     , m_canDebug(QFileInfo::exists(QString::fromUtf8(dump.m_rawData.value("COREDUMP_FILENAME"))))
0021     , m_timestamp(dump.m_rawData["COREDUMP_TIMESTAMP"].toLong())
0022     , m_coredumpExe(dump.m_rawData["COREDUMP_EXE"])
0023     , m_coredumpCom(dump.m_rawData["COREDUMP_COMM"])
0024 {
0025 }
0026 
0027 QStringList Patient::coredumpctlArguments(const QString &command) const
0028 {
0029     return {command, QString::number(m_pid), QString::fromUtf8(m_coredumpExe), QString::fromUtf8(m_coredumpCom)};
0030 }
0031 
0032 void Patient::debug() const
0033 {
0034     const QString arguments = KShell::joinArgs(coredumpctlArguments(QStringLiteral("debug")));
0035     auto job = new KTerminalLauncherJob(QStringLiteral("coredumpctl %1").arg(arguments));
0036     connect(job, &KJob::result, this, [job] {
0037         job->deleteLater();
0038         if (job->error() != KJob::NoError) {
0039             qWarning() << job->errorText();
0040         }
0041     });
0042     job->start();
0043 }
0044 
0045 QString Patient::dateTime() const
0046 {
0047     QDateTime time;
0048     time.setMSecsSinceEpoch(m_timestamp / 1000);
0049     return time.toString();
0050 }
0051 
0052 QString Patient::iconName() const
0053 {
0054     // Caching it because it's an N² look-up and there generally are tons of duplicates
0055     static QHash<QString, QString> s_cache;
0056     const QString executable = m_appName;
0057     auto it = s_cache.find(executable);
0058     if (it == s_cache.end()) {
0059         const auto servicesFound = KApplicationTrader::query([&executable](const KService::Ptr &service) {
0060             return QFileInfo(service->exec()).fileName() == executable;
0061         });
0062 
0063         QString iconName;
0064         if (servicesFound.isEmpty()) {
0065             iconName = QStringLiteral("applications-science");
0066         } else {
0067             iconName = servicesFound.constFirst()->icon();
0068         }
0069         it = s_cache.insert(executable, iconName);
0070     }
0071     return *it;
0072 }