diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,10 +1,13 @@ - set(kcrash_SRCS kcrash.cpp coreconfig.cpp + kcrashhandlerplugin.cpp + ${kcrash_QM_LOADER} ) +set(KCRASH_PLUGIN_INSTALL_DIR ${PLUGIN_INSTALL_DIR}/kcrashhandlers) + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/config-kcrash.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kcrash.h @@ -17,7 +20,6 @@ target_include_directories(KF5Crash INTERFACE "$") target_link_libraries(KF5Crash PUBLIC Qt5::Core) -target_link_libraries(KF5Crash PRIVATE KF5::CoreAddons KF5::WindowSystem) if(${X11_FOUND}) @@ -49,3 +51,5 @@ include(ECMGeneratePriFile) ecm_generate_pri_file(BASE_NAME KCrash LIB_NAME KF5Crash DEPS "core" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/KCrash) install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) + +add_subdirectory(plugins) diff --git a/src/config-kcrash.h.cmake b/src/config-kcrash.h.cmake --- a/src/config-kcrash.h.cmake +++ b/src/config-kcrash.h.cmake @@ -3,3 +3,5 @@ #define kde_socklen_t socklen_t #define CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_FULL_LIBEXECDIR}" + +#cmakedefine KCRASH_PLUGIN_INSTALL_DIR "${KCRASH_PLUGIN_INSTALL_DIR}" diff --git a/src/kcrash.cpp b/src/kcrash.cpp --- a/src/kcrash.cpp +++ b/src/kcrash.cpp @@ -23,6 +23,7 @@ */ #include "kcrash.h" +#include "kcrashhandlerplugin.h" #include @@ -43,14 +44,13 @@ #include #endif -#include -#include - #include #include #include #include #include +#include +#include #include #include @@ -434,98 +434,61 @@ return; } - const char *argv[29]; // don't forget to update this - int i = 0; - - // argument 0 has to be drkonqi - argv[i++] = s_drkonqiPath; + QVarLengthArray argv; + argv << s_drkonqiPath; const QByteArray platformName = QGuiApplication::platformName().toUtf8(); if (!platformName.isEmpty()) { - argv[i++] = "-platform"; - argv[i++] = platformName.constData(); - } - -#if HAVE_X11 - if (platformName == QByteArrayLiteral("xcb")) { - // start up on the correct display - argv[i++] = "-display"; - if (QX11Info::display()) { - argv[i++] = XDisplayString(QX11Info::display()); - } else { - argv[i++] = getenv("DISPLAY"); - } + argv << "-platform" << platformName.constData(); } -#endif - argv[i++] = "--appname"; - argv[i++] = s_appName ? s_appName : ""; + argv << "--appname" << (s_appName ? s_appName : ""); if (loadedByKdeinit) { - argv[i++] = "--kdeinit"; + argv << "--kdeinit"; } // only add apppath if it's not NULL if (s_appPath && *s_appPath) { - argv[i++] = "--apppath"; - argv[i++] = s_appPath; + argv << "--apppath" << s_appPath; } // signal number -- will never be NULL char sigtxt[ 10 ]; sprintf(sigtxt, "%d", sig); - argv[i++] = "--signal"; - argv[i++] = sigtxt; + argv << "--signal" << sigtxt; char pidtxt[ 20 ]; sprintf(pidtxt, "%lld", QCoreApplication::applicationPid()); - argv[i++] = "--pid"; - argv[i++] = pidtxt; - - const KAboutData *about = KAboutData::applicationDataPointer(); - if (about) { - if (about->internalVersion()) { - argv[i++] = "--appversion"; - argv[i++] = about->internalVersion(); - } - - if (about->internalProgramName()) { - argv[i++] = "--programname"; - argv[i++] = about->internalProgramName(); - } - - if (about->internalBugAddress()) { - argv[i++] = "--bugaddress"; - argv[i++] = about->internalBugAddress(); - } - } - - // make sure the constData() pointer remains valid when we call startProcess by making a copy - QByteArray startupId = KStartupInfo::startupId(); - if (!startupId.isNull()) { - argv[i++] = "--startupid"; - argv[i++] = startupId.constData(); + argv << "--pid" << pidtxt; + + QDirIterator dirIt(QStringLiteral(KCRASH_PLUGIN_INSTALL_DIR), QDir::Files); + QMap args; + for (; dirIt.hasNext();) { + dirIt.next(); + QPluginLoader loader(dirIt.filePath()); + KCrashHandlerPlugin *plugin = qobject_cast(loader.instance()); + plugin->extractHandlerArgs(argv); } if (s_flags & SaferDialog) { - argv[i++] = "--safer"; + argv << "--safer"; } if ((s_flags & AutoRestart) && s_autoRestartCommand) { - argv[i++] = "--restarted"; //tell drkonqi if the app has been restarted + argv << "--restarted"; //tell drkonqi if the app has been restarted } #if defined(Q_OS_WIN) char threadId[8] = { 0 }; sprintf(threadId, "%d", GetCurrentThreadId()); - argv[i++] = "--thread"; - argv[i++] = threadId; + argv << "--thread" << threadId; #endif // NULL terminated list - argv[i] = nullptr; + argv << nullptr; - startProcess(i, argv, true); + startProcess(argv.size()-1, argv.data(), true); } if (crashRecursionCounter < 4) { diff --git a/src/kcrashhandlerplugin.h b/src/kcrashhandlerplugin.h new file mode 100644 --- /dev/null +++ b/src/kcrashhandlerplugin.h @@ -0,0 +1,39 @@ +/* + * This file is part of the KDE Libraries + * Copyright (C) 2017 Aleix Pol Gonzalez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef KCRASHHANDLERPLUGIN_H +#define KCRASHHANDLERPLUGIN_H + +#include +#include +#include "kcrash_export.h" + +class KCRASH_EXPORT KCrashHandlerPlugin : public QObject +{ +Q_OBJECT +public: + KCrashHandlerPlugin(QObject* parent = nullptr); + + virtual void extractHandlerArgs(QVarLengthArray& args) = 0; +}; + +Q_DECLARE_INTERFACE( KCrashHandlerPlugin, "org.kde.KCrashHandlerPlugin" ) + +#endif diff --git a/src/kcrashhandlerplugin.cpp b/src/kcrashhandlerplugin.cpp new file mode 100644 --- /dev/null +++ b/src/kcrashhandlerplugin.cpp @@ -0,0 +1,26 @@ +/* + * This file is part of the KDE Libraries + * Copyright (C) 2017 Aleix Pol Gonzalez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kcrashhandlerplugin.h" + +KCrashHandlerPlugin::KCrashHandlerPlugin(QObject* parent) + : QObject(parent) +{ +} diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/src/plugins/CMakeLists.txt @@ -0,0 +1,13 @@ +add_library(KCoreAddonsCrashHandler MODULE kcoreaddonsplugin.cpp) +target_link_libraries(KCoreAddonsCrashHandler PRIVATE KF5::Crash KF5::CoreAddons) +install(TARGETS KCoreAddonsCrashHandler DESTINATION ${KCRASH_PLUGIN_INSTALL_DIR}) + +add_library(KStartupidCrashHandler MODULE kstartupinfoplugin.cpp) +target_link_libraries(KStartupidCrashHandler PRIVATE KF5::Crash KF5::WindowSystem) +install(TARGETS KStartupidCrashHandler DESTINATION ${KCRASH_PLUGIN_INSTALL_DIR}) + +if(HAVE_X11) + add_library(XCBCrashHandler MODULE xcbplugin.cpp) + target_link_libraries(XCBCrashHandler PRIVATE KF5::Crash Qt5::X11Extras ${X11_LIBRARIES}) + install(TARGETS XCBCrashHandler DESTINATION ${KCRASH_PLUGIN_INSTALL_DIR}) +endif() diff --git a/src/plugins/kcoreaddonsplugin.cpp b/src/plugins/kcoreaddonsplugin.cpp new file mode 100644 --- /dev/null +++ b/src/plugins/kcoreaddonsplugin.cpp @@ -0,0 +1,48 @@ +/* + * This file is part of the KDE Libraries + * Copyright (C) 2017 Aleix Pol Gonzalez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kcrashhandlerplugin.h" +#include + +class KCoreAddonsPlugin : public KCrashHandlerPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kde.KCrashHandlerPlugin") + Q_INTERFACES(KCrashHandlerPlugin) + + void extractHandlerArgs(QVarLengthArray& args) override { + const KAboutData *about = KAboutData::applicationDataPointer(); + if (about) { + if (about->internalVersion()) { + args << "--appversion" << about->internalVersion(); + } + + if (about->internalProgramName()) { + args << "--programname" << about->internalProgramName(); + } + + if (about->internalBugAddress()) { + args << "--bugaddress" << about->internalBugAddress(); + } + } + } +}; + +#include "kcoreaddonsplugin.moc" diff --git a/src/plugins/kstartupinfoplugin.cpp b/src/plugins/kstartupinfoplugin.cpp new file mode 100644 --- /dev/null +++ b/src/plugins/kstartupinfoplugin.cpp @@ -0,0 +1,39 @@ +/* + * This file is part of the KDE Libraries + * Copyright (C) 2017 Aleix Pol Gonzalez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kcrashhandlerplugin.h" +#include + +class KCoreAddonsPlugin : public KCrashHandlerPlugin +{ + Q_OBJECT\ + Q_PLUGIN_METADATA(IID "org.kde.KCrashHandlerPlugin") + Q_INTERFACES(KCrashHandlerPlugin) + + void extractHandlerArgs(QVarLengthArray& args) override { + // make sure the constData() pointer remains valid when we call startProcess by making a copy + QByteArray startupId = KStartupInfo::startupId(); + if (!startupId.isNull()) { + args << "--startupid" << startupId.constData(); + } + } +}; + +#include "kstartupinfoplugin.moc" diff --git a/src/plugins/xcbplugin.cpp b/src/plugins/xcbplugin.cpp new file mode 100644 --- /dev/null +++ b/src/plugins/xcbplugin.cpp @@ -0,0 +1,52 @@ +/* + * This file is part of the KDE Libraries + * Copyright (C) 2017 Aleix Pol Gonzalez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kcrashhandlerplugin.h" +#include +#include + +class XCBPlugin : public KCrashHandlerPlugin +{ + Q_OBJECT\ + Q_PLUGIN_METADATA(IID "org.kde.KCrashHandlerPlugin") + Q_INTERFACES(KCrashHandlerPlugin) + + void extractHandlerArgs(QVarLengthArray& args) override; +}; + +#include "xcbplugin.moc" + +#include //This messes around with Bool and breaks compilation if not included after moc + +void XCBPlugin::extractHandlerArgs(QVarLengthArray& args) +{ + const QString platformName = QGuiApplication::platformName(); + + if (platformName == QLatin1String("xcb")) { + // start up on the correct display + args << "-display"; + if (QX11Info::display()) { + args << XDisplayString(QX11Info::display()); + } else { + args << getenv("DISPLAY"); + } + } +} +