File indexing completed on 2024-05-05 04:39:52

0001 /*
0002     SPDX-FileCopyrightText: 1999-2001 John Birch <jbb@kdevelop.org>
0003     SPDX-FileCopyrightText: 2001 Bernd Gehrmann <bernd@kdevelop.org>
0004     SPDX-FileCopyrightText: 2006 Vladimir Prus <ghost@cs.msu.su>
0005     SPDX-FileCopyrightText: 2007 Hamish Rodda <rodda@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "debuggerplugin.h"
0011 
0012 #include "config-gdb-plugin.h"
0013 
0014 #include "widgets/disassemblewidget.h"
0015 #include "memviewdlg.h"
0016 #include "gdboutputwidget.h"
0017 
0018 #include "gdbconfigpage.h"
0019 #include "debugsession.h"
0020 
0021 #include <execute/iexecuteplugin.h>
0022 #include <interfaces/icore.h>
0023 #include <interfaces/idebugcontroller.h>
0024 #include <interfaces/iplugincontroller.h>
0025 #include <interfaces/iruncontroller.h>
0026 #include <interfaces/iuicontroller.h>
0027 #include <interfaces/launchconfigurationtype.h>
0028 
0029 #include <KPluginFactory>
0030 
0031 // explicit init of resources needed, because all files
0032 // are first compiled into a static library which is also used for unit testing
0033 // for some reason the respective resource init methods are not triggered or registered then
0034 inline void initMyResource() { Q_INIT_RESOURCE(kdevgdb); }
0035 
0036 using namespace KDevMI::GDB;
0037 
0038 K_PLUGIN_FACTORY_WITH_JSON(CppDebuggerFactory, "kdevgdb.json", registerPlugin<CppDebuggerPlugin>(); )
0039 
0040 CppDebuggerPlugin::CppDebuggerPlugin(QObject *parent, const QVariantList &)
0041     : MIDebuggerPlugin(QStringLiteral("kdevgdb"), i18n("GDB"), parent)
0042     , disassemblefactory(nullptr)
0043     , gdbfactory(nullptr)
0044     , memoryviewerfactory(nullptr)
0045 {
0046     initMyResource();
0047 
0048     setXMLFile(QStringLiteral("kdevgdbui.rc"));
0049 
0050 
0051     auto pluginController = core()->pluginController();
0052     const auto plugins = pluginController->allPluginsForExtension(QStringLiteral("org.kdevelop.IExecutePlugin"));
0053     for (auto plugin : plugins) {
0054         setupExecutePlugin(plugin, true);
0055     }
0056 
0057     connect(pluginController, &KDevelop::IPluginController::pluginLoaded,
0058             this, [this](KDevelop::IPlugin* plugin) {
0059                 setupExecutePlugin(plugin, true);
0060             });
0061 
0062     connect(pluginController, &KDevelop::IPluginController::unloadingPlugin,
0063             this, [this](KDevelop::IPlugin* plugin) {
0064                 setupExecutePlugin(plugin, false);
0065             });
0066 }
0067 
0068 void CppDebuggerPlugin::unload()
0069 {
0070     const auto plugins = core()->pluginController()->allPluginsForExtension(QStringLiteral("org.kdevelop.IExecutePlugin"));
0071     for (auto plugin : plugins) {
0072         setupExecutePlugin(plugin, false);
0073     }
0074     Q_ASSERT(m_launchers.isEmpty());
0075 }
0076 
0077 void CppDebuggerPlugin::setupExecutePlugin(KDevelop::IPlugin* plugin, bool load)
0078 {
0079     if (plugin == this) {
0080         return;
0081     }
0082 
0083     auto iface = plugin->extension<IExecutePlugin>();
0084     if (!iface) {
0085         return;
0086     }
0087 
0088     auto type = core()->runController()->launchConfigurationTypeForId(iface->nativeAppConfigTypeId());
0089     Q_ASSERT(type);
0090 
0091     if (load) {
0092         auto launcher = new GdbLauncher(this, iface);
0093         m_launchers.insert(plugin, launcher);
0094         type->addLauncher(launcher);
0095     } else {
0096         auto launcher = m_launchers.take(plugin);
0097         Q_ASSERT(launcher);
0098 
0099         type->removeLauncher(launcher);
0100         delete launcher;
0101     }
0102 }
0103 
0104 void CppDebuggerPlugin::setupToolViews()
0105 {
0106     disassemblefactory = new DebuggerToolFactory<DisassembleWidget>(
0107     this, QStringLiteral("org.kdevelop.debugger.DisassemblerView"), Qt::BottomDockWidgetArea);
0108 
0109     gdbfactory = new DebuggerToolFactory<GDBOutputWidget, CppDebuggerPlugin>(
0110     this, QStringLiteral("org.kdevelop.debugger.ConsoleView"),Qt::BottomDockWidgetArea);
0111 
0112     core()->uiController()->addToolView(
0113         i18nc("@title:window", "Disassemble/Registers"),
0114         disassemblefactory);
0115 
0116     core()->uiController()->addToolView(
0117         i18nc("@title:window", "GDB"),
0118         gdbfactory);
0119 
0120 #ifndef KDEV_WITH_MEMVIEW
0121     memoryviewerfactory = nullptr;
0122 #else
0123     memoryviewerfactory = new DebuggerToolFactory<MemoryViewerWidget, CppDebuggerPlugin>(
0124     this, QStringLiteral("org.kdevelop.debugger.MemoryView"), Qt::BottomDockWidgetArea);
0125     core()->uiController()->addToolView(
0126         i18nc("@title:window", "Memory"),
0127         memoryviewerfactory);
0128 #endif
0129 }
0130 
0131 void CppDebuggerPlugin::unloadToolViews()
0132 {
0133     if (disassemblefactory) {
0134         core()->uiController()->removeToolView(disassemblefactory);
0135         disassemblefactory = nullptr;
0136     }
0137     if (gdbfactory) {
0138         core()->uiController()->removeToolView(gdbfactory);
0139         gdbfactory = nullptr;
0140     }
0141     if (memoryviewerfactory) {
0142         core()->uiController()->removeToolView(memoryviewerfactory);
0143         memoryviewerfactory = nullptr;
0144     }
0145 }
0146 
0147 CppDebuggerPlugin::~CppDebuggerPlugin()
0148 {
0149 }
0150 
0151 DebugSession* CppDebuggerPlugin::createSession()
0152 {
0153     auto *session = new DebugSession(this);
0154     KDevelop::ICore::self()->debugController()->addSession(session);
0155     connect(session, &DebugSession::showMessage, this, &CppDebuggerPlugin::showStatusMessage);
0156     connect(session, &DebugSession::reset, this, &CppDebuggerPlugin::reset);
0157     connect(session, &DebugSession::raiseDebuggerConsoleViews,
0158             this, &CppDebuggerPlugin::raiseDebuggerConsoleViews);
0159     return session;
0160 }
0161 
0162 #include "debuggerplugin.moc"
0163 #include "moc_debuggerplugin.cpp"