Debugger: Re-organize dock widget persisting

Looks like the mainwindow cannot be convinced to handle multiple
sets of dockwidgets.

So switch back to a single set containing everything and keep
track of non-default visibility in the perspectives, and persist
these sets.

The following pass:

1.

 Start Creator with new settings
 Goto Debug Mode
 Move Break dock widget to right, switch on Global log widget
 Leave Creator
 Start Creator
 Goto Debug Mode
 Check: Debugger Selected, Break on right, Global log visible

2.

 Start Creator with new settings
 Goto Debug Mode
 Move Break dock widget to right, switch on Global log widget
 Switch to QmlProfiler sub-perspective
 Leave Creator
 Start Creator
 Goto Debug Mode
 Check QmlProfiler selected
 Switch to Debugger sub-perspective
 Check: Debugger Selected, Break on right, Global log visible

3.

 Start Creator with new settings
 Use any C++ test project
 Start debugging / stop at main()  (F10)
 Wait for stop
 Switch to Edit mode
 Switch back to Debug mode
 Check: Only "running" debugger dock widget layout present
  (not the normal + preset at the same time)
 Quit Qt Creator while this debugger is running
 Check: Shuts down without crash

4.
 Use any C++ test project
 Start debugging
 Switch to Debugger Preset perspective
 Start a second debugger
 Kill either instance
 Check: Application dies, Debugger Preset perspective gets displayed
 Switch to perspective of second instance
 Check: Perspective looks ok (docks visible as before)

Task-number: QTCREATORBUG-21083
Task-number: QTCREATORBUG-21669
Task-number: QTCREATORBUG-21668
Task-number: QTCREATORBUG-21813
Task-number: QTCREATORBUG-21851
Task-number: QTCREATORBUG-22110
Task-number: QTCREATORBUG-22169
Task-number: QTCREATORBUG-22189
Change-Id: Ic9eb41ff7699ac0f48a85e68376daa80b2b6847e
Reviewed-by: Robert Loehning <robert.loehning@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
hjk
2019-03-22 07:35:48 +01:00
parent 6ee855a2bc
commit 5273ef2a8a
12 changed files with 614 additions and 370 deletions

View File

@@ -61,6 +61,7 @@
#include <coreplugin/icore.h>
#include <coreplugin/idocument.h>
#include <coreplugin/messagebox.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
@@ -280,12 +281,16 @@ public:
m_disassemblerAgent(engine),
m_toolTipManager(engine)
{
m_logWindow = new LogWindow(m_engine); // Needed before start()
m_logWindow->setObjectName(DOCKWIDGET_OUTPUT);
m_debuggerName = DebuggerEngine::tr("Debugger");
connect(action(EnableReverseDebugging), &SavedAction::valueChanged,
this, [this] { updateState(true); });
m_logWindow = new LogWindow(m_engine); // Needed before start()
m_logWindow->setObjectName("Debugger.Dock.Output");
connect(action(EnableReverseDebugging), &SavedAction::valueChanged, this, [this] {
updateState();
if (m_companionEngine)
m_companionEngine->d->updateState();
});
static int contextCount = 0;
m_context = Context(Id("Debugger.Engine.").withSuffix(++contextCount));
@@ -370,17 +375,15 @@ public:
if (!m_perspective)
return;
delete m_perspective;
Perspective *perspective = m_perspective;
m_perspective = nullptr;
EngineManager::unregisterEngine(m_engine);
// Give up ownership on claimed breakpoints.
m_breakHandler.releaseAllBreakpoints();
m_toolTipManager.deregisterEngine();
m_memoryAgents.handleDebuggerFinished();
setBusyCursor(false);
// This triggers activity in the EngineManager which
// recognizes the rampdown by the m_perpective == nullptr above.
perspective->destroy();
delete perspective;
}
void updateReturnViewHeader(int section, int, int newSize)
@@ -446,14 +449,14 @@ public:
void setInitialActionStates();
void setBusyCursor(bool on);
void cleanupViews();
void updateState(bool alsoUpdateCompanion);
void updateState();
void updateReverseActions();
DebuggerEngine *m_engine = nullptr; // Not owned.
QString m_runId;
QPointer<RunConfiguration> m_runConfiguration; // Not owned.
QString m_debuggerName;
Perspective *m_perspective = nullptr;
QPointer<Perspective> m_perspective;
DebuggerRunParameters m_runParameters;
IDevice::ConstPtr m_device;
@@ -551,16 +554,17 @@ public:
void DebuggerEnginePrivate::setupViews()
{
const DebuggerRunParameters &rp = m_runParameters;
const QString engineId = EngineManager::registerEngine(m_engine);
QTC_CHECK(!m_perspective);
m_perspective = new Perspective("Debugger.Perspective." + m_runId + '.' + m_debuggerName,
const QString perspectiveId = "Debugger.Perspective." + m_runId + '.' + m_debuggerName;
const QString settingsId = "Debugger.Perspective." + m_debuggerName;
m_perspective = new Perspective(perspectiveId,
m_engine->displayName(),
Debugger::Constants::PRESET_PERSPECTIVE_ID,
m_debuggerName);
m_perspective->setShouldPersistChecker([this] {
return EngineManager::isLastOf(m_debuggerName);
});
settingsId);
m_progress.setProgressRange(0, 1000);
FutureProgress *fp = ProgressManager::addTask(m_progress.future(),
@@ -628,7 +632,7 @@ void DebuggerEnginePrivate::setupViews()
m_engine, &DebuggerEngine::reloadModules,
Qt::QueuedConnection);
m_modulesWindow = addSearch(m_modulesView);
m_modulesWindow->setObjectName(DOCKWIDGET_MODULES);
m_modulesWindow->setObjectName("Debugger.Dock.Modules." + engineId);
m_modulesWindow->setWindowTitle(tr("&Modules"));
m_registerView = new BaseTreeView;
@@ -639,7 +643,7 @@ void DebuggerEnginePrivate::setupViews()
m_engine, &DebuggerEngine::reloadRegisters,
Qt::QueuedConnection);
m_registerWindow = addSearch(m_registerView);
m_registerWindow->setObjectName(DOCKWIDGET_REGISTER);
m_registerWindow->setObjectName("Debugger.Dock.Register." + engineId);
m_registerWindow->setWindowTitle(tr("Reg&isters"));
m_stackView = new StackTreeView;
@@ -647,7 +651,7 @@ void DebuggerEnginePrivate::setupViews()
m_stackView->setSettings(settings, "Debugger.StackView");
m_stackView->setIconSize(QSize(10, 10));
m_stackWindow = addSearch(m_stackView);
m_stackWindow->setObjectName(DOCKWIDGET_STACK);
m_stackWindow->setObjectName("Debugger.Dock.Stack." + engineId);
m_stackWindow->setWindowTitle(tr("&Stack"));
m_sourceFilesView = new BaseTreeView;
@@ -658,7 +662,7 @@ void DebuggerEnginePrivate::setupViews()
m_engine, &DebuggerEngine::reloadSourceFiles,
Qt::QueuedConnection);
m_sourceFilesWindow = addSearch(m_sourceFilesView);
m_sourceFilesWindow->setObjectName(DOCKWIDGET_SOURCE_FILES);
m_sourceFilesWindow->setObjectName("Debugger.Dock.SourceFiles." + engineId);
m_sourceFilesWindow->setWindowTitle(tr("Source Files"));
m_threadsView = new BaseTreeView;
@@ -668,7 +672,7 @@ void DebuggerEnginePrivate::setupViews()
m_threadsView->setIconSize(QSize(10, 10));
m_threadsView->setSpanColumn(ThreadData::FunctionColumn);
m_threadsWindow = addSearch(m_threadsView);
m_threadsWindow->setObjectName(DOCKWIDGET_THREADS);
m_threadsWindow->setObjectName("Debugger.Dock.Threads." + engineId);
m_threadsWindow->setWindowTitle(tr("&Threads"));
m_returnView = new WatchTreeView{ReturnType};
@@ -682,26 +686,26 @@ void DebuggerEnginePrivate::setupViews()
m_localsView->setModel(m_watchHandler.model());
m_localsView->setSettings(settings, "Debugger.LocalsView");
m_localsWindow = addSearch(m_localsView);
m_localsWindow->setObjectName("CppDebugLocals");
m_localsWindow->setObjectName("Debugger.Dock.Locals." + engineId);
m_localsWindow->setWindowTitle(tr("Locals"));
m_inspectorView = new WatchTreeView{InspectType};
m_inspectorView->setModel(m_watchHandler.model());
m_inspectorView->setSettings(settings, "Debugger.LocalsView"); // sic! same as locals view.
m_inspectorWindow = addSearch(m_inspectorView);
m_inspectorWindow->setObjectName("Inspector");
m_inspectorWindow->setObjectName("Debugger.Dock.Inspector." + engineId);
m_inspectorWindow->setWindowTitle(tr("Locals"));
m_watchersView = new WatchTreeView{WatchersType};
m_watchersView->setModel(m_watchHandler.model());
m_watchersView->setSettings(settings, "Debugger.WatchersView");
m_watchersWindow = addSearch(m_watchersView);
m_watchersWindow->setObjectName("CppDebugWatchers");
m_watchersWindow->setObjectName("Debugger.Dock.Watchers." + engineId);
m_watchersWindow->setWindowTitle(tr("&Expressions"));
m_localsAndInspectorWindow = new LocalsAndInspectorWindow(
m_localsWindow, m_inspectorWindow, m_returnWindow);
m_localsAndInspectorWindow->setObjectName(DOCKWIDGET_LOCALS_AND_INSPECTOR);
m_localsAndInspectorWindow->setObjectName("Debugger.Dock.LocalsAndInspector." + engineId);
m_localsAndInspectorWindow->setWindowTitle(m_localsWindow->windowTitle());
// Locals
@@ -719,7 +723,7 @@ void DebuggerEnginePrivate::setupViews()
m_breakView->setModel(m_breakHandler.model());
m_breakView->setRootIsDecorated(true);
m_breakWindow = addSearch(m_breakView);
m_breakWindow->setObjectName(DOCKWIDGET_BREAK);
m_breakWindow->setObjectName("Debugger.Dock.Break." + engineId);
m_breakWindow->setWindowTitle(tr("&Breakpoints"));
m_perspective->useSubPerspectiveSwitcher(EngineManager::engineChooser());
@@ -846,7 +850,6 @@ void DebuggerEnginePrivate::setupViews()
DebuggerEngine::DebuggerEngine()
: d(new DebuggerEnginePrivate(this))
{
updateState(false);
}
DebuggerEngine::~DebuggerEngine()
@@ -1020,7 +1023,6 @@ void DebuggerEngine::setRunTool(DebuggerRunTool *runTool)
void DebuggerEngine::start()
{
EngineManager::registerEngine(this);
d->m_watchHandler.resetWatchers();
d->setInitialActionStates();
setState(EngineSetupRequested);
@@ -1116,7 +1118,7 @@ void DebuggerEngine::abortDebugger()
void DebuggerEngine::updateUi(bool isCurrentEngine)
{
updateState(false);
updateState();
if (isCurrentEngine) {
gotoCurrentLocation();
} else {
@@ -1319,7 +1321,7 @@ void DebuggerEngine::notifyInferiorSpontaneousStop()
{
showMessage("NOTE: INFERIOR SPONTANEOUS STOP");
QTC_ASSERT(state() == InferiorRunOk, qDebug() << this << state());
EngineManager::activateEngine(this);
d->m_perspective->select();
showMessage(tr("Stopped."), StatusBar);
setState(InferiorStopOk);
if (boolSetting(RaiseOnInterrupt))
@@ -1386,10 +1388,12 @@ void DebuggerEnginePrivate::setInitialActionStates()
m_threadLabel->setEnabled(false);
}
void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion)
void DebuggerEnginePrivate::updateState()
{
if (!m_perspective)
// Can happen in mixed debugging.
if (!m_threadLabel)
return;
QTC_ASSERT(m_threadLabel, return);
const DebuggerState state = m_state;
const bool companionPreventsAction = m_engine->companionPreventsActions();
@@ -1399,7 +1403,7 @@ void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion)
// visible, possibly disabled.
if (state == DebuggerNotReady) {
// Happens when companion starts, otherwise this should not happen.
QTC_CHECK(m_companionEngine);
//QTC_CHECK(m_companionEngine);
m_interruptAction.setVisible(true);
m_interruptAction.setEnabled(false);
m_continueAction.setVisible(false);
@@ -1529,9 +1533,6 @@ void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion)
|| state == DebuggerFinished
|| state == InferiorUnrunnable;
setBusyCursor(!notbusy);
if (alsoUpdateCompanion && m_companionEngine)
m_companionEngine->updateState(false);
}
void DebuggerEnginePrivate::updateReverseActions()
@@ -1690,9 +1691,9 @@ void DebuggerEngine::notifyInferiorExited()
d->doShutdownEngine();
}
void DebuggerEngine::updateState(bool alsoUpdateCompanion)
void DebuggerEngine::updateState()
{
d->updateState(alsoUpdateCompanion);
d->updateState();
}
WatchTreeView *DebuggerEngine::inspectorView()
@@ -1793,17 +1794,28 @@ void DebuggerEngine::setState(DebuggerState state, bool forced)
if (!forced && !isAllowedTransition(oldState, state))
qDebug() << "*** UNEXPECTED STATE TRANSITION: " << this << msg;
if (state == EngineRunRequested)
if (state == EngineRunRequested) {
emit engineStarted();
d->m_perspective->select();
}
showMessage(msg, LogDebug);
d->updateState(true);
d->updateState();
if (d->m_companionEngine)
d->m_companionEngine->d->updateState();
if (oldState != d->m_state)
emit EngineManager::instance()->engineStateChanged(this);
if (state == DebuggerFinished) {
d->setBusyCursor(false);
// Give up ownership on claimed breakpoints.
d->m_breakHandler.releaseAllBreakpoints();
d->m_toolTipManager.deregisterEngine();
d->m_memoryAgents.handleDebuggerFinished();
d->destroyPerspective();
emit engineFinished();
}