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()
while (it.hasPrevious()) {
PluginSpec *spec = it.previous();
loadPlugin(spec, PluginSpec::Running);
if (spec->state() == PluginSpec::Running)
if (spec->state() == PluginSpec::Running) {
delayedInitializeQueue.append(spec);
} else {
// Plugin initialization failed, so cleanup after it
spec->d->kill();
}
}
emit q->pluginsChanged();
......@@ -1246,8 +1250,12 @@ void PluginManagerPrivate::shutdown()
shutdownEventLoop->exec();
}
deleteAll();
if (!allObjects.isEmpty())
qDebug() << "There are" << allObjects.size() << "objects left in the plugin manager pool: " << allObjects;
if (!allObjects.isEmpty()) {
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()
if (!plugin->initialize(arguments, &err)) {
errorString = QCoreApplication::translate("PluginSpec", "Plugin initialization failed: %1").arg(err);
hasError = true;
// clean up
loader.unload();
plugin = 0;
return false;
}
state = PluginSpec::Initialized;
......
......@@ -93,7 +93,6 @@ CppToolsPlugin::CppToolsPlugin()
CppToolsPlugin::~CppToolsPlugin()
{
m_instance = 0;
delete CppModelManager::instance();
}
CppToolsPlugin *CppToolsPlugin::instance()
......@@ -141,6 +140,8 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
Q_UNUSED(arguments)
Q_UNUSED(error)
CppModelManager::instance()->setParent(this);
m_settings = new CppToolsSettings(this); // force registration of cpp tools settings
// Objects
......
......@@ -167,7 +167,7 @@ private:
inline CvsControl *cvsVersionControl() const;
CvsSettings m_settings;
CvsClient *m_client;
CvsClient *m_client = nullptr;
QString m_commitMessageFileName;
QString m_commitRepository;
......
......@@ -3244,7 +3244,6 @@ QSharedPointer<Internal::GlobalDebuggerOptions> globalDebuggerOptions()
DebuggerPlugin::DebuggerPlugin()
{
setObjectName(QLatin1String("DebuggerPlugin"));
addObject(this);
dd = new DebuggerPluginPrivate(this);
}
......@@ -3256,6 +3255,7 @@ DebuggerPlugin::~DebuggerPlugin()
bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
addObject(this);
// Menu groups
ActionContainer *mstart = ActionManager::actionContainer(PE::M_DEBUG_STARTDEBUGGING);
mstart->appendGroup(Constants::G_GENERAL);
......
......@@ -1127,7 +1127,7 @@ private:
StatusBarWidget *m_statusBar;
// @TODO: Delete
//WordCompletion *m_wordCompletion;
FakeVimCompletionAssistProvider *m_wordProvider;
FakeVimCompletionAssistProvider *m_wordProvider = nullptr;
};
QVariant FakeVimUserCommandsModel::data(const QModelIndex &index, int role) const
......@@ -1184,6 +1184,18 @@ FakeVimPluginPrivate::FakeVimPluginPrivate(FakeVimPlugin *plugin)
}
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);
delete m_fakeVimOptionsPage;
......@@ -1199,19 +1211,6 @@ FakeVimPluginPrivate::~FakeVimPluginPrivate()
delete m_wordProvider;
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()
......
......@@ -356,7 +356,7 @@ public:
QString m_projectFilterString;
MiniProjectTargetSelector * m_targetSelector;
ProjectExplorerSettings m_projectExplorerSettings;
ProjectWelcomePage *m_welcomePage;
ProjectWelcomePage *m_welcomePage = nullptr;
IMode *m_projectsMode;
TaskHub *m_taskHub;
......@@ -412,10 +412,6 @@ ProjectExplorerPlugin::~ProjectExplorerPlugin()
{
JsonWizardFactory::destroyAllFactories();
removeObject(dd->m_welcomePage);
delete dd->m_welcomePage;
removeObject(this);
// Force sequence of deletion:
delete dd->m_kitManager; // remove all the profile information
delete dd->m_toolChainManager;
......@@ -1521,6 +1517,9 @@ ExtensionSystem::IPlugin::ShutdownFlag ProjectExplorerPlugin::aboutToShutdown()
// Attempt to synchronously shutdown all run controls.
// If that fails, fall back to asynchronous shutdown (Debugger run controls
// might shutdown asynchronously).
removeObject(dd->m_welcomePage);
delete dd->m_welcomePage;
removeObject(this);
if (dd->m_outputPane->closeTabs(AppOutputPane::CloseTabNoPrompt /* No prompt any more */))
return SynchronousShutdown;
connect(dd->m_outputPane, &AppOutputPane::allRunControlsFinished,
......
......@@ -77,18 +77,13 @@ using namespace QmakeProjectManager;
using namespace ProjectExplorer;
QmakeProjectManagerPlugin::QmakeProjectManagerPlugin()
: m_previousStartupProject(0), m_previousTarget(0)
: m_qmakeProjectManager(0), m_previousStartupProject(0), m_previousTarget(0)
{
}
QmakeProjectManagerPlugin::~QmakeProjectManagerPlugin()
{
//removeObject(m_embeddedPropertiesPage);
//delete m_embeddedPropertiesPage;
removeObject(m_qmakeProjectManager);
delete m_qmakeProjectManager;
}
bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
......@@ -102,7 +97,7 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString
//create and register objects
m_qmakeProjectManager = new QmakeManager;
addObject(m_qmakeProjectManager);
addAutoReleasedObject(m_qmakeProjectManager);
ProjectExplorer::KitManager::registerKitInformation(new QmakeKitInformation);
......
......@@ -53,7 +53,6 @@ bool RemoteLinuxPlugin::initialize(const QStringList &arguments,
Q_UNUSED(arguments)
Q_UNUSED(errorMessage)
addObject(this);
addAutoReleasedObject(new GenericLinuxDeviceConfigurationFactory);
addAutoReleasedObject(new RemoteLinuxRunConfigurationFactory);
addAutoReleasedObject(new RemoteLinuxRunControlFactory);
......@@ -67,7 +66,6 @@ bool RemoteLinuxPlugin::initialize(const QStringList &arguments,
RemoteLinuxPlugin::~RemoteLinuxPlugin()
{
removeObject(this);
}
void RemoteLinuxPlugin::extensionsInitialized()
......
......@@ -149,7 +149,7 @@ private:
const QStringList m_svnDirectories;
SubversionClient *m_client;
SubversionClient *m_client = nullptr;
QString m_commitMessageFileName;
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