diff --git a/plugins/heaptrack/job.h b/plugins/heaptrack/job.h --- a/plugins/heaptrack/job.h +++ b/plugins/heaptrack/job.h @@ -22,10 +22,8 @@ #include #include -namespace KDevelop -{ - class ILaunchConfiguration; -} +class IExecutePlugin; +namespace KDevelop { class ILaunchConfiguration; } namespace Heaptrack { @@ -36,7 +34,7 @@ Q_INTERFACES(KDevelop::IStatus) public: - explicit Job(KDevelop::ILaunchConfiguration* launchConfig); + Job(KDevelop::ILaunchConfiguration* launchConfig, IExecutePlugin* executePlugin); explicit Job(long int pid); ~Job() override; diff --git a/plugins/heaptrack/job.cpp b/plugins/heaptrack/job.cpp --- a/plugins/heaptrack/job.cpp +++ b/plugins/heaptrack/job.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -38,36 +37,33 @@ namespace Heaptrack { -Job::Job(KDevelop::ILaunchConfiguration* launchConfig) +Job::Job(KDevelop::ILaunchConfiguration* launchConfig, IExecutePlugin* executePlugin) : m_pid(-1) { Q_ASSERT(launchConfig); + Q_ASSERT(executePlugin); - auto pluginController = KDevelop::ICore::self()->pluginController(); - auto iface = pluginController->pluginForExtension(QStringLiteral("org.kdevelop.IExecutePlugin"))->extension(); - Q_ASSERT(iface); - - QString envProfile = iface->environmentProfileName(launchConfig); + QString envProfile = executePlugin->environmentProfileName(launchConfig); if (envProfile.isEmpty()) { envProfile = KDevelop::EnvironmentProfileList(KSharedConfig::openConfig()).defaultProfileName(); } setEnvironmentProfile(envProfile); QString errorString; - m_analyzedExecutable = iface->executable(launchConfig, errorString).toLocalFile(); + m_analyzedExecutable = executePlugin->executable(launchConfig, errorString).toLocalFile(); if (!errorString.isEmpty()) { setError(-1); setErrorText(errorString); } - QStringList analyzedExecutableArguments = iface->arguments(launchConfig, errorString); + QStringList analyzedExecutableArguments = executePlugin->arguments(launchConfig, errorString); if (!errorString.isEmpty()) { setError(-1); setErrorText(errorString); } - QUrl workDir = iface->workingDirectory(launchConfig); + QUrl workDir = executePlugin->workingDirectory(launchConfig); if (workDir.isEmpty() || !workDir.isValid()) { workDir = QUrl::fromLocalFile(QFileInfo(m_analyzedExecutable).absolutePath()); } diff --git a/plugins/heaptrack/kdevheaptrack.json b/plugins/heaptrack/kdevheaptrack.json --- a/plugins/heaptrack/kdevheaptrack.json +++ b/plugins/heaptrack/kdevheaptrack.json @@ -78,7 +78,7 @@ }, "X-KDevelop-Category": "Global", "X-KDevelop-IRequired": [ - "org.kdevelop.IExecutePlugin" + "org.kdevelop.IExecutePlugin@kdevexecute" ], "X-KDevelop-Mode": "GUI" } diff --git a/plugins/heaptrack/plugin.cpp b/plugins/heaptrack/plugin.cpp --- a/plugins/heaptrack/plugin.cpp +++ b/plugins/heaptrack/plugin.cpp @@ -33,15 +33,18 @@ #include #include +#include #include #include #include #include #include +#include #include #include +#include #include K_PLUGIN_FACTORY_WITH_JSON(HeaptrackFactory, "kdevheaptrack.json", registerPlugin();) @@ -79,25 +82,43 @@ void Plugin::launchHeaptrack() { - auto runController = KDevelop::Core::self()->runControllerInternal(); - if (runController->launchConfigurations().isEmpty()) { - runController->showConfigurationDialog(); + IExecutePlugin* executePlugin = nullptr; + + // First we should check that our "kdevexecute" plugin is loaded. This is needed since + // current plugin controller logic allows us to unload this plugin with keeping dependent + // plugins like Heaptrack in "loaded" state. This seems to be wrong behaviour but now we have + // to do additional checks. + // TODO fix plugin controller to avoid such inconsistent states. + auto pluginController = core()->pluginController(); + if (auto plugin = pluginController->pluginForExtension( + QStringLiteral("org.kdevelop.IExecutePlugin"), QStringLiteral("kdevexecute"))) { + executePlugin = plugin->extension(); + } else { + auto pluginInfo = pluginController->infoForPluginId(QStringLiteral("kdevexecute")); + KMessageBox::error( + qApp->activeWindow(), + i18n("Unable to start Heaptrack analysis - \"%1\" plugin is not loaded.", pluginInfo.name())); + return; } + auto runController = KDevelop::Core::self()->runControllerInternal(); auto defaultLaunch = runController->defaultLaunch(); if (!defaultLaunch) { - return; + runController->showConfigurationDialog(); } - auto pluginController = core()->self()->pluginController(); - auto iface = pluginController->pluginForExtension(QStringLiteral("org.kdevelop.IExecutePlugin"))->extension(); - Q_ASSERT(iface); + if (!defaultLaunch->type()->launcherForId(QStringLiteral("nativeAppLauncher"))) { + KMessageBox::error( + qApp->activeWindow(), + i18n("Heaptrack analysis can be started only for native applications.")); + return; + } - auto heaptrackJob = new Job(defaultLaunch); + auto heaptrackJob = new Job(defaultLaunch, executePlugin); connect(heaptrackJob, &Job::finished, this, &Plugin::jobFinished); QList jobList; - if (KJob* depJob = iface->dependencyJob(defaultLaunch)) { + if (KJob* depJob = executePlugin->dependencyJob(defaultLaunch)) { jobList += depJob; } jobList += heaptrackJob;