Commit 68426717 authored by Jarek Kobus's avatar Jarek Kobus

Properly delete plugins dependent on failed plugin

Init all class member pointers to NULL.
This fixes possible crash on exit when dependent
plugin was not loaded (e.g. TextEditor was missing).
In this case plugin's constructor gets called,
initialize() method is _not_ called
and destructor gets called -> crash.

Properly delete dependent plugins on
a plugin which failed to initialize properly.

Fix labels of deleted plugins inside an error dialog
after pressing "Error Details" from "Installed Plugins"
dialog.

Change-Id: Iddc029a0f07dcba2501d734d142fb0e69e9383d3
Reviewed-by: default avatarEike Ziller <eike.ziller@theqtcompany.com>
parent 8131aea4
...@@ -1222,8 +1222,12 @@ void PluginManagerPrivate::loadPlugins() ...@@ -1222,8 +1222,12 @@ void PluginManagerPrivate::loadPlugins()
while (it.hasPrevious()) { while (it.hasPrevious()) {
PluginSpec *spec = it.previous(); PluginSpec *spec = it.previous();
loadPlugin(spec, PluginSpec::Running); loadPlugin(spec, PluginSpec::Running);
if (spec->state() == PluginSpec::Running) if (spec->state() == PluginSpec::Running) {
delayedInitializeQueue.append(spec); delayedInitializeQueue.append(spec);
} else {
// Plugin initialization failed, so cleanup after it
spec->d->kill();
}
} }
emit q->pluginsChanged(); emit q->pluginsChanged();
...@@ -1246,8 +1250,12 @@ void PluginManagerPrivate::shutdown() ...@@ -1246,8 +1250,12 @@ void PluginManagerPrivate::shutdown()
shutdownEventLoop->exec(); shutdownEventLoop->exec();
} }
deleteAll(); deleteAll();
if (!allObjects.isEmpty()) if (!allObjects.isEmpty()) {
qDebug() << "There are" << allObjects.size() << "objects left in the plugin manager pool: " << allObjects; qDebug() << "There are" << allObjects.size() << "objects left in the plugin manager pool.";
// Intentionally split debug info here, since in case the list contains
// already deleted object we get at least the info about the number of objects;
qDebug() << "The following objects left in the plugin manager pool:" << allObjects;
}
} }
/*! /*!
......
...@@ -983,9 +983,6 @@ bool PluginSpecPrivate::initializePlugin() ...@@ -983,9 +983,6 @@ bool PluginSpecPrivate::initializePlugin()
if (!plugin->initialize(arguments, &err)) { if (!plugin->initialize(arguments, &err)) {
errorString = QCoreApplication::translate("PluginSpec", "Plugin initialization failed: %1").arg(err); errorString = QCoreApplication::translate("PluginSpec", "Plugin initialization failed: %1").arg(err);
hasError = true; hasError = true;
// clean up
loader.unload();
plugin = 0;
return false; return false;
} }
state = PluginSpec::Initialized; state = PluginSpec::Initialized;
......
...@@ -93,7 +93,6 @@ CppToolsPlugin::CppToolsPlugin() ...@@ -93,7 +93,6 @@ CppToolsPlugin::CppToolsPlugin()
CppToolsPlugin::~CppToolsPlugin() CppToolsPlugin::~CppToolsPlugin()
{ {
m_instance = 0; m_instance = 0;
delete CppModelManager::instance();
} }
CppToolsPlugin *CppToolsPlugin::instance() CppToolsPlugin *CppToolsPlugin::instance()
...@@ -141,6 +140,8 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error) ...@@ -141,6 +140,8 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
Q_UNUSED(arguments) Q_UNUSED(arguments)
Q_UNUSED(error) Q_UNUSED(error)
CppModelManager::instance()->setParent(this);
m_settings = new CppToolsSettings(this); // force registration of cpp tools settings m_settings = new CppToolsSettings(this); // force registration of cpp tools settings
// Objects // Objects
......
...@@ -167,7 +167,7 @@ private: ...@@ -167,7 +167,7 @@ private:
inline CvsControl *cvsVersionControl() const; inline CvsControl *cvsVersionControl() const;
CvsSettings m_settings; CvsSettings m_settings;
CvsClient *m_client; CvsClient *m_client = nullptr;
QString m_commitMessageFileName; QString m_commitMessageFileName;
QString m_commitRepository; QString m_commitRepository;
......
...@@ -3244,7 +3244,6 @@ QSharedPointer<Internal::GlobalDebuggerOptions> globalDebuggerOptions() ...@@ -3244,7 +3244,6 @@ QSharedPointer<Internal::GlobalDebuggerOptions> globalDebuggerOptions()
DebuggerPlugin::DebuggerPlugin() DebuggerPlugin::DebuggerPlugin()
{ {
setObjectName(QLatin1String("DebuggerPlugin")); setObjectName(QLatin1String("DebuggerPlugin"));
addObject(this);
dd = new DebuggerPluginPrivate(this); dd = new DebuggerPluginPrivate(this);
} }
...@@ -3256,6 +3255,7 @@ DebuggerPlugin::~DebuggerPlugin() ...@@ -3256,6 +3255,7 @@ DebuggerPlugin::~DebuggerPlugin()
bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMessage) bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{ {
addObject(this);
// Menu groups // Menu groups
ActionContainer *mstart = ActionManager::actionContainer(PE::M_DEBUG_STARTDEBUGGING); ActionContainer *mstart = ActionManager::actionContainer(PE::M_DEBUG_STARTDEBUGGING);
mstart->appendGroup(Constants::G_GENERAL); mstart->appendGroup(Constants::G_GENERAL);
......
...@@ -1127,7 +1127,7 @@ private: ...@@ -1127,7 +1127,7 @@ private:
StatusBarWidget *m_statusBar; StatusBarWidget *m_statusBar;
// @TODO: Delete // @TODO: Delete
//WordCompletion *m_wordCompletion; //WordCompletion *m_wordCompletion;
FakeVimCompletionAssistProvider *m_wordProvider; FakeVimCompletionAssistProvider *m_wordProvider = nullptr;
}; };
QVariant FakeVimUserCommandsModel::data(const QModelIndex &index, int role) const QVariant FakeVimUserCommandsModel::data(const QModelIndex &index, int role) const
...@@ -1184,6 +1184,18 @@ FakeVimPluginPrivate::FakeVimPluginPrivate(FakeVimPlugin *plugin) ...@@ -1184,6 +1184,18 @@ FakeVimPluginPrivate::FakeVimPluginPrivate(FakeVimPlugin *plugin)
} }
FakeVimPluginPrivate::~FakeVimPluginPrivate() FakeVimPluginPrivate::~FakeVimPluginPrivate()
{
theFakeVimSettings()->deleteLater();
}
void FakeVimPluginPrivate::onCoreAboutToClose()
{
// Don't attach to editors anymore.
disconnect(EditorManager::instance(), &EditorManager::editorOpened,
this, &FakeVimPluginPrivate::editorOpened);
}
void FakeVimPluginPrivate::aboutToShutdown()
{ {
q->removeObject(m_fakeVimOptionsPage); q->removeObject(m_fakeVimOptionsPage);
delete m_fakeVimOptionsPage; delete m_fakeVimOptionsPage;
...@@ -1199,19 +1211,6 @@ FakeVimPluginPrivate::~FakeVimPluginPrivate() ...@@ -1199,19 +1211,6 @@ FakeVimPluginPrivate::~FakeVimPluginPrivate()
delete m_wordProvider; delete m_wordProvider;
m_wordProvider = 0; m_wordProvider = 0;
theFakeVimSettings()->deleteLater();
}
void FakeVimPluginPrivate::onCoreAboutToClose()
{
// Don't attach to editors anymore.
disconnect(EditorManager::instance(), &EditorManager::editorOpened,
this, &FakeVimPluginPrivate::editorOpened);
}
void FakeVimPluginPrivate::aboutToShutdown()
{
} }
bool FakeVimPluginPrivate::initialize() bool FakeVimPluginPrivate::initialize()
......
...@@ -356,7 +356,7 @@ public: ...@@ -356,7 +356,7 @@ public:
QString m_projectFilterString; QString m_projectFilterString;
MiniProjectTargetSelector * m_targetSelector; MiniProjectTargetSelector * m_targetSelector;
ProjectExplorerSettings m_projectExplorerSettings; ProjectExplorerSettings m_projectExplorerSettings;
ProjectWelcomePage *m_welcomePage; ProjectWelcomePage *m_welcomePage = nullptr;
IMode *m_projectsMode; IMode *m_projectsMode;
TaskHub *m_taskHub; TaskHub *m_taskHub;
...@@ -412,10 +412,6 @@ ProjectExplorerPlugin::~ProjectExplorerPlugin() ...@@ -412,10 +412,6 @@ ProjectExplorerPlugin::~ProjectExplorerPlugin()
{ {
JsonWizardFactory::destroyAllFactories(); JsonWizardFactory::destroyAllFactories();
removeObject(dd->m_welcomePage);
delete dd->m_welcomePage;
removeObject(this);
// Force sequence of deletion: // Force sequence of deletion:
delete dd->m_kitManager; // remove all the profile information delete dd->m_kitManager; // remove all the profile information
delete dd->m_toolChainManager; delete dd->m_toolChainManager;
...@@ -1521,6 +1517,9 @@ ExtensionSystem::IPlugin::ShutdownFlag ProjectExplorerPlugin::aboutToShutdown() ...@@ -1521,6 +1517,9 @@ ExtensionSystem::IPlugin::ShutdownFlag ProjectExplorerPlugin::aboutToShutdown()
// Attempt to synchronously shutdown all run controls. // Attempt to synchronously shutdown all run controls.
// If that fails, fall back to asynchronous shutdown (Debugger run controls // If that fails, fall back to asynchronous shutdown (Debugger run controls
// might shutdown asynchronously). // might shutdown asynchronously).
removeObject(dd->m_welcomePage);
delete dd->m_welcomePage;
removeObject(this);
if (dd->m_outputPane->closeTabs(AppOutputPane::CloseTabNoPrompt /* No prompt any more */)) if (dd->m_outputPane->closeTabs(AppOutputPane::CloseTabNoPrompt /* No prompt any more */))
return SynchronousShutdown; return SynchronousShutdown;
connect(dd->m_outputPane, &AppOutputPane::allRunControlsFinished, connect(dd->m_outputPane, &AppOutputPane::allRunControlsFinished,
......
...@@ -77,18 +77,13 @@ using namespace QmakeProjectManager; ...@@ -77,18 +77,13 @@ using namespace QmakeProjectManager;
using namespace ProjectExplorer; using namespace ProjectExplorer;
QmakeProjectManagerPlugin::QmakeProjectManagerPlugin() QmakeProjectManagerPlugin::QmakeProjectManagerPlugin()
: m_previousStartupProject(0), m_previousTarget(0) : m_qmakeProjectManager(0), m_previousStartupProject(0), m_previousTarget(0)
{ {
} }
QmakeProjectManagerPlugin::~QmakeProjectManagerPlugin() QmakeProjectManagerPlugin::~QmakeProjectManagerPlugin()
{ {
//removeObject(m_embeddedPropertiesPage);
//delete m_embeddedPropertiesPage;
removeObject(m_qmakeProjectManager);
delete m_qmakeProjectManager;
} }
bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString *errorMessage) bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
...@@ -102,7 +97,7 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString ...@@ -102,7 +97,7 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString
//create and register objects //create and register objects
m_qmakeProjectManager = new QmakeManager; m_qmakeProjectManager = new QmakeManager;
addObject(m_qmakeProjectManager); addAutoReleasedObject(m_qmakeProjectManager);
ProjectExplorer::KitManager::registerKitInformation(new QmakeKitInformation); ProjectExplorer::KitManager::registerKitInformation(new QmakeKitInformation);
......
...@@ -53,7 +53,6 @@ bool RemoteLinuxPlugin::initialize(const QStringList &arguments, ...@@ -53,7 +53,6 @@ bool RemoteLinuxPlugin::initialize(const QStringList &arguments,
Q_UNUSED(arguments) Q_UNUSED(arguments)
Q_UNUSED(errorMessage) Q_UNUSED(errorMessage)
addObject(this);
addAutoReleasedObject(new GenericLinuxDeviceConfigurationFactory); addAutoReleasedObject(new GenericLinuxDeviceConfigurationFactory);
addAutoReleasedObject(new RemoteLinuxRunConfigurationFactory); addAutoReleasedObject(new RemoteLinuxRunConfigurationFactory);
addAutoReleasedObject(new RemoteLinuxRunControlFactory); addAutoReleasedObject(new RemoteLinuxRunControlFactory);
...@@ -67,7 +66,6 @@ bool RemoteLinuxPlugin::initialize(const QStringList &arguments, ...@@ -67,7 +66,6 @@ bool RemoteLinuxPlugin::initialize(const QStringList &arguments,
RemoteLinuxPlugin::~RemoteLinuxPlugin() RemoteLinuxPlugin::~RemoteLinuxPlugin()
{ {
removeObject(this);
} }
void RemoteLinuxPlugin::extensionsInitialized() void RemoteLinuxPlugin::extensionsInitialized()
......
...@@ -149,7 +149,7 @@ private: ...@@ -149,7 +149,7 @@ private:
const QStringList m_svnDirectories; const QStringList m_svnDirectories;
SubversionClient *m_client; SubversionClient *m_client = nullptr;
QString m_commitMessageFileName; QString m_commitMessageFileName;
QString m_commitRepository; QString m_commitRepository;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment