2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2008-12-02 15:08:31 +01:00
|
|
|
|
2009-03-17 17:00:06 +01:00
|
|
|
#include "debuggeractions.h"
|
2011-04-21 15:52:51 +02:00
|
|
|
#include "debuggerinternalconstants.h"
|
2010-11-10 11:39:01 +01:00
|
|
|
#include "debuggercore.h"
|
2010-06-16 11:08:54 +02:00
|
|
|
#include "debuggerdialogs.h"
|
|
|
|
|
#include "debuggerengine.h"
|
2015-11-23 16:41:54 +01:00
|
|
|
#include "debuggericons.h"
|
2013-10-25 13:47:08 +02:00
|
|
|
#include "debuggeritemmanager.h"
|
2010-12-02 17:43:14 +01:00
|
|
|
#include "debuggermainwindow.h"
|
2013-03-27 13:03:15 +01:00
|
|
|
#include "debuggerrunconfigurationaspect.h"
|
2014-10-17 13:40:04 +02:00
|
|
|
#include "debuggerruncontrol.h"
|
2023-08-15 15:47:33 +02:00
|
|
|
#include "debuggerkitaspect.h"
|
2024-01-18 18:30:14 +01:00
|
|
|
#include "debuggertest.h"
|
2022-07-05 15:37:08 +02:00
|
|
|
#include "debuggertr.h"
|
2010-11-04 09:54:23 +01:00
|
|
|
#include "breakhandler.h"
|
2018-09-27 15:09:09 +02:00
|
|
|
#include "enginemanager.h"
|
2010-09-22 16:20:08 +02:00
|
|
|
#include "logwindow.h"
|
2023-01-13 14:02:32 +01:00
|
|
|
#include "stackframe.h"
|
2013-09-20 16:48:01 +02:00
|
|
|
#include "unstartedappwatcherdialog.h"
|
2012-07-24 17:02:42 +02:00
|
|
|
#include "loadcoredialog.h"
|
2013-01-24 16:33:17 +01:00
|
|
|
#include "sourceutils.h"
|
2015-11-10 16:59:02 +01:00
|
|
|
#include "shared/hostutils.h"
|
|
|
|
|
#include "console/console.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2016-02-24 14:42:52 +01:00
|
|
|
#include "analyzer/analyzerconstants.h"
|
|
|
|
|
#include "analyzer/analyzermanager.h"
|
|
|
|
|
|
2010-03-18 10:59:06 +01:00
|
|
|
#include <coreplugin/actionmanager/actioncontainer.h>
|
2016-02-29 12:11:18 +01:00
|
|
|
#include <coreplugin/actionmanager/actionmanager.h>
|
2015-02-26 13:38:54 +01:00
|
|
|
#include <coreplugin/actionmanager/command.h>
|
2016-02-29 12:11:18 +01:00
|
|
|
#include <coreplugin/coreconstants.h>
|
|
|
|
|
#include <coreplugin/editormanager/documentmodel.h>
|
|
|
|
|
#include <coreplugin/editormanager/editormanager.h>
|
|
|
|
|
#include <coreplugin/find/itemviewfind.h>
|
2018-09-19 18:14:28 +02:00
|
|
|
#include <coreplugin/findplaceholder.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <coreplugin/icore.h>
|
2016-02-29 12:11:18 +01:00
|
|
|
#include <coreplugin/imode.h>
|
2014-11-25 13:08:18 +01:00
|
|
|
#include <coreplugin/messagebox.h>
|
2013-03-05 11:10:33 +01:00
|
|
|
#include <coreplugin/messagemanager.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <coreplugin/modemanager.h>
|
2016-03-02 13:57:37 +01:00
|
|
|
#include <coreplugin/modemanager.h>
|
2016-02-29 12:11:18 +01:00
|
|
|
#include <coreplugin/navigationwidget.h>
|
|
|
|
|
#include <coreplugin/outputpane.h>
|
|
|
|
|
#include <coreplugin/rightpane.h>
|
2024-02-02 08:48:30 +01:00
|
|
|
#include <coreplugin/session.h>
|
2008-12-09 16:18:28 +01:00
|
|
|
|
2024-01-12 18:16:51 +01:00
|
|
|
#include <extensionsystem/iplugin.h>
|
2018-01-26 12:26:43 +01:00
|
|
|
#include <extensionsystem/pluginmanager.h>
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <cppeditor/cppeditorconstants.h>
|
2017-02-21 10:36:10 +01:00
|
|
|
#include <qmljseditor/qmljseditorconstants.h>
|
2008-12-09 16:18:28 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
#include <projectexplorer/buildconfiguration.h>
|
2012-10-31 18:14:17 +01:00
|
|
|
#include <projectexplorer/buildmanager.h>
|
2023-07-04 16:32:37 +02:00
|
|
|
#include <projectexplorer/buildsystem.h>
|
2022-04-12 21:01:45 +02:00
|
|
|
#include <projectexplorer/devicesupport/idevice.h>
|
2012-08-08 12:03:07 +02:00
|
|
|
#include <projectexplorer/devicesupport/deviceprocessesdialog.h>
|
2022-05-13 01:08:44 +02:00
|
|
|
#include <projectexplorer/devicesupport/sshparameters.h>
|
2018-03-07 15:31:08 +01:00
|
|
|
#include <projectexplorer/itaskhandler.h>
|
2023-08-10 14:29:21 +02:00
|
|
|
#include <projectexplorer/kitaspects.h>
|
2016-03-02 13:57:37 +01:00
|
|
|
#include <projectexplorer/project.h>
|
2011-10-25 18:23:37 +08:00
|
|
|
#include <projectexplorer/projectexplorer.h>
|
2015-11-23 16:41:54 +01:00
|
|
|
#include <projectexplorer/projectexplorericons.h>
|
2023-01-13 14:02:32 +01:00
|
|
|
#include <projectexplorer/projectexplorerconstants.h>
|
2011-10-25 18:23:37 +08:00
|
|
|
#include <projectexplorer/projectexplorersettings.h>
|
2023-02-14 15:47:22 +01:00
|
|
|
#include <projectexplorer/projectmanager.h>
|
2016-03-02 13:57:37 +01:00
|
|
|
#include <projectexplorer/projecttree.h>
|
2016-02-29 12:11:18 +01:00
|
|
|
#include <projectexplorer/runconfiguration.h>
|
2023-02-14 15:47:22 +01:00
|
|
|
#include <projectexplorer/projectmanager.h>
|
2010-07-21 17:06:22 +02:00
|
|
|
#include <projectexplorer/target.h>
|
2016-03-02 13:57:37 +01:00
|
|
|
#include <projectexplorer/taskhub.h>
|
|
|
|
|
#include <projectexplorer/toolchain.h>
|
2022-05-12 18:43:44 +02:00
|
|
|
|
2014-09-26 09:14:03 +02:00
|
|
|
#include <texteditor/texteditor.h>
|
2015-02-26 13:22:35 +01:00
|
|
|
#include <texteditor/textdocument.h>
|
2010-06-16 11:08:54 +02:00
|
|
|
#include <texteditor/fontsettings.h>
|
2010-04-19 16:42:02 +02:00
|
|
|
#include <texteditor/texteditorsettings.h>
|
2008-12-09 16:18:28 +01:00
|
|
|
|
2016-02-29 12:11:18 +01:00
|
|
|
#include <utils/algorithm.h>
|
|
|
|
|
#include <utils/appmainwindow.h>
|
2014-06-04 14:45:10 +02:00
|
|
|
#include <utils/basetreeview.h>
|
2016-03-02 13:57:37 +01:00
|
|
|
#include <utils/checkablemessagebox.h>
|
2016-02-29 12:11:18 +01:00
|
|
|
#include <utils/fancymainwindow.h>
|
2012-08-23 15:53:58 +02:00
|
|
|
#include <utils/hostosinfo.h>
|
2022-02-24 18:42:47 +01:00
|
|
|
#include <utils/processinfo.h>
|
2011-01-12 16:36:29 +01:00
|
|
|
#include <utils/proxyaction.h>
|
2014-06-04 14:45:10 +02:00
|
|
|
#include <utils/qtcassert.h>
|
2011-03-16 13:49:28 +01:00
|
|
|
#include <utils/statuslabel.h>
|
2014-06-04 14:45:10 +02:00
|
|
|
#include <utils/styledbar.h>
|
2017-01-20 15:53:46 +01:00
|
|
|
#include <utils/temporarydirectory.h>
|
2016-08-03 17:55:54 +02:00
|
|
|
#include <utils/utilsicons.h>
|
2014-02-19 15:35:58 +01:00
|
|
|
#include <utils/winutils.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2016-02-29 12:11:18 +01:00
|
|
|
#include <QAction>
|
2014-05-18 15:43:20 +10:00
|
|
|
#include <QApplication>
|
2014-05-16 17:32:07 +02:00
|
|
|
#include <QCheckBox>
|
2013-06-07 17:57:25 +02:00
|
|
|
#include <QComboBox>
|
2016-02-29 12:11:18 +01:00
|
|
|
#include <QDebug>
|
2016-03-02 13:57:37 +01:00
|
|
|
#include <QDialog>
|
|
|
|
|
#include <QDialogButtonBox>
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDockWidget>
|
|
|
|
|
#include <QFileDialog>
|
2014-05-16 17:32:07 +02:00
|
|
|
#include <QHeaderView>
|
2012-06-05 10:25:48 +02:00
|
|
|
#include <QInputDialog>
|
2023-08-18 15:17:11 +02:00
|
|
|
#include <QJsonDocument>
|
|
|
|
|
#include <QJsonObject>
|
2016-02-29 12:11:18 +01:00
|
|
|
#include <QMenu>
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QMessageBox>
|
2016-03-02 13:57:37 +01:00
|
|
|
#include <QPointer>
|
|
|
|
|
#include <QPushButton>
|
2023-06-03 13:38:59 +02:00
|
|
|
#include <QScopeGuard>
|
2016-03-01 07:51:06 +01:00
|
|
|
#include <QStackedWidget>
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QTextBlock>
|
|
|
|
|
#include <QToolButton>
|
2014-06-04 14:45:10 +02:00
|
|
|
#include <QVBoxLayout>
|
2016-03-02 13:57:37 +01:00
|
|
|
#include <QVariant>
|
2014-06-04 14:45:10 +02:00
|
|
|
|
2009-08-12 10:51:25 +02:00
|
|
|
#include <climits>
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
#define DEBUG_STATE 1
|
|
|
|
|
#ifdef DEBUG_STATE
|
|
|
|
|
//# define STATE_DEBUG(s)
|
|
|
|
|
// do { QString msg; QTextStream ts(&msg); ts << s;
|
|
|
|
|
// showMessage(msg, LogDebug); } while (0)
|
2012-11-28 20:44:03 +02:00
|
|
|
# define STATE_DEBUG(s) do { qDebug() << s; } while (0)
|
2010-06-16 11:08:54 +02:00
|
|
|
#else
|
|
|
|
|
# define STATE_DEBUG(s)
|
|
|
|
|
#endif
|
|
|
|
|
|
2011-01-26 17:22:25 +01:00
|
|
|
/*!
|
|
|
|
|
\namespace Debugger
|
|
|
|
|
Debugger plugin namespace
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\namespace Debugger::Internal
|
|
|
|
|
Internal namespace of the Debugger plugin
|
2011-02-04 15:08:31 +01:00
|
|
|
\internal
|
2011-01-26 17:22:25 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\class Debugger::DebuggerEngine
|
|
|
|
|
|
2013-06-05 14:29:24 +02:00
|
|
|
\brief The DebuggerEngine class is the base class of a debugger engine.
|
2011-01-26 17:22:25 +01:00
|
|
|
|
2013-09-06 17:16:18 +02:00
|
|
|
\note The Debugger process itself and any helper processes like
|
2012-08-22 13:27:25 +02:00
|
|
|
gdbserver are referred to as 'Engine', whereas the debugged process
|
|
|
|
|
is referred to as 'Inferior'.
|
2011-01-26 17:22:25 +01:00
|
|
|
|
|
|
|
|
Transitions marked by '---' are done in the individual engines.
|
|
|
|
|
Transitions marked by '+-+' are done in the base DebuggerEngine.
|
|
|
|
|
Transitions marked by '*' are done asynchronously.
|
|
|
|
|
|
|
|
|
|
The GdbEngine->setupEngine() function is described in more detail below.
|
|
|
|
|
|
|
|
|
|
The engines are responsible for local roll-back to the last
|
|
|
|
|
acknowledged state before calling notify*Failed. I.e. before calling
|
|
|
|
|
notifyEngineSetupFailed() any process started during setupEngine()
|
|
|
|
|
so far must be terminated.
|
|
|
|
|
\code
|
|
|
|
|
|
|
|
|
|
DebuggerNotReady
|
|
|
|
|
progressmanager/progressmanager.cpp +
|
|
|
|
|
EngineSetupRequested
|
|
|
|
|
+
|
|
|
|
|
(calls *Engine->setupEngine())
|
|
|
|
|
| |
|
|
|
|
|
| |
|
|
|
|
|
{notify- {notify-
|
|
|
|
|
Engine- Engine-
|
|
|
|
|
SetupOk} SetupFailed}
|
2020-12-18 18:20:32 +01:00
|
|
|
+ | +
|
|
|
|
|
EngineRunRequested <+-+' | `+-+-+> EngineSetupFailed
|
|
|
|
|
| +
|
|
|
|
|
| [calls RunControl->startFailed]
|
|
|
|
|
| +
|
|
|
|
|
| DebuggerFinished
|
|
|
|
|
|
|
|
|
|
|
------------------------
|
|
|
|
|
/ | | \
|
2017-11-15 17:12:03 +01:00
|
|
|
/ | | \
|
|
|
|
|
/ | | \
|
|
|
|
|
| (core) | (attach) | |
|
|
|
|
|
| | | |
|
|
|
|
|
{notify- {notifyER&- {notifyER&- {notify-
|
|
|
|
|
Inferior- Inferior- Inferior- EngineRun-
|
|
|
|
|
Unrunnable} StopOk} RunOk} Failed}
|
|
|
|
|
+ + + +
|
|
|
|
|
InferiorUnrunnable + InferiorRunOk +
|
|
|
|
|
+ +
|
|
|
|
|
InferiorStopOk EngineRunFailed
|
|
|
|
|
+
|
2011-01-26 17:22:25 +01:00
|
|
|
`-+-+-+-+-+-+-+-+-+-+-+>-+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
#Interrupt@InferiorRunOk# +
|
|
|
|
|
+ +
|
|
|
|
|
InferiorStopRequested +
|
|
|
|
|
#SpontaneousStop + +
|
|
|
|
|
@InferiorRunOk# (calls *Engine-> +
|
|
|
|
|
+ interruptInferior()) +
|
|
|
|
|
{notify- | | +
|
|
|
|
|
Spontaneous- {notify- {notify- +
|
|
|
|
|
Inferior- Inferior- Inferior- +
|
|
|
|
|
StopOk} StopOk} StopFailed} +
|
|
|
|
|
+ + + +
|
|
|
|
|
+ + + +
|
|
|
|
|
InferiorStopOk + +
|
|
|
|
|
+ + +
|
|
|
|
|
+ + +
|
|
|
|
|
+ + +
|
|
|
|
|
#Stop@InferiorUnrunnable# + +
|
|
|
|
|
#Creator Close Event# + +
|
|
|
|
|
+ + +
|
|
|
|
|
InferiorShutdownRequested +
|
|
|
|
|
+ +
|
|
|
|
|
(calls *Engine->shutdownInferior()) +
|
2017-12-14 09:36:41 +01:00
|
|
|
| +
|
|
|
|
|
{notifyInferiorShutdownFinished} +
|
|
|
|
|
+ +
|
|
|
|
|
+ +
|
|
|
|
|
#Inferior exited# + +
|
|
|
|
|
| + +
|
|
|
|
|
{notifyInferior- + +
|
|
|
|
|
Exited} + +
|
|
|
|
|
+ + +
|
|
|
|
|
+ + +
|
|
|
|
|
+ + +
|
|
|
|
|
InferiorShutdownFinished +
|
|
|
|
|
* +
|
2011-01-26 17:22:25 +01:00
|
|
|
EngineShutdownRequested +
|
|
|
|
|
+ +
|
|
|
|
|
(calls *Engine->shutdownEngine()) <+-+-+-+-+-+-+-+-+-+-+-+-+-+'
|
2017-12-14 09:11:16 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{notifyEngineShutdownFinished}
|
|
|
|
|
+
|
|
|
|
|
EngineShutdownFinished
|
|
|
|
|
*
|
2011-01-26 17:22:25 +01:00
|
|
|
DebuggerFinished
|
|
|
|
|
|
|
|
|
|
\endcode */
|
2010-11-08 15:19:13 +01:00
|
|
|
|
2010-08-31 12:49:51 +02:00
|
|
|
/* Here is a matching graph as a GraphViz graph. View it using
|
|
|
|
|
* \code
|
|
|
|
|
grep "^sg1:" debuggerplugin.cpp | cut -c5- | dot -osg1.ps -Tps && gv sg1.ps
|
2010-07-08 11:44:00 +02:00
|
|
|
|
2010-08-31 12:49:51 +02:00
|
|
|
sg1: digraph DebuggerStates {
|
|
|
|
|
sg1: DebuggerNotReady -> EngineSetupRequested
|
|
|
|
|
sg1: EngineSetupRequested -> EngineSetupOk [ label="notifyEngineSetupOk", style="dashed" ];
|
|
|
|
|
sg1: EngineSetupRequested -> EngineSetupFailed [ label= "notifyEngineSetupFailed", style="dashed"];
|
|
|
|
|
sg1: EngineSetupFailed -> DebuggerFinished [ label= "RunControl::StartFailed" ];
|
2017-11-15 17:12:03 +01:00
|
|
|
sg1: EngineSetupOk -> EngineRunRequested [ label= "RunControl::StartSuccessful" ];
|
2010-08-31 12:49:51 +02:00
|
|
|
sg1: EngineRunRequested -> InferiorUnrunnable [ label="notifyInferiorUnrunnable", style="dashed" ];
|
|
|
|
|
sg1: EngineRunRequested -> InferiorStopOk [ label="notifyEngineRunAndInferiorStopOk", style="dashed" ];
|
|
|
|
|
sg1: EngineRunRequested -> InferiorRunOk [ label="notifyEngineRunAndInferiorRunOk", style="dashed" ];
|
|
|
|
|
sg1: EngineRunRequested -> EngineRunFailed [ label="notifyEngineRunFailed", style="dashed" ];
|
|
|
|
|
sg1: EngineRunFailed -> EngineShutdownRequested
|
|
|
|
|
sg1: InferiorRunOk -> InferiorStopOk [ label="SpontaneousStop\nnotifyInferiorSpontaneousStop", style="dashed" ];
|
|
|
|
|
sg1: InferiorRunOk -> InferiorStopRequested [ label="User stop\nEngine::interruptInferior", style="dashed"];
|
|
|
|
|
sg1: InferiorStopRequested -> InferiorStopOk [ label="notifyInferiorStopOk", style="dashed" ];
|
|
|
|
|
sg1: InferiorStopRequested -> InferiorShutdownRequested [ label="notifyInferiorStopFailed", style="dashed" ];
|
|
|
|
|
sg1: InferiorStopOk -> InferiorRunRequested [ label="User\nEngine::continueInferior" ];
|
|
|
|
|
sg1: InferiorRunRequested -> InferiorRunOk [ label="notifyInferiorRunOk", style="dashed"];
|
|
|
|
|
sg1: InferiorRunRequested -> InferiorRunFailed [ label="notifyInferiorRunFailed", style="dashed"];
|
|
|
|
|
sg1: InferiorRunFailed -> InferiorStopOk
|
2011-01-17 10:36:13 +01:00
|
|
|
sg1: InferiorStopOk -> InferiorShutdownRequested [ label="Close event" ];
|
|
|
|
|
sg1: InferiorUnrunnable -> InferiorShutdownRequested [ label="Close event" ];
|
2017-12-14 09:36:41 +01:00
|
|
|
sg1: InferiorShutdownRequested -> InferiorShutdownFinished [ label= "Engine::shutdownInferior\nnotifyInferiorShutdownFinished", style="dashed" ];
|
2011-01-17 10:36:13 +01:00
|
|
|
sg1: InferiorExited -> InferiorExitOk [ label="notifyInferiorExited", style="dashed"];
|
|
|
|
|
sg1: InferiorExitOk -> InferiorShutdownOk
|
2017-12-14 09:36:41 +01:00
|
|
|
sg1: InferiorShutdownFinished -> EngineShutdownRequested
|
2017-12-14 09:11:16 +01:00
|
|
|
sg1: EngineShutdownRequested -> EngineShutdownFinished [ label="Engine::shutdownEngine\nnotifyEngineShutdownFinished", style="dashed" ];
|
|
|
|
|
sg1: EngineShutdownFinished -> DebuggerFinished [ style = "dotted" ];
|
2010-08-31 12:49:51 +02:00
|
|
|
sg1: }
|
|
|
|
|
* \endcode */
|
2010-07-15 09:41:11 +02:00
|
|
|
// Additional signalling: {notifyInferiorIll} {notifyEngineIll}
|
2010-07-09 17:07:59 +02:00
|
|
|
|
|
|
|
|
|
2011-01-26 17:22:25 +01:00
|
|
|
/*!
|
|
|
|
|
\class Debugger::Internal::GdbEngine
|
2013-06-05 14:29:24 +02:00
|
|
|
\brief The GdbEngine class implements Debugger::Engine driving a GDB
|
|
|
|
|
executable.
|
2011-01-26 17:22:25 +01:00
|
|
|
|
|
|
|
|
GdbEngine specific startup. All happens in EngineSetupRequested state:
|
|
|
|
|
|
2013-09-06 17:16:18 +02:00
|
|
|
\list
|
|
|
|
|
\li Transitions marked by '---' are done in the individual adapters.
|
2011-01-26 17:22:25 +01:00
|
|
|
|
2013-09-06 17:16:18 +02:00
|
|
|
\li Transitions marked by '+-+' are done in the GdbEngine.
|
|
|
|
|
\endlist
|
2011-01-26 17:22:25 +01:00
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
GdbEngine::setupEngine()
|
|
|
|
|
+
|
|
|
|
|
(calls *Adapter->startAdapter())
|
|
|
|
|
| |
|
|
|
|
|
| `---> handleAdapterStartFailed()
|
|
|
|
|
| +
|
|
|
|
|
| {notifyEngineSetupFailed}
|
|
|
|
|
|
|
|
|
|
|
handleAdapterStarted()
|
|
|
|
|
+
|
|
|
|
|
{notifyEngineSetupOk}
|
2010-07-08 11:44:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-26 17:22:25 +01:00
|
|
|
GdbEngine::setupInferior()
|
|
|
|
|
+
|
|
|
|
|
(calls *Adapter->prepareInferior())
|
|
|
|
|
| |
|
|
|
|
|
| `---> handlePrepareInferiorFailed()
|
|
|
|
|
| +
|
|
|
|
|
| {notifyInferiorSetupFailed}
|
|
|
|
|
|
|
|
|
|
|
handleInferiorPrepared()
|
|
|
|
|
+
|
|
|
|
|
{notifyInferiorSetupOk}
|
2010-07-08 11:44:00 +02:00
|
|
|
|
2011-01-26 17:22:25 +01:00
|
|
|
\endcode */
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
using namespace Core;
|
2016-03-09 19:16:14 +01:00
|
|
|
using namespace Core::Constants;
|
2009-01-13 18:15:24 +01:00
|
|
|
using namespace Debugger::Constants;
|
2014-10-22 13:04:47 +02:00
|
|
|
using namespace Debugger::Internal;
|
2012-08-15 16:19:15 +02:00
|
|
|
using namespace ExtensionSystem;
|
2008-12-02 12:01:29 +01:00
|
|
|
using namespace ProjectExplorer;
|
2009-01-13 18:15:24 +01:00
|
|
|
using namespace TextEditor;
|
2012-08-15 16:19:15 +02:00
|
|
|
using namespace Utils;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2010-03-11 12:22:24 +01:00
|
|
|
namespace CC = Core::Constants;
|
|
|
|
|
namespace PE = ProjectExplorer::Constants;
|
|
|
|
|
|
2024-01-12 18:16:51 +01:00
|
|
|
Q_DECLARE_METATYPE(QString *)
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
namespace Debugger {
|
2010-11-24 11:44:43 +01:00
|
|
|
namespace Internal {
|
|
|
|
|
|
2018-10-25 15:24:39 +02:00
|
|
|
const char DEBUGGER_START[] = "Debugger.Start";
|
|
|
|
|
|
2019-02-18 15:49:05 +01:00
|
|
|
// Menu Groups
|
|
|
|
|
const char MENU_GROUP_GENERAL[] = "Debugger.Group.General";
|
|
|
|
|
const char MENU_GROUP_SPECIAL[] = "Debugger.Group.Special";
|
|
|
|
|
const char MENU_GROUP_START_QML[] = "Debugger.Group.Start.Qml";
|
|
|
|
|
|
2011-01-12 12:10:12 +01:00
|
|
|
void addCdbOptionPages(QList<IOptionsPage*> *opts);
|
2017-07-07 18:34:05 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
static QIcon startIcon(bool toolBarStyle)
|
|
|
|
|
{
|
|
|
|
|
const static QIcon sidebarIcon =
|
|
|
|
|
Icon::sideBarIcon(ProjectExplorer::Icons::DEBUG_START, ProjectExplorer::Icons::DEBUG_START_FLAT);
|
|
|
|
|
const static QIcon icon =
|
|
|
|
|
Icon::combinedIcon({ProjectExplorer::Icons::DEBUG_START_SMALL.icon(), sidebarIcon});
|
|
|
|
|
const static QIcon iconToolBar =
|
|
|
|
|
Icon::combinedIcon({ProjectExplorer::Icons::DEBUG_START_SMALL_TOOLBAR.icon(), sidebarIcon});
|
|
|
|
|
return toolBarStyle ? iconToolBar : icon;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static QIcon continueIcon(bool toolBarStyle)
|
|
|
|
|
{
|
|
|
|
|
const static QIcon sidebarIcon =
|
|
|
|
|
Icon::sideBarIcon(Icons::CONTINUE, Icons::CONTINUE_FLAT);
|
|
|
|
|
const static QIcon icon =
|
|
|
|
|
Icon::combinedIcon({Icons::DEBUG_CONTINUE_SMALL.icon(), sidebarIcon});
|
|
|
|
|
const static QIcon iconToolBar =
|
|
|
|
|
Icon::combinedIcon({Icons::DEBUG_CONTINUE_SMALL_TOOLBAR.icon(), sidebarIcon});
|
|
|
|
|
return toolBarStyle ? iconToolBar : icon;
|
2016-04-24 22:51:24 +02:00
|
|
|
}
|
|
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
static QIcon interruptIcon(bool toolBarStyle)
|
2012-05-24 10:19:50 +02:00
|
|
|
{
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
const static QIcon sidebarIcon =
|
|
|
|
|
Icon::sideBarIcon(Icons::INTERRUPT, Icons::INTERRUPT_FLAT);
|
|
|
|
|
const static QIcon icon =
|
|
|
|
|
Icon::combinedIcon({Icons::DEBUG_INTERRUPT_SMALL.icon(), sidebarIcon});
|
|
|
|
|
const static QIcon iconToolBar =
|
|
|
|
|
Icon::combinedIcon({Icons::DEBUG_INTERRUPT_SMALL_TOOLBAR.icon(), sidebarIcon});
|
|
|
|
|
return toolBarStyle ? iconToolBar : icon;
|
2012-05-24 10:19:50 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-14 12:11:30 +01:00
|
|
|
static bool hideAnalyzeMenu()
|
|
|
|
|
{
|
|
|
|
|
return Core::ICore::settings()
|
|
|
|
|
->value(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_ANALYZE, false)
|
|
|
|
|
.toBool();
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-16 20:39:20 +02:00
|
|
|
static bool hideDebugMenu()
|
|
|
|
|
{
|
|
|
|
|
return Core::ICore::settings()
|
|
|
|
|
->value(ProjectExplorer::Constants::SETTINGS_MENU_HIDE_DEBUG, false)
|
|
|
|
|
.toBool();
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-04 16:37:59 -08:00
|
|
|
QAction *addAction(const QObject *parent, QMenu *menu, const QString &display, bool on,
|
2016-07-18 12:36:31 +02:00
|
|
|
const std::function<void()> &onTriggered)
|
|
|
|
|
{
|
|
|
|
|
QAction *act = menu->addAction(display);
|
|
|
|
|
act->setEnabled(on);
|
2022-02-04 16:37:59 -08:00
|
|
|
// Always queue the connection to prevent the following sequence of events if the menu cleans
|
|
|
|
|
// itself up on dismissal:
|
|
|
|
|
// 1. The menu is dismissed when selecting a menu item.
|
|
|
|
|
// 2. The deletion gets queued via deleteLater().
|
|
|
|
|
// 2. The onTriggered action gets invoked and opens a dialog box.
|
|
|
|
|
// 3. The dialog box triggers the events to be processed.
|
|
|
|
|
// 4. The menu is deleted when processing the events, while still in the event function to
|
|
|
|
|
// handle the dismissal.
|
|
|
|
|
QObject::connect(act, &QAction::triggered, parent, onTriggered, Qt::QueuedConnection);
|
2016-07-18 12:36:31 +02:00
|
|
|
return act;
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-04 16:37:59 -08:00
|
|
|
QAction *addAction(const QObject *parent, QMenu *menu, const QString &d1, const QString &d2, bool on,
|
2016-07-18 12:36:31 +02:00
|
|
|
const std::function<void()> &onTriggered)
|
|
|
|
|
{
|
2022-02-04 16:37:59 -08:00
|
|
|
return on ? addAction(parent, menu, d1, true, onTriggered) : addAction(parent, menu, d2, false);
|
2016-07-18 12:36:31 +02:00
|
|
|
};
|
|
|
|
|
|
2022-02-04 16:37:59 -08:00
|
|
|
QAction *addCheckableAction(const QObject *parent, QMenu *menu, const QString &display, bool on,
|
|
|
|
|
bool checked, const std::function<void()> &onTriggered)
|
2016-07-18 12:36:31 +02:00
|
|
|
{
|
2022-02-04 16:37:59 -08:00
|
|
|
QAction *act = addAction(parent, menu, display, on, onTriggered);
|
2016-07-18 12:36:31 +02:00
|
|
|
act->setCheckable(true);
|
|
|
|
|
act->setChecked(checked);
|
|
|
|
|
return act;
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-14 18:09:02 +01:00
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// DebugMode
|
|
|
|
|
//
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2024-07-08 09:59:33 +02:00
|
|
|
class DebugModeWidget final : public MiniSplitter
|
2009-01-13 18:15:24 +01:00
|
|
|
{
|
|
|
|
|
public:
|
2024-07-08 09:59:33 +02:00
|
|
|
DebugModeWidget()
|
2011-04-13 13:00:30 +02:00
|
|
|
{
|
2018-09-19 18:14:28 +02:00
|
|
|
DebuggerMainWindow *mainWindow = DebuggerMainWindow::instance();
|
|
|
|
|
|
|
|
|
|
auto editorHolderLayout = new QVBoxLayout;
|
2019-08-29 10:36:01 +02:00
|
|
|
editorHolderLayout->setContentsMargins(0, 0, 0, 0);
|
2018-09-19 18:14:28 +02:00
|
|
|
editorHolderLayout->setSpacing(0);
|
|
|
|
|
|
|
|
|
|
auto editorAndFindWidget = new QWidget;
|
|
|
|
|
editorAndFindWidget->setLayout(editorHolderLayout);
|
2020-11-18 22:42:51 +01:00
|
|
|
editorHolderLayout->addWidget(DebuggerMainWindow::centralWidgetStack());
|
2018-09-19 18:14:28 +02:00
|
|
|
editorHolderLayout->addWidget(new FindToolBarPlaceHolder(editorAndFindWidget));
|
|
|
|
|
|
|
|
|
|
auto documentAndRightPane = new MiniSplitter;
|
|
|
|
|
documentAndRightPane->addWidget(editorAndFindWidget);
|
|
|
|
|
documentAndRightPane->addWidget(new RightPanePlaceHolder(MODE_DEBUG));
|
|
|
|
|
documentAndRightPane->setStretchFactor(0, 1);
|
|
|
|
|
documentAndRightPane->setStretchFactor(1, 0);
|
|
|
|
|
|
2020-03-24 14:40:54 +01:00
|
|
|
auto centralEditorWidget = mainWindow->centralWidget();
|
2018-09-19 18:14:28 +02:00
|
|
|
auto centralLayout = new QVBoxLayout(centralEditorWidget);
|
|
|
|
|
centralEditorWidget->setLayout(centralLayout);
|
2019-08-29 10:36:01 +02:00
|
|
|
centralLayout->setContentsMargins(0, 0, 0, 0);
|
2018-09-19 18:14:28 +02:00
|
|
|
centralLayout->setSpacing(0);
|
|
|
|
|
centralLayout->addWidget(documentAndRightPane);
|
|
|
|
|
centralLayout->setStretch(0, 1);
|
|
|
|
|
centralLayout->setStretch(1, 0);
|
|
|
|
|
|
|
|
|
|
// Right-side window with editor, output etc.
|
|
|
|
|
auto mainWindowSplitter = new MiniSplitter;
|
|
|
|
|
mainWindowSplitter->addWidget(mainWindow);
|
|
|
|
|
mainWindowSplitter->addWidget(new OutputPanePlaceHolder(MODE_DEBUG, mainWindowSplitter));
|
|
|
|
|
auto outputPane = new OutputPanePlaceHolder(MODE_DEBUG, mainWindowSplitter);
|
2018-10-07 22:38:47 +03:00
|
|
|
outputPane->setObjectName("DebuggerOutputPanePlaceHolder");
|
2018-09-19 18:14:28 +02:00
|
|
|
mainWindowSplitter->addWidget(outputPane);
|
|
|
|
|
mainWindowSplitter->setStretchFactor(0, 10);
|
|
|
|
|
mainWindowSplitter->setStretchFactor(1, 0);
|
|
|
|
|
mainWindowSplitter->setOrientation(Qt::Vertical);
|
|
|
|
|
|
|
|
|
|
// Navigation and right-side window.
|
2024-07-08 09:59:33 +02:00
|
|
|
setFocusProxy(DebuggerMainWindow::centralWidgetStack());
|
|
|
|
|
addWidget(new NavigationWidgetPlaceHolder(MODE_DEBUG, Side::Left));
|
|
|
|
|
addWidget(mainWindowSplitter);
|
|
|
|
|
setStretchFactor(0, 0);
|
|
|
|
|
setStretchFactor(1, 1);
|
|
|
|
|
setObjectName("DebugModeWidget");
|
2018-09-19 18:14:28 +02:00
|
|
|
|
2018-09-21 10:48:49 +03:00
|
|
|
mainWindow->addSubPerspectiveSwitcher(EngineManager::engineChooser());
|
2023-08-18 15:17:11 +02:00
|
|
|
mainWindow->addSubPerspectiveSwitcher(EngineManager::dapEngineChooser());
|
2024-07-16 11:53:42 +02:00
|
|
|
|
|
|
|
|
IContext::attach(this, Context(CC::C_EDITORMANAGER));
|
2024-07-08 09:59:33 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class DebugMode final : public IMode
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
DebugMode()
|
|
|
|
|
{
|
|
|
|
|
setObjectName("DebugMode");
|
|
|
|
|
setContext(Context(C_DEBUGMODE, CC::C_NAVIGATION_PANE));
|
|
|
|
|
setDisplayName(Tr::tr("Debug"));
|
|
|
|
|
setIcon(Utils::Icon::modeIcon(Icons::MODE_DEBUGGER_CLASSIC,
|
|
|
|
|
Icons::MODE_DEBUGGER_FLAT, Icons::MODE_DEBUGGER_FLAT_ACTIVE));
|
|
|
|
|
setPriority(85);
|
|
|
|
|
setId(MODE_DEBUG);
|
2018-09-19 18:14:28 +02:00
|
|
|
|
2024-07-08 11:05:38 +02:00
|
|
|
setWidgetCreator([] { return new DebugModeWidget; });
|
2024-07-08 09:59:33 +02:00
|
|
|
setMainWindow(DebuggerMainWindow::instance());
|
2020-06-16 15:56:47 +02:00
|
|
|
|
2024-07-09 15:57:48 +02:00
|
|
|
setMenu(&DebuggerMainWindow::addPerspectiveMenu);
|
2011-04-13 13:00:30 +02:00
|
|
|
}
|
2010-06-16 11:08:54 +02:00
|
|
|
};
|
2009-01-13 18:15:24 +01:00
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Misc
|
|
|
|
|
//
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2017-01-11 17:25:58 +01:00
|
|
|
static Kit::Predicate cdbPredicate(char wordWidth = 0)
|
2012-08-23 15:23:37 +02:00
|
|
|
{
|
2014-07-23 09:09:20 +02:00
|
|
|
return [wordWidth](const Kit *k) -> bool {
|
2019-02-06 12:50:51 +01:00
|
|
|
if (DebuggerKitAspect::engineType(k) != CdbEngineType
|
|
|
|
|
|| DebuggerKitAspect::configurationErrors(k)) {
|
2012-08-23 15:23:37 +02:00
|
|
|
return false;
|
2012-09-05 14:56:08 +02:00
|
|
|
}
|
2016-07-13 10:40:05 +02:00
|
|
|
if (wordWidth)
|
2023-11-24 17:55:50 +01:00
|
|
|
return ToolchainKitAspect::targetAbi(k).wordWidth() == wordWidth;
|
2012-08-23 15:23:37 +02:00
|
|
|
return true;
|
2014-07-23 09:09:20 +02:00
|
|
|
};
|
|
|
|
|
}
|
2012-08-23 15:23:37 +02:00
|
|
|
|
2014-07-23 09:09:20 +02:00
|
|
|
// Find a CDB kit for debugging unknown processes.
|
|
|
|
|
// On a 64bit OS, prefer a 64bit debugger.
|
|
|
|
|
static Kit *findUniversalCdbKit()
|
|
|
|
|
{
|
|
|
|
|
if (Utils::is64BitWindowsSystem()) {
|
2017-01-11 17:25:58 +01:00
|
|
|
if (Kit *cdb64Kit = KitManager::kit(cdbPredicate(64)))
|
2014-07-23 09:09:20 +02:00
|
|
|
return cdb64Kit;
|
2012-08-23 15:23:37 +02:00
|
|
|
}
|
2017-01-11 17:25:58 +01:00
|
|
|
return KitManager::kit(cdbPredicate());
|
2014-07-23 09:09:20 +02:00
|
|
|
}
|
2012-08-23 15:23:37 +02:00
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
2011-02-03 14:08:01 +01:00
|
|
|
// DebuggerPluginPrivate
|
2010-06-16 11:08:54 +02:00
|
|
|
//
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2024-01-12 18:16:51 +01:00
|
|
|
class DebuggerPlugin;
|
2019-09-17 17:13:32 +02:00
|
|
|
static DebuggerPlugin *m_instance = nullptr;
|
2018-02-01 10:59:24 +01:00
|
|
|
static DebuggerPluginPrivate *dd = nullptr;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2011-02-04 15:08:31 +01:00
|
|
|
/*!
|
|
|
|
|
\class Debugger::Internal::DebuggerCore
|
|
|
|
|
|
|
|
|
|
This is the "internal" interface of the debugger plugin that's
|
|
|
|
|
used by debugger views and debugger engines. The interface is
|
|
|
|
|
implemented in DebuggerPluginPrivate.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\class Debugger::Internal::DebuggerPluginPrivate
|
|
|
|
|
|
|
|
|
|
Implementation of DebuggerCore.
|
|
|
|
|
*/
|
|
|
|
|
|
2014-10-22 13:04:47 +02:00
|
|
|
class DebuggerPluginPrivate : public QObject
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
2010-03-19 13:58:26 +01:00
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
public:
|
2019-09-17 17:13:32 +02:00
|
|
|
explicit DebuggerPluginPrivate(const QStringList &arguments);
|
2018-07-23 22:28:49 +02:00
|
|
|
~DebuggerPluginPrivate() override;
|
2010-03-10 13:46:05 +01:00
|
|
|
|
2010-12-06 08:25:29 +01:00
|
|
|
void extensionsInitialized();
|
|
|
|
|
|
2022-02-24 18:42:47 +01:00
|
|
|
RunControl *attachToRunningProcess(Kit *kit, const ProcessInfo &process, bool contAfterAttach);
|
2011-09-01 16:36:27 +02:00
|
|
|
|
2015-01-10 01:07:01 +01:00
|
|
|
void breakpointSetMarginActionTriggered(bool isMessageOnly, const ContextData &data)
|
2010-11-08 15:41:44 +01:00
|
|
|
{
|
2011-06-27 10:37:57 +02:00
|
|
|
QString message;
|
2015-01-10 01:07:01 +01:00
|
|
|
if (isMessageOnly) {
|
2015-07-20 09:37:54 +02:00
|
|
|
if (data.type == LocationByAddress) {
|
2011-06-27 10:37:57 +02:00
|
|
|
//: Message tracepoint: Address hit.
|
2022-07-05 15:37:08 +02:00
|
|
|
message = Tr::tr("0x%1 hit").arg(data.address, 0, 16);
|
2011-06-27 10:37:57 +02:00
|
|
|
} else {
|
|
|
|
|
//: Message tracepoint: %1 file, %2 line %3 function hit.
|
2022-07-05 15:37:08 +02:00
|
|
|
message = Tr::tr("%1:%2 %3() hit").arg(data.fileName.fileName()).
|
2023-06-06 15:44:59 +02:00
|
|
|
arg(data.textPosition.line).
|
|
|
|
|
arg(cppFunctionAt(data.fileName, data.textPosition.line));
|
2011-06-27 10:37:57 +02:00
|
|
|
}
|
|
|
|
|
QInputDialog dialog; // Create wide input dialog.
|
2022-07-05 15:37:08 +02:00
|
|
|
dialog.setWindowFlags(dialog.windowFlags() & ~(Qt::MSWindowsFixedSizeDialogHint));
|
2011-06-27 10:37:57 +02:00
|
|
|
dialog.resize(600, dialog.height());
|
2022-07-05 15:37:08 +02:00
|
|
|
dialog.setWindowTitle(Tr::tr("Add Message Tracepoint"));
|
|
|
|
|
dialog.setLabelText(Tr::tr("Message:"));
|
2011-06-27 10:37:57 +02:00
|
|
|
dialog.setTextValue(message);
|
|
|
|
|
if (dialog.exec() != QDialog::Accepted || dialog.textValue().isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
message = dialog.textValue();
|
|
|
|
|
}
|
2022-01-03 10:30:08 +01:00
|
|
|
BreakpointManager::setOrRemoveBreakpoint(data, message);
|
2010-11-04 09:54:23 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-17 13:04:04 +02:00
|
|
|
void addFontSizeAdaptation(QWidget *widget);
|
|
|
|
|
BaseTreeView *createBreakpointManagerView(const QByteArray &settingsKey);
|
|
|
|
|
QWidget *createBreakpointManagerWindow(BaseTreeView *breakpointManagerView,
|
|
|
|
|
const QString &title,
|
|
|
|
|
const QString &objectName);
|
|
|
|
|
|
2023-08-18 15:17:11 +02:00
|
|
|
BaseTreeView *createEngineManagerView(QAbstractItemModel *model,
|
|
|
|
|
const QString &title,
|
|
|
|
|
const QByteArray &settingsKey);
|
2023-08-17 13:04:04 +02:00
|
|
|
QWidget *createEngineManagerWindow(BaseTreeView *engineManagerView,
|
|
|
|
|
const QString &title,
|
|
|
|
|
const QString &objectName);
|
|
|
|
|
|
2023-08-18 15:17:11 +02:00
|
|
|
void createDapDebuggerPerspective(QWidget *globalLogWindow);
|
2023-08-17 13:04:04 +02:00
|
|
|
|
2015-02-03 23:58:49 +02:00
|
|
|
void editorOpened(IEditor *editor);
|
|
|
|
|
void updateBreakMenuItem(IEditor *editor);
|
|
|
|
|
void requestMark(TextEditorWidget *widget, int lineNumber,
|
|
|
|
|
TextMarkRequestKind kind);
|
|
|
|
|
void requestContextMenu(TextEditorWidget *widget,
|
2014-09-30 16:54:26 +02:00
|
|
|
int lineNumber, QMenu *menu);
|
2009-05-07 15:20:44 +02:00
|
|
|
|
2022-01-03 10:30:08 +01:00
|
|
|
void setOrRemoveBreakpoint();
|
|
|
|
|
void enableOrDisableBreakpoint();
|
2011-10-25 18:23:37 +08:00
|
|
|
void updateDebugWithoutDeployMenu();
|
2010-02-09 20:44:40 +01:00
|
|
|
|
2010-11-19 16:13:22 +01:00
|
|
|
void startRemoteCdbSession();
|
2012-08-06 12:22:35 +02:00
|
|
|
void attachToRunningApplication();
|
2013-09-20 16:48:01 +02:00
|
|
|
void attachToUnstartedApplicationDialog();
|
2011-09-13 17:26:02 +02:00
|
|
|
void attachToQmlPort();
|
2016-03-09 19:16:14 +01:00
|
|
|
void runScheduled();
|
2010-06-16 11:08:54 +02:00
|
|
|
void attachCore();
|
2021-06-23 11:24:42 +02:00
|
|
|
void reloadDebuggingHelpers();
|
2009-06-08 19:28:28 +02:00
|
|
|
|
2015-03-09 10:59:58 +02:00
|
|
|
void remoteCommand(const QStringList &options);
|
2010-11-10 11:39:01 +01:00
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
void dumpLog();
|
2010-07-05 17:08:30 +02:00
|
|
|
void setInitialState();
|
2010-06-16 11:08:54 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
void onStartupProjectChanged(Project *project);
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2011-02-08 13:48:04 +01:00
|
|
|
bool parseArgument(QStringList::const_iterator &it,
|
2012-08-09 01:50:26 +02:00
|
|
|
const QStringList::const_iterator &cend, QString *errorMessage);
|
|
|
|
|
bool parseArguments(const QStringList &args, QString *errorMessage);
|
2013-03-05 11:10:33 +01:00
|
|
|
void parseCommandLineArguments();
|
2011-02-08 13:48:04 +01:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
void updatePresetState();
|
2019-09-17 17:13:32 +02:00
|
|
|
QWidget *addSearch(BaseTreeView *treeView);
|
2012-04-18 14:20:54 +02:00
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
public:
|
2016-03-24 13:59:05 +01:00
|
|
|
QPointer<DebugMode> m_mode;
|
2016-03-02 13:57:37 +01:00
|
|
|
|
2018-02-01 10:59:24 +01:00
|
|
|
ActionContainer *m_menu = nullptr;
|
2016-02-29 12:11:18 +01:00
|
|
|
|
2017-09-07 10:40:22 +02:00
|
|
|
QVector<DebuggerRunTool *> m_scheduledStarts;
|
2010-06-16 11:08:54 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
ProxyAction m_visibleStartAction; // The fat debug button
|
|
|
|
|
ProxyAction m_hiddenStopAction;
|
|
|
|
|
QAction m_undisturbableAction;
|
|
|
|
|
OptionalAction m_startAction;
|
2023-08-18 15:17:11 +02:00
|
|
|
OptionalAction m_startDapAction;
|
2022-07-05 15:37:08 +02:00
|
|
|
QAction m_debugWithoutDeployAction{Tr::tr("Start Debugging Without Deployment")};
|
|
|
|
|
QAction m_startAndDebugApplicationAction{Tr::tr("Start and Debug External Application...")};
|
|
|
|
|
QAction m_attachToRunningApplication{Tr::tr("Attach to Running Application...")};
|
|
|
|
|
QAction m_attachToUnstartedApplication{Tr::tr("Attach to Unstarted Application...")};
|
|
|
|
|
QAction m_attachToQmlPortAction{Tr::tr("Attach to QML Port...")};
|
|
|
|
|
QAction m_attachToRemoteServerAction{Tr::tr("Attach to Running Debug Server...")};
|
|
|
|
|
QAction m_startRemoteCdbAction{Tr::tr("Attach to Remote CDB Session...")};
|
|
|
|
|
QAction m_attachToCoreAction{Tr::tr("Load Core File...")};
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
|
|
|
|
|
// In the Debug menu.
|
2022-07-05 15:37:08 +02:00
|
|
|
QAction m_startAndBreakOnMain{Tr::tr("Start and Break on Main")};
|
|
|
|
|
QAction m_watchAction{Tr::tr("Add Expression Evaluator")};
|
2018-02-01 10:59:24 +01:00
|
|
|
Command *m_watchCommand = nullptr;
|
2022-07-05 15:37:08 +02:00
|
|
|
QAction m_setOrRemoveBreakpointAction{Tr::tr("Set or Remove Breakpoint")};
|
|
|
|
|
QAction m_enableOrDisableBreakpointAction{Tr::tr("Enable or Disable Breakpoint")};
|
|
|
|
|
QAction m_reloadDebuggingHelpersAction{Tr::tr("Reload Debugging Helpers")};
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
|
|
|
|
|
BreakpointManager m_breakpointManager;
|
2010-06-16 11:08:54 +02:00
|
|
|
QString m_lastPermanentStatusMessage;
|
|
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
EngineManager m_engineManager;
|
2017-07-07 09:23:26 +03:00
|
|
|
QTimer m_shutdownTimer;
|
2019-09-17 17:13:32 +02:00
|
|
|
|
|
|
|
|
Console m_console; // ensure Debugger Console is created before settings are taken into account
|
2011-02-22 11:21:08 +01:00
|
|
|
QStringList m_arguments;
|
2018-02-01 09:07:26 +01:00
|
|
|
|
|
|
|
|
QList<IOptionsPage *> m_optionPages;
|
2018-03-13 11:25:38 +01:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
Perspective m_perspective{Constants::PRESET_PERSPECTIVE_ID, Tr::tr("Debugger")};
|
2023-08-18 15:17:11 +02:00
|
|
|
Perspective m_perspectiveDap{Constants::DAP_PERSPECTIVE_ID, Tr::tr("DAP")};
|
2019-03-14 09:17:59 +01:00
|
|
|
|
2023-01-05 08:50:37 +01:00
|
|
|
DebuggerRunWorkerFactory debuggerWorkerFactory;
|
2019-08-07 18:05:15 +02:00
|
|
|
|
|
|
|
|
// FIXME: Needed?
|
|
|
|
|
// QString mainScript = runConfig->property("mainScript").toString();
|
|
|
|
|
// const bool isDebuggableScript = mainScript.endsWith(".py"); // Only Python for now.
|
|
|
|
|
// return isDebuggableScript;
|
2010-06-16 11:08:54 +02:00
|
|
|
};
|
|
|
|
|
|
2023-08-17 13:04:04 +02:00
|
|
|
void DebuggerPluginPrivate::addFontSizeAdaptation(QWidget *widget)
|
|
|
|
|
{
|
|
|
|
|
QObject::connect(TextEditorSettings::instance(),
|
|
|
|
|
&TextEditorSettings::fontSettingsChanged,
|
|
|
|
|
this,
|
|
|
|
|
[widget](const FontSettings &fs) {
|
|
|
|
|
if (!settings().fontSizeFollowsEditor())
|
|
|
|
|
return;
|
|
|
|
|
qreal size = fs.fontZoom() * fs.fontSize() / 100.;
|
|
|
|
|
QFont font = widget->font();
|
|
|
|
|
font.setPointSizeF(size);
|
|
|
|
|
widget->setFont(font);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
BaseTreeView *DebuggerPluginPrivate::createBreakpointManagerView(const QByteArray &settingsKey)
|
|
|
|
|
{
|
|
|
|
|
auto breakpointManagerView = new BaseTreeView;
|
|
|
|
|
breakpointManagerView->setActivationMode(Utils::DoubleClickActivation);
|
|
|
|
|
breakpointManagerView->setIconSize(QSize(10, 10));
|
|
|
|
|
breakpointManagerView->setWindowIcon(Icons::BREAKPOINTS.icon());
|
|
|
|
|
breakpointManagerView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
|
|
|
breakpointManagerView->setSettings(ICore::settings(), settingsKey);
|
|
|
|
|
breakpointManagerView->setRootIsDecorated(true);
|
|
|
|
|
breakpointManagerView->setModel(BreakpointManager::model());
|
|
|
|
|
breakpointManagerView->setSpanColumn(BreakpointFunctionColumn);
|
|
|
|
|
breakpointManagerView->enableColumnHiding();
|
|
|
|
|
return breakpointManagerView;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QWidget *DebuggerPluginPrivate::createBreakpointManagerWindow(BaseTreeView *breakpointManagerView,
|
|
|
|
|
const QString &title,
|
|
|
|
|
const QString &objectName)
|
|
|
|
|
{
|
|
|
|
|
auto breakpointManagerWindow = addSearch(breakpointManagerView);
|
|
|
|
|
breakpointManagerWindow->setWindowTitle(title);
|
|
|
|
|
breakpointManagerWindow->setObjectName(objectName);
|
|
|
|
|
addFontSizeAdaptation(breakpointManagerWindow);
|
|
|
|
|
return breakpointManagerWindow;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-18 15:17:11 +02:00
|
|
|
BaseTreeView *DebuggerPluginPrivate::createEngineManagerView(QAbstractItemModel *model,
|
|
|
|
|
const QString &title,
|
|
|
|
|
const QByteArray &settingsKey)
|
2023-08-17 13:04:04 +02:00
|
|
|
{
|
|
|
|
|
auto engineManagerView = new BaseTreeView;
|
|
|
|
|
engineManagerView->setWindowTitle(title);
|
|
|
|
|
engineManagerView->setSettings(ICore::settings(), settingsKey);
|
|
|
|
|
engineManagerView->setIconSize(QSize(10, 10));
|
2023-08-18 15:17:11 +02:00
|
|
|
engineManagerView->setModel(model);
|
2023-08-17 13:04:04 +02:00
|
|
|
engineManagerView->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
|
|
|
engineManagerView->enableColumnHiding();
|
|
|
|
|
return engineManagerView;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QWidget *DebuggerPluginPrivate::createEngineManagerWindow(BaseTreeView *engineManagerView,
|
|
|
|
|
const QString &title,
|
|
|
|
|
const QString &objectName)
|
|
|
|
|
{
|
|
|
|
|
auto engineManagerWindow = addSearch(engineManagerView);
|
|
|
|
|
engineManagerWindow->setWindowTitle(title);
|
|
|
|
|
engineManagerWindow->setObjectName(objectName);
|
|
|
|
|
addFontSizeAdaptation(engineManagerWindow);
|
|
|
|
|
return engineManagerWindow;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-17 17:13:32 +02:00
|
|
|
DebuggerPluginPrivate::DebuggerPluginPrivate(const QStringList &arguments)
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
2011-01-04 15:54:36 +01:00
|
|
|
qRegisterMetaType<ContextData>("ContextData");
|
2015-05-27 13:59:56 +02:00
|
|
|
qRegisterMetaType<DebuggerRunParameters>("DebuggerRunParameters");
|
2021-07-13 13:05:36 +02:00
|
|
|
qRegisterMetaType<QString *>();
|
2011-01-04 15:54:36 +01:00
|
|
|
|
2019-09-17 17:13:32 +02:00
|
|
|
// Menu groups
|
|
|
|
|
ActionContainer *mstart = ActionManager::actionContainer(PE::M_DEBUG_STARTDEBUGGING);
|
|
|
|
|
mstart->appendGroup(MENU_GROUP_GENERAL);
|
|
|
|
|
mstart->appendGroup(MENU_GROUP_SPECIAL);
|
|
|
|
|
mstart->appendGroup(MENU_GROUP_START_QML);
|
2011-02-08 13:48:04 +01:00
|
|
|
|
2019-09-17 17:13:32 +02:00
|
|
|
// Separators
|
|
|
|
|
mstart->addSeparator(MENU_GROUP_GENERAL);
|
|
|
|
|
mstart->addSeparator(MENU_GROUP_SPECIAL);
|
2013-03-05 11:10:33 +01:00
|
|
|
|
2019-09-17 17:13:32 +02:00
|
|
|
// Task integration.
|
|
|
|
|
//: Category under which Analyzer tasks are listed in Issues view
|
2023-07-11 14:14:40 +02:00
|
|
|
TaskHub::addCategory({ANALYZERTASK_ID,
|
|
|
|
|
Tr::tr("Valgrind"),
|
|
|
|
|
Tr::tr("Issues that the Valgrind tools found when analyzing the code.")});
|
2018-10-17 10:08:20 +02:00
|
|
|
|
|
|
|
|
const Context debuggerNotRunning(C_DEBUGGER_NOTRUNNING);
|
|
|
|
|
ICore::addAdditionalContext(debuggerNotRunning);
|
|
|
|
|
|
2011-02-22 11:21:08 +01:00
|
|
|
m_arguments = arguments;
|
2024-02-02 08:48:30 +01:00
|
|
|
if (!m_arguments.isEmpty()) {
|
|
|
|
|
connect(SessionManager::instance(), &SessionManager::startupSessionRestored,
|
2014-10-22 13:04:47 +02:00
|
|
|
this, &DebuggerPluginPrivate::parseCommandLineArguments);
|
2024-02-02 08:48:30 +01:00
|
|
|
}
|
2015-11-10 16:59:02 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
// Menus
|
|
|
|
|
m_menu = ActionManager::createMenu(M_DEBUG_ANALYZER);
|
2022-07-05 15:37:08 +02:00
|
|
|
m_menu->menu()->setTitle(Tr::tr("&Analyze"));
|
2016-03-02 13:57:37 +01:00
|
|
|
m_menu->menu()->setEnabled(true);
|
|
|
|
|
|
|
|
|
|
m_menu->appendGroup(G_ANALYZER_CONTROL);
|
|
|
|
|
m_menu->appendGroup(G_ANALYZER_TOOLS);
|
|
|
|
|
m_menu->appendGroup(G_ANALYZER_REMOTE_TOOLS);
|
|
|
|
|
m_menu->appendGroup(G_ANALYZER_OPTIONS);
|
|
|
|
|
|
Add macOS touch bar support
Introduce a generic Utils::TouchBar that implements a touch bar for
macOS based on QAction. Touch bars can be nested, and one is set to be
the application's top level touch bar.
Also add an ActionContainer for the touch bar. That allows us to manage
the layout of the touch bar the same way we do with menus.
Since the touch bar is an input device with very limited space, a
command in the touch bar needs to be specifically styled for the touch
bar by setting either touchBarText or touchBarIcon (or both).
Touch bars can be nested by nesting the ActionContainers. A nested touch
bar ActionContainer needs to specify an icon and/or text to show in the
touch bar button that opens that sub-bar.
Commands are only shown in the touch bar if they are valid within the
current context.
Implementation-wise we cannot use the standard NSPopoverTouchBarItem for
nesting touch bar levels. We cannot hide items in the touch bar, because
hidden items still take up space in the touch bar. So we need to rebuild
the touch bar regularly. Since the items we show are very dynamic, every
time the items in the toplevel bar change because of a context change,
any opened sub-level touch bar closes. That is why we maintain a stack of
touch bar levels ourselves, replacing the main touch bar with the current
level, and managing opening and closing the levels manually.
This patch adds buttons for Help, Bookmarks, Header/Source, Follow
(Symbol), Decl/Def, and a sub-bar for the debugger actions.
Fixes: QTCREATORBUG-21263
Change-Id: Ib63e610f21a993f1d324fe23c83a7f2224f434ac
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
2018-10-05 13:52:57 +02:00
|
|
|
ActionContainer *touchBar = ActionManager::createTouchBar("Debugger.TouchBar",
|
|
|
|
|
Icons::MACOS_TOUCHBAR_DEBUG.icon());
|
|
|
|
|
ActionManager::actionContainer(Core::Constants::TOUCH_BAR)
|
|
|
|
|
->addMenu(touchBar, Core::Constants::G_TOUCHBAR_OTHER);
|
|
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
ActionContainer *menubar = ActionManager::actionContainer(MENU_BAR);
|
|
|
|
|
ActionContainer *mtools = ActionManager::actionContainer(M_TOOLS);
|
2022-02-14 12:11:30 +01:00
|
|
|
if (!hideAnalyzeMenu())
|
|
|
|
|
menubar->addMenu(mtools, m_menu);
|
2016-03-02 13:57:37 +01:00
|
|
|
|
|
|
|
|
m_menu->addSeparator(G_ANALYZER_TOOLS);
|
|
|
|
|
m_menu->addSeparator(G_ANALYZER_REMOTE_TOOLS);
|
|
|
|
|
m_menu->addSeparator(G_ANALYZER_OPTIONS);
|
|
|
|
|
|
2018-10-23 15:32:33 +02:00
|
|
|
QAction *act;
|
|
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
// Populate Windows->Views menu with standard actions.
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(Tr::tr("Memory..."), this);
|
2018-11-12 12:46:33 +01:00
|
|
|
act->setVisible(false);
|
|
|
|
|
act->setEnabled(false);
|
|
|
|
|
Command *cmd = ActionManager::registerAction(act, Constants::OPEN_MEMORY_EDITOR);
|
2016-03-01 07:51:06 +01:00
|
|
|
|
2023-07-11 14:14:40 +02:00
|
|
|
TaskHub::addCategory({TASK_CATEGORY_DEBUGGER_RUNTIME,
|
|
|
|
|
Tr::tr("Debugger Runtime"),
|
|
|
|
|
Tr::tr("Issues with starting the debugger.")});
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2023-08-17 13:04:04 +02:00
|
|
|
auto breakpointManagerView = createBreakpointManagerView("Debugger.BreakWindow");
|
|
|
|
|
auto breakpointManagerWindow
|
|
|
|
|
= createBreakpointManagerWindow(breakpointManagerView,
|
|
|
|
|
Tr::tr("Breakpoint Preset"),
|
|
|
|
|
"Debugger.Docks.BreakpointManager");
|
2018-11-12 16:00:54 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
// Snapshot
|
2023-08-18 15:17:11 +02:00
|
|
|
auto engineManagerView = createEngineManagerView(EngineManager::model(),
|
|
|
|
|
Tr::tr("Running Debuggers"),
|
2023-08-17 13:04:04 +02:00
|
|
|
"Debugger.SnapshotView");
|
|
|
|
|
auto engineManagerWindow = createEngineManagerWindow(engineManagerView,
|
|
|
|
|
Tr::tr("Debugger Perspectives"),
|
|
|
|
|
"Debugger.Docks.Snapshots");
|
2010-06-16 11:08:54 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
// Logging
|
2019-09-17 16:16:30 +02:00
|
|
|
auto globalLogWindow = new GlobalLogWindow;
|
|
|
|
|
addFontSizeAdaptation(globalLogWindow);
|
2010-09-22 12:25:42 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
ActionContainer *debugMenu = ActionManager::actionContainer(PE::M_DEBUG);
|
2011-02-04 14:36:50 +01:00
|
|
|
|
2017-07-14 09:36:09 +02:00
|
|
|
RunConfiguration::registerAspect<DebuggerRunConfigurationAspect>();
|
2010-06-16 11:08:54 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
// The main "Start Debugging" action. Acts as "Continue" at times.
|
|
|
|
|
connect(&m_startAction, &QAction::triggered, this, [] {
|
|
|
|
|
ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE, false);
|
|
|
|
|
});
|
2010-08-18 13:54:12 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
connect(&m_debugWithoutDeployAction, &QAction::triggered, this, [] {
|
|
|
|
|
ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE, true);
|
|
|
|
|
});
|
2010-08-26 16:02:41 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
connect(&m_startAndDebugApplicationAction, &QAction::triggered,
|
|
|
|
|
this, &StartApplicationDialog::startAndDebugApplication);
|
2015-01-10 01:07:01 +01:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
connect(&m_attachToCoreAction, &QAction::triggered,
|
|
|
|
|
this, &DebuggerPluginPrivate::attachCore);
|
2015-01-10 01:07:01 +01:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
connect(&m_attachToRemoteServerAction, &QAction::triggered,
|
|
|
|
|
this, &StartApplicationDialog::attachToRemoteServer);
|
2010-06-16 11:08:54 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
connect(&m_attachToRunningApplication, &QAction::triggered,
|
|
|
|
|
this, &DebuggerPluginPrivate::attachToRunningApplication);
|
2010-06-16 11:08:54 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
connect(&m_attachToUnstartedApplication, &QAction::triggered,
|
|
|
|
|
this, &DebuggerPluginPrivate::attachToUnstartedApplicationDialog);
|
2010-11-09 10:23:10 +01:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
connect(&m_attachToQmlPortAction, &QAction::triggered,
|
|
|
|
|
this, &DebuggerPluginPrivate::attachToQmlPort);
|
2010-12-01 15:41:08 +01:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
connect(&m_startRemoteCdbAction, &QAction::triggered,
|
|
|
|
|
this, &DebuggerPluginPrivate::startRemoteCdbSession);
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
// "Start Debugging" sub-menu
|
|
|
|
|
// groups:
|
|
|
|
|
// G_DEFAULT_ONE
|
2019-02-18 15:49:05 +01:00
|
|
|
// MENU_GROUP_START_LOCAL
|
|
|
|
|
// MENU_GROUP_START_REMOTE
|
|
|
|
|
// MENU_GROUP_START_QML
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
const QKeySequence startShortcut(useMacShortcuts ? Tr::tr("Ctrl+Y") : Tr::tr("F5"));
|
2018-10-25 15:24:39 +02:00
|
|
|
|
2019-02-18 15:49:05 +01:00
|
|
|
cmd = ActionManager::registerAction(&m_visibleStartAction, "Debugger.Debug");
|
|
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDescription(Tr::tr("Start Debugging or Continue"));
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
cmd->setAttribute(Command::CA_UpdateText);
|
|
|
|
|
cmd->setAttribute(Command::CA_UpdateIcon);
|
|
|
|
|
//mstart->addAction(cmd, CC::G_DEFAULT_ONE);
|
|
|
|
|
|
2018-10-25 15:24:39 +02:00
|
|
|
cmd = ActionManager::registerAction(&m_startAction, DEBUGGER_START);
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDescription(Tr::tr("Start Debugging"));
|
2016-03-02 13:57:37 +01:00
|
|
|
cmd->setAttribute(Command::CA_UpdateText);
|
2018-10-25 15:24:39 +02:00
|
|
|
cmd->setDefaultKeySequence(startShortcut);
|
2016-03-02 13:57:37 +01:00
|
|
|
mstart->addAction(cmd, CC::G_DEFAULT_ONE);
|
2010-06-16 11:08:54 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
m_visibleStartAction.initialize(&m_startAction);
|
|
|
|
|
m_visibleStartAction.setAttribute(ProxyAction::UpdateText);
|
2018-10-04 15:34:12 +02:00
|
|
|
m_visibleStartAction.setAttribute(ProxyAction::UpdateIcon);
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
m_visibleStartAction.setAction(&m_startAction);
|
2011-10-06 17:38:28 +02:00
|
|
|
|
2018-12-10 17:10:17 +01:00
|
|
|
m_visibleStartAction.setObjectName("Debug"); // used for UI introduction
|
2022-05-16 20:39:20 +02:00
|
|
|
|
|
|
|
|
if (!hideDebugMenu())
|
|
|
|
|
ModeManager::addAction(&m_visibleStartAction, /*priority*/ 90);
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
|
2018-10-04 15:34:12 +02:00
|
|
|
m_undisturbableAction.setIcon(interruptIcon(false));
|
|
|
|
|
m_undisturbableAction.setEnabled(false);
|
|
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
cmd = ActionManager::registerAction(&m_debugWithoutDeployAction,
|
2016-03-02 13:57:37 +01:00
|
|
|
"Debugger.DebugWithoutDeploy");
|
|
|
|
|
cmd->setAttribute(Command::CA_Hide);
|
|
|
|
|
mstart->addAction(cmd, CC::G_DEFAULT_ONE);
|
2010-11-12 20:18:29 +01:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
cmd = ActionManager::registerAction(&m_attachToRunningApplication,
|
2016-03-02 13:57:37 +01:00
|
|
|
"Debugger.AttachToRemoteProcess");
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDescription(Tr::tr("Attach to Running Application"));
|
2019-02-18 15:49:05 +01:00
|
|
|
mstart->addAction(cmd, MENU_GROUP_GENERAL);
|
2009-06-04 16:06:12 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
cmd = ActionManager::registerAction(&m_attachToUnstartedApplication,
|
2016-03-02 13:57:37 +01:00
|
|
|
"Debugger.AttachToUnstartedProcess");
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDescription(Tr::tr("Attach to Unstarted Application"));
|
2019-02-18 15:49:05 +01:00
|
|
|
mstart->addAction(cmd, MENU_GROUP_GENERAL);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
cmd = ActionManager::registerAction(&m_startAndDebugApplicationAction,
|
2016-03-02 13:57:37 +01:00
|
|
|
"Debugger.StartAndDebugApplication");
|
|
|
|
|
cmd->setAttribute(Command::CA_Hide);
|
2019-02-18 15:49:05 +01:00
|
|
|
mstart->addAction(cmd, MENU_GROUP_GENERAL);
|
2010-12-01 15:41:08 +01:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
cmd = ActionManager::registerAction(&m_attachToCoreAction,
|
|
|
|
|
"Debugger.AttachCore");
|
2016-03-02 13:57:37 +01:00
|
|
|
cmd->setAttribute(Command::CA_Hide);
|
2019-02-18 15:49:05 +01:00
|
|
|
mstart->addAction(cmd, MENU_GROUP_GENERAL);
|
2009-03-02 15:14:12 +01:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
cmd = ActionManager::registerAction(&m_attachToRemoteServerAction,
|
|
|
|
|
"Debugger.AttachToRemoteServer");
|
2016-03-02 13:57:37 +01:00
|
|
|
cmd->setAttribute(Command::CA_Hide);
|
2019-02-18 15:49:05 +01:00
|
|
|
mstart->addAction(cmd, MENU_GROUP_SPECIAL);
|
2012-06-12 13:29:37 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
if (HostOsInfo::isWindowsHost()) {
|
|
|
|
|
cmd = ActionManager::registerAction(&m_startRemoteCdbAction,
|
2016-03-02 13:57:37 +01:00
|
|
|
"Debugger.AttachRemoteCdb");
|
|
|
|
|
cmd->setAttribute(Command::CA_Hide);
|
2019-02-18 15:49:05 +01:00
|
|
|
mstart->addAction(cmd, MENU_GROUP_SPECIAL);
|
2010-12-02 13:20:06 +01:00
|
|
|
}
|
2010-05-05 12:41:52 +02:00
|
|
|
|
2019-02-18 15:49:05 +01:00
|
|
|
mstart->addSeparator(Context(CC::C_GLOBAL), MENU_GROUP_START_QML);
|
2009-05-07 17:11:19 +02:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
cmd = ActionManager::registerAction(&m_attachToQmlPortAction, "Debugger.AttachToQmlPort");
|
2016-03-02 13:57:37 +01:00
|
|
|
cmd->setAttribute(Command::CA_Hide);
|
2019-02-18 15:49:05 +01:00
|
|
|
mstart->addAction(cmd, MENU_GROUP_START_QML);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(Tr::tr("Detach Debugger"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::DETACH);
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
|
2010-07-22 10:23:27 +02:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(interruptIcon(false), Tr::tr("Interrupt"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::INTERRUPT);
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDescription(Tr::tr("Interrupt Debugger"));
|
2018-10-23 15:32:33 +02:00
|
|
|
cmd->setAttribute(Command::CA_UpdateText);
|
2018-10-25 15:24:39 +02:00
|
|
|
cmd->setDefaultKeySequence(startShortcut);
|
Add macOS touch bar support
Introduce a generic Utils::TouchBar that implements a touch bar for
macOS based on QAction. Touch bars can be nested, and one is set to be
the application's top level touch bar.
Also add an ActionContainer for the touch bar. That allows us to manage
the layout of the touch bar the same way we do with menus.
Since the touch bar is an input device with very limited space, a
command in the touch bar needs to be specifically styled for the touch
bar by setting either touchBarText or touchBarIcon (or both).
Touch bars can be nested by nesting the ActionContainers. A nested touch
bar ActionContainer needs to specify an icon and/or text to show in the
touch bar button that opens that sub-bar.
Commands are only shown in the touch bar if they are valid within the
current context.
Implementation-wise we cannot use the standard NSPopoverTouchBarItem for
nesting touch bar levels. We cannot hide items in the touch bar, because
hidden items still take up space in the touch bar. So we need to rebuild
the touch bar regularly. Since the items we show are very dynamic, every
time the items in the toplevel bar change because of a context change,
any opened sub-level touch bar closes. That is why we maintain a stack of
touch bar levels ourselves, replacing the main touch bar with the current
level, and managing opening and closing the levels manually.
This patch adds buttons for Help, Bookmarks, Header/Source, Follow
(Symbol), Decl/Def, and a sub-bar for the debugger actions.
Fixes: QTCREATORBUG-21263
Change-Id: Ib63e610f21a993f1d324fe23c83a7f2224f434ac
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
2018-10-05 13:52:57 +02:00
|
|
|
cmd->setTouchBarIcon(Icons::MACOS_TOUCHBAR_DEBUG_INTERRUPT.icon());
|
|
|
|
|
touchBar->addAction(cmd);
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
|
2010-10-05 12:47:23 +02:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(continueIcon(false), Tr::tr("Continue"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::CONTINUE);
|
|
|
|
|
cmd->setAttribute(Command::CA_UpdateText);
|
2018-10-25 15:24:39 +02:00
|
|
|
cmd->setDefaultKeySequence(startShortcut);
|
Add macOS touch bar support
Introduce a generic Utils::TouchBar that implements a touch bar for
macOS based on QAction. Touch bars can be nested, and one is set to be
the application's top level touch bar.
Also add an ActionContainer for the touch bar. That allows us to manage
the layout of the touch bar the same way we do with menus.
Since the touch bar is an input device with very limited space, a
command in the touch bar needs to be specifically styled for the touch
bar by setting either touchBarText or touchBarIcon (or both).
Touch bars can be nested by nesting the ActionContainers. A nested touch
bar ActionContainer needs to specify an icon and/or text to show in the
touch bar button that opens that sub-bar.
Commands are only shown in the touch bar if they are valid within the
current context.
Implementation-wise we cannot use the standard NSPopoverTouchBarItem for
nesting touch bar levels. We cannot hide items in the touch bar, because
hidden items still take up space in the touch bar. So we need to rebuild
the touch bar regularly. Since the items we show are very dynamic, every
time the items in the toplevel bar change because of a context change,
any opened sub-level touch bar closes. That is why we maintain a stack of
touch bar levels ourselves, replacing the main touch bar with the current
level, and managing opening and closing the levels manually.
This patch adds buttons for Help, Bookmarks, Header/Source, Follow
(Symbol), Decl/Def, and a sub-bar for the debugger actions.
Fixes: QTCREATORBUG-21263
Change-Id: Ib63e610f21a993f1d324fe23c83a7f2224f434ac
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
2018-10-05 13:52:57 +02:00
|
|
|
cmd->setTouchBarIcon(Icons::MACOS_TOUCHBAR_DEBUG_CONTINUE.icon());
|
|
|
|
|
touchBar->addAction(cmd);
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2019-04-03 14:31:43 +02:00
|
|
|
const QIcon sidebarStopIcon = Icon::sideBarIcon(Icons::STOP, Icons::STOP_FLAT);
|
|
|
|
|
const QIcon stopIcon = Icon::combinedIcon({Icons::DEBUG_EXIT_SMALL.icon(), sidebarStopIcon});
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(stopIcon, Tr::tr("Stop Debugger"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::STOP);
|
Add macOS touch bar support
Introduce a generic Utils::TouchBar that implements a touch bar for
macOS based on QAction. Touch bars can be nested, and one is set to be
the application's top level touch bar.
Also add an ActionContainer for the touch bar. That allows us to manage
the layout of the touch bar the same way we do with menus.
Since the touch bar is an input device with very limited space, a
command in the touch bar needs to be specifically styled for the touch
bar by setting either touchBarText or touchBarIcon (or both).
Touch bars can be nested by nesting the ActionContainers. A nested touch
bar ActionContainer needs to specify an icon and/or text to show in the
touch bar button that opens that sub-bar.
Commands are only shown in the touch bar if they are valid within the
current context.
Implementation-wise we cannot use the standard NSPopoverTouchBarItem for
nesting touch bar levels. We cannot hide items in the touch bar, because
hidden items still take up space in the touch bar. So we need to rebuild
the touch bar regularly. Since the items we show are very dynamic, every
time the items in the toplevel bar change because of a context change,
any opened sub-level touch bar closes. That is why we maintain a stack of
touch bar levels ourselves, replacing the main touch bar with the current
level, and managing opening and closing the levels manually.
This patch adds buttons for Help, Bookmarks, Header/Source, Follow
(Symbol), Decl/Def, and a sub-bar for the debugger actions.
Fixes: QTCREATORBUG-21263
Change-Id: Ib63e610f21a993f1d324fe23c83a7f2224f434ac
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
2018-10-05 13:52:57 +02:00
|
|
|
cmd->setTouchBarIcon(Icons::MACOS_TOUCHBAR_DEBUG_EXIT.icon());
|
|
|
|
|
touchBar->addAction(cmd);
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
m_hiddenStopAction.initialize(cmd->action());
|
|
|
|
|
m_hiddenStopAction.setAttribute(ProxyAction::UpdateText);
|
|
|
|
|
m_hiddenStopAction.setAttribute(ProxyAction::UpdateIcon);
|
2011-02-04 14:36:50 +01:00
|
|
|
|
2018-11-09 13:45:48 +01:00
|
|
|
cmd = ActionManager::registerAction(&m_hiddenStopAction, "Debugger.HiddenStop");
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Shift+Ctrl+Y") : Tr::tr("Shift+F5")));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(Tr::tr("Abort Debugging"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::ABORT);
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDescription(Tr::tr("Reset Debugger"));
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(Icons::RESTART_TOOLBAR.icon(), Tr::tr("Restart Debugging"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
2022-07-05 15:37:08 +02:00
|
|
|
act->setToolTip(Tr::tr("Restart the debugging session."));
|
2018-10-23 15:32:33 +02:00
|
|
|
cmd = ActionManager::registerAction(act, Constants::RESET);
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDescription(Tr::tr("Restart Debugging"));
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addSeparator();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2018-10-17 10:08:20 +02:00
|
|
|
cmd = ActionManager::registerAction(&m_startAndBreakOnMain,
|
2018-11-09 13:45:48 +01:00
|
|
|
"Debugger.StartAndBreakOnMain",
|
2018-10-17 10:08:20 +02:00
|
|
|
debuggerNotRunning);
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Shift+O") : Tr::tr("F10")));
|
2016-03-02 13:57:37 +01:00
|
|
|
cmd->setAttribute(Command::CA_Hide);
|
|
|
|
|
debugMenu->addAction(cmd);
|
2018-10-17 10:08:20 +02:00
|
|
|
connect(&m_startAndBreakOnMain, &QAction::triggered, this, [] {
|
|
|
|
|
DebuggerRunTool::setBreakOnMainNextTime();
|
|
|
|
|
ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE, false);
|
|
|
|
|
});
|
|
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(Icons::STEP_OVER.icon(), Tr::tr("Step Over"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::NEXT);
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Shift+O") : Tr::tr("F10")));
|
Add macOS touch bar support
Introduce a generic Utils::TouchBar that implements a touch bar for
macOS based on QAction. Touch bars can be nested, and one is set to be
the application's top level touch bar.
Also add an ActionContainer for the touch bar. That allows us to manage
the layout of the touch bar the same way we do with menus.
Since the touch bar is an input device with very limited space, a
command in the touch bar needs to be specifically styled for the touch
bar by setting either touchBarText or touchBarIcon (or both).
Touch bars can be nested by nesting the ActionContainers. A nested touch
bar ActionContainer needs to specify an icon and/or text to show in the
touch bar button that opens that sub-bar.
Commands are only shown in the touch bar if they are valid within the
current context.
Implementation-wise we cannot use the standard NSPopoverTouchBarItem for
nesting touch bar levels. We cannot hide items in the touch bar, because
hidden items still take up space in the touch bar. So we need to rebuild
the touch bar regularly. Since the items we show are very dynamic, every
time the items in the toplevel bar change because of a context change,
any opened sub-level touch bar closes. That is why we maintain a stack of
touch bar levels ourselves, replacing the main touch bar with the current
level, and managing opening and closing the levels manually.
This patch adds buttons for Help, Bookmarks, Header/Source, Follow
(Symbol), Decl/Def, and a sub-bar for the debugger actions.
Fixes: QTCREATORBUG-21263
Change-Id: Ib63e610f21a993f1d324fe23c83a7f2224f434ac
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
2018-10-05 13:52:57 +02:00
|
|
|
cmd->setTouchBarIcon(Icons::MACOS_TOUCHBAR_DEBUG_STEP_OVER.icon());
|
|
|
|
|
touchBar->addAction(cmd);
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd);
|
2010-03-18 10:56:25 +01:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(Icons::STEP_INTO.icon(), Tr::tr("Step Into"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::STEP);
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Shift+I") : Tr::tr("F11")));
|
Add macOS touch bar support
Introduce a generic Utils::TouchBar that implements a touch bar for
macOS based on QAction. Touch bars can be nested, and one is set to be
the application's top level touch bar.
Also add an ActionContainer for the touch bar. That allows us to manage
the layout of the touch bar the same way we do with menus.
Since the touch bar is an input device with very limited space, a
command in the touch bar needs to be specifically styled for the touch
bar by setting either touchBarText or touchBarIcon (or both).
Touch bars can be nested by nesting the ActionContainers. A nested touch
bar ActionContainer needs to specify an icon and/or text to show in the
touch bar button that opens that sub-bar.
Commands are only shown in the touch bar if they are valid within the
current context.
Implementation-wise we cannot use the standard NSPopoverTouchBarItem for
nesting touch bar levels. We cannot hide items in the touch bar, because
hidden items still take up space in the touch bar. So we need to rebuild
the touch bar regularly. Since the items we show are very dynamic, every
time the items in the toplevel bar change because of a context change,
any opened sub-level touch bar closes. That is why we maintain a stack of
touch bar levels ourselves, replacing the main touch bar with the current
level, and managing opening and closing the levels manually.
This patch adds buttons for Help, Bookmarks, Header/Source, Follow
(Symbol), Decl/Def, and a sub-bar for the debugger actions.
Fixes: QTCREATORBUG-21263
Change-Id: Ib63e610f21a993f1d324fe23c83a7f2224f434ac
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
2018-10-05 13:52:57 +02:00
|
|
|
cmd->setTouchBarIcon(Icons::MACOS_TOUCHBAR_DEBUG_STEP_INTO.icon());
|
|
|
|
|
touchBar->addAction(cmd);
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(Icons::STEP_OUT.icon(), Tr::tr("Step Out"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::STEPOUT);
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Shift+T") : Tr::tr("Shift+F11")));
|
Add macOS touch bar support
Introduce a generic Utils::TouchBar that implements a touch bar for
macOS based on QAction. Touch bars can be nested, and one is set to be
the application's top level touch bar.
Also add an ActionContainer for the touch bar. That allows us to manage
the layout of the touch bar the same way we do with menus.
Since the touch bar is an input device with very limited space, a
command in the touch bar needs to be specifically styled for the touch
bar by setting either touchBarText or touchBarIcon (or both).
Touch bars can be nested by nesting the ActionContainers. A nested touch
bar ActionContainer needs to specify an icon and/or text to show in the
touch bar button that opens that sub-bar.
Commands are only shown in the touch bar if they are valid within the
current context.
Implementation-wise we cannot use the standard NSPopoverTouchBarItem for
nesting touch bar levels. We cannot hide items in the touch bar, because
hidden items still take up space in the touch bar. So we need to rebuild
the touch bar regularly. Since the items we show are very dynamic, every
time the items in the toplevel bar change because of a context change,
any opened sub-level touch bar closes. That is why we maintain a stack of
touch bar levels ourselves, replacing the main touch bar with the current
level, and managing opening and closing the levels manually.
This patch adds buttons for Help, Bookmarks, Header/Source, Follow
(Symbol), Decl/Def, and a sub-bar for the debugger actions.
Fixes: QTCREATORBUG-21263
Change-Id: Ib63e610f21a993f1d324fe23c83a7f2224f434ac
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
2018-10-05 13:52:57 +02:00
|
|
|
cmd->setTouchBarIcon(Icons::MACOS_TOUCHBAR_DEBUG_STEP_OUT.icon());
|
|
|
|
|
touchBar->addAction(cmd);
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd);
|
2010-12-02 13:20:06 +01:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(Tr::tr("Run to Line"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
act->setVisible(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::RUNTOLINE);
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Shift+F8") : Tr::tr("Ctrl+F10")));
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd);
|
2010-03-18 10:56:25 +01:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(Tr::tr("Run to Selected Function"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
act->setEnabled(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::RUNTOSELECTEDFUNCTION);
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+F6")));
|
2016-03-02 13:57:37 +01:00
|
|
|
// Don't add to menu by default as keeping its enabled state
|
|
|
|
|
// and text up-to-date is a lot of hassle.
|
|
|
|
|
// debugMenu->addAction(cmd);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(Tr::tr("Jump to Line"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
act->setVisible(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::JUMPTOLINE);
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd);
|
2012-03-26 17:30:57 +02:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
act = new QAction(Tr::tr("Immediately Return From Inner Function"), this);
|
2018-10-23 15:32:33 +02:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
act->setVisible(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::RETURNFROMFUNCTION);
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd);
|
2010-03-18 10:56:25 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addSeparator();
|
2010-03-18 10:56:25 +01:00
|
|
|
|
2018-11-12 12:46:33 +01:00
|
|
|
act = new QAction(this);
|
2023-02-09 11:43:49 +01:00
|
|
|
act->setText(Tr::tr("Move to Calling Frame"));
|
2018-11-12 12:46:33 +01:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
act->setVisible(false);
|
|
|
|
|
ActionManager::registerAction(act, Constants::FRAME_UP);
|
2009-05-25 17:19:42 +02:00
|
|
|
|
2018-11-12 12:46:33 +01:00
|
|
|
act = new QAction(this);
|
2023-02-09 11:43:49 +01:00
|
|
|
act->setText(Tr::tr("Move to Called Frame"));
|
2018-11-12 12:46:33 +01:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
act->setVisible(false);
|
|
|
|
|
ActionManager::registerAction(act, Constants::FRAME_DOWN);
|
2010-03-18 10:56:25 +01:00
|
|
|
|
2018-11-12 12:46:33 +01:00
|
|
|
act = new QAction(this);
|
2023-02-09 11:43:49 +01:00
|
|
|
act->setText(Tr::tr("Operate by Instruction"));
|
2018-11-12 12:46:33 +01:00
|
|
|
act->setEnabled(false);
|
|
|
|
|
act->setVisible(false);
|
|
|
|
|
act->setCheckable(true);
|
|
|
|
|
act->setChecked(false);
|
|
|
|
|
cmd = ActionManager::registerAction(act, Constants::OPERATE_BY_INSTRUCTION);
|
|
|
|
|
debugMenu->addAction(cmd);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2022-01-03 10:30:08 +01:00
|
|
|
cmd = ActionManager::registerAction(&m_setOrRemoveBreakpointAction, "Debugger.ToggleBreak");
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("F8") : Tr::tr("F9")));
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd);
|
2022-01-03 10:30:08 +01:00
|
|
|
connect(&m_setOrRemoveBreakpointAction, &QAction::triggered,
|
|
|
|
|
this, &DebuggerPluginPrivate::setOrRemoveBreakpoint);
|
|
|
|
|
|
|
|
|
|
cmd = ActionManager::registerAction(&m_enableOrDisableBreakpointAction,
|
|
|
|
|
"Debugger.EnableOrDisableBreakpoint");
|
2022-07-05 15:37:08 +02:00
|
|
|
cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+F8") : Tr::tr("Ctrl+F9")));
|
2022-01-03 10:30:08 +01:00
|
|
|
debugMenu->addAction(cmd);
|
|
|
|
|
connect(&m_enableOrDisableBreakpointAction, &QAction::triggered,
|
|
|
|
|
this, &DebuggerPluginPrivate::enableOrDisableBreakpoint);
|
2011-05-02 18:22:32 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addSeparator();
|
2010-03-18 10:56:25 +01:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
auto qmlShowAppOnTopDummyAction = new QAction(Tr::tr("Show Application on Top"), this);
|
2016-03-02 13:57:37 +01:00
|
|
|
qmlShowAppOnTopDummyAction->setCheckable(true);
|
|
|
|
|
qmlShowAppOnTopDummyAction->setIcon(Icons::APP_ON_TOP.icon());
|
|
|
|
|
qmlShowAppOnTopDummyAction->setEnabled(false);
|
|
|
|
|
cmd = ActionManager::registerAction(qmlShowAppOnTopDummyAction, Constants::QML_SHOW_APP_ON_TOP);
|
|
|
|
|
debugMenu->addAction(cmd);
|
2010-03-18 10:56:25 +01:00
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
auto qmlSelectDummyAction = new QAction(Tr::tr("Select"), this);
|
2016-03-02 13:57:37 +01:00
|
|
|
qmlSelectDummyAction->setCheckable(true);
|
|
|
|
|
qmlSelectDummyAction->setIcon(Icons::SELECT.icon());
|
|
|
|
|
qmlSelectDummyAction->setEnabled(false);
|
|
|
|
|
cmd = ActionManager::registerAction(qmlSelectDummyAction, Constants::QML_SELECTTOOL);
|
|
|
|
|
debugMenu->addAction(cmd);
|
2010-03-18 10:56:25 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addSeparator();
|
2011-07-18 17:23:42 +02:00
|
|
|
|
2021-06-23 11:24:42 +02:00
|
|
|
ActionManager::registerAction(&m_reloadDebuggingHelpersAction, Constants::RELOAD_DEBUGGING_HELPERS);
|
|
|
|
|
connect(&m_reloadDebuggingHelpersAction, &QAction::triggered,
|
|
|
|
|
this, &DebuggerPluginPrivate::reloadDebuggingHelpers);
|
|
|
|
|
|
2018-11-12 12:46:33 +01:00
|
|
|
cmd = m_watchCommand = ActionManager::registerAction(&m_watchAction, Constants::WATCH);
|
2016-03-02 13:57:37 +01:00
|
|
|
debugMenu->addAction(cmd);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2018-11-12 12:46:33 +01:00
|
|
|
// FIXME: Re-vive watcher creation before engine runs.
|
|
|
|
|
// connect(&m_watchAction, &QAction::triggered, this, [&] {
|
|
|
|
|
// QTC_CHECK(false);
|
|
|
|
|
// });
|
|
|
|
|
|
2018-02-01 09:07:26 +01:00
|
|
|
addCdbOptionPages(&m_optionPages);
|
2010-02-08 09:13:21 +01:00
|
|
|
|
2019-03-14 12:21:47 +01:00
|
|
|
connect(ModeManager::instance(), &ModeManager::currentModeAboutToChange, this, [] {
|
|
|
|
|
if (ModeManager::currentModeId() == MODE_DEBUG)
|
|
|
|
|
DebuggerMainWindow::leaveDebugMode();
|
|
|
|
|
});
|
|
|
|
|
|
2022-12-07 23:20:02 +01:00
|
|
|
connect(ModeManager::instance(), &ModeManager::currentModeChanged,
|
|
|
|
|
this, [](Id mode, Id oldMode) {
|
2019-03-22 07:35:48 +01:00
|
|
|
QTC_ASSERT(mode != oldMode, return);
|
2019-03-14 12:21:47 +01:00
|
|
|
if (mode == MODE_DEBUG) {
|
|
|
|
|
DebuggerMainWindow::enterDebugMode();
|
|
|
|
|
if (IEditor *editor = EditorManager::currentEditor())
|
|
|
|
|
editor->widget()->setFocus();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
|
|
|
|
|
this, &DebuggerPluginPrivate::updateDebugWithoutDeployMenu);
|
2012-05-08 09:43:14 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
// Debug mode setup
|
2016-03-24 13:59:05 +01:00
|
|
|
m_mode = new DebugMode;
|
2010-11-26 15:10:10 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
//
|
|
|
|
|
// Connections
|
|
|
|
|
//
|
2010-11-23 16:42:46 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
// ProjectExplorer
|
2020-02-24 15:55:15 +01:00
|
|
|
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::runActionsUpdated,
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
this, &DebuggerPluginPrivate::updatePresetState);
|
2016-03-02 13:57:37 +01:00
|
|
|
|
|
|
|
|
// EditorManager
|
|
|
|
|
connect(EditorManager::instance(), &EditorManager::editorOpened,
|
|
|
|
|
this, &DebuggerPluginPrivate::editorOpened);
|
|
|
|
|
connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
|
|
|
|
|
this, &DebuggerPluginPrivate::updateBreakMenuItem);
|
|
|
|
|
|
|
|
|
|
// Application interaction
|
2022-02-04 16:37:59 -08:00
|
|
|
// Use a queued connection so the dialog isn't triggered in the same event.
|
2023-07-13 15:23:29 +02:00
|
|
|
connect(settings().settingsDialog.action(), &QAction::triggered, this,
|
2022-02-04 16:37:59 -08:00
|
|
|
[] { ICore::showOptionsDialog(DEBUGGER_COMMON_SETTINGS_ID); }, Qt::QueuedConnection);
|
2016-03-02 13:57:37 +01:00
|
|
|
|
2023-08-18 15:17:11 +02:00
|
|
|
EngineManager::registerDefaultPerspective(Tr::tr("Debugger Preset"),
|
|
|
|
|
{},
|
|
|
|
|
Constants::PRESET_PERSPECTIVE_ID);
|
|
|
|
|
|
2018-09-11 11:24:19 +02:00
|
|
|
m_perspective.useSubPerspectiveSwitcher(EngineManager::engineChooser());
|
2018-08-21 12:30:00 +02:00
|
|
|
m_perspective.addToolBarAction(&m_startAction);
|
2018-08-13 09:34:47 +02:00
|
|
|
|
2019-09-17 16:16:30 +02:00
|
|
|
m_perspective.addWindow(engineManagerWindow, Perspective::SplitVertical, nullptr);
|
|
|
|
|
m_perspective.addWindow(breakpointManagerWindow, Perspective::SplitHorizontal, engineManagerWindow);
|
|
|
|
|
m_perspective.addWindow(globalLogWindow, Perspective::AddToTab, nullptr, false, Qt::TopDockWidgetArea);
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
|
2023-08-18 15:17:11 +02:00
|
|
|
createDapDebuggerPerspective(globalLogWindow);
|
2016-03-02 13:57:37 +01:00
|
|
|
setInitialState();
|
|
|
|
|
|
2023-02-14 15:47:22 +01:00
|
|
|
connect(ProjectManager::instance(), &ProjectManager::startupProjectChanged,
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
this, &DebuggerPluginPrivate::onStartupProjectChanged);
|
|
|
|
|
connect(EngineManager::instance(), &EngineManager::engineStateChanged,
|
|
|
|
|
this, &DebuggerPluginPrivate::updatePresetState);
|
|
|
|
|
connect(EngineManager::instance(), &EngineManager::currentEngineChanged,
|
|
|
|
|
this, &DebuggerPluginPrivate::updatePresetState);
|
2019-09-17 17:13:32 +02:00
|
|
|
}
|
2016-03-02 13:57:37 +01:00
|
|
|
|
2023-08-18 15:17:11 +02:00
|
|
|
void DebuggerPluginPrivate::createDapDebuggerPerspective(QWidget *globalLogWindow)
|
2023-08-17 13:04:04 +02:00
|
|
|
{
|
2023-09-29 14:50:58 +02:00
|
|
|
struct DapPerspective
|
|
|
|
|
{
|
|
|
|
|
QString name;
|
|
|
|
|
char const *runMode;
|
2023-12-11 08:11:23 +01:00
|
|
|
bool forceSkipDeploy = false;
|
2023-09-29 14:50:58 +02:00
|
|
|
};
|
2023-08-18 15:17:11 +02:00
|
|
|
|
2023-09-29 14:50:58 +02:00
|
|
|
const QList<DapPerspective> perspectiveList = {
|
2023-12-11 08:11:23 +01:00
|
|
|
DapPerspective{Tr::tr("CMake Preset"),
|
|
|
|
|
ProjectExplorer::Constants::DAP_CMAKE_DEBUG_RUN_MODE,
|
|
|
|
|
/*forceSkipDeploy=*/true},
|
2023-09-29 14:50:58 +02:00
|
|
|
DapPerspective{Tr::tr("GDB Preset"), ProjectExplorer::Constants::DAP_GDB_DEBUG_RUN_MODE},
|
2024-06-13 16:19:45 +02:00
|
|
|
DapPerspective{Tr::tr("LLDB Preset"), ProjectExplorer::Constants::DAP_LLDB_DEBUG_RUN_MODE},
|
2023-12-11 08:11:23 +01:00
|
|
|
DapPerspective{Tr::tr("Python Preset"), ProjectExplorer::Constants::DAP_PY_DEBUG_RUN_MODE},
|
2023-09-29 14:50:58 +02:00
|
|
|
};
|
2023-08-25 15:40:18 +02:00
|
|
|
|
2023-09-29 14:50:58 +02:00
|
|
|
for (const DapPerspective &dp : perspectiveList)
|
|
|
|
|
EngineManager::registerDefaultPerspective(dp.name, "DAP", Constants::DAP_PERSPECTIVE_ID);
|
|
|
|
|
|
|
|
|
|
connect(&m_startDapAction, &QAction::triggered, this, [perspectiveList] {
|
|
|
|
|
QComboBox *combo = qobject_cast<QComboBox *>(EngineManager::dapEngineChooser());
|
2023-12-11 08:11:23 +01:00
|
|
|
if (perspectiveList.size() > combo->currentIndex()) {
|
|
|
|
|
const DapPerspective dapPerspective = perspectiveList.at(combo->currentIndex());
|
|
|
|
|
ProjectExplorerPlugin::runStartupProject(dapPerspective.runMode,
|
|
|
|
|
dapPerspective.forceSkipDeploy);
|
|
|
|
|
}
|
2023-09-29 14:50:58 +02:00
|
|
|
});
|
2023-08-18 15:17:11 +02:00
|
|
|
|
|
|
|
|
auto breakpointManagerView = createBreakpointManagerView("DAPDebugger.BreakWindow");
|
2023-08-17 13:04:04 +02:00
|
|
|
auto breakpointManagerWindow
|
|
|
|
|
= createBreakpointManagerWindow(breakpointManagerView,
|
2023-08-18 15:17:11 +02:00
|
|
|
Tr::tr("DAP Breakpoint Preset"),
|
|
|
|
|
"DAPDebugger.Docks.BreakpointManager");
|
2023-08-17 13:04:04 +02:00
|
|
|
|
|
|
|
|
// Snapshot
|
2023-08-18 15:17:11 +02:00
|
|
|
auto engineManagerView = createEngineManagerView(EngineManager::dapModel(),
|
|
|
|
|
Tr::tr("Running Debuggers"),
|
|
|
|
|
"DAPDebugger.SnapshotView");
|
2023-08-17 13:04:04 +02:00
|
|
|
auto engineManagerWindow = createEngineManagerWindow(engineManagerView,
|
2023-08-18 15:17:11 +02:00
|
|
|
Tr::tr("DAP Debugger Perspectives"),
|
|
|
|
|
"DAPDebugger.Docks.Snapshots");
|
|
|
|
|
|
2023-08-29 09:36:24 +02:00
|
|
|
m_perspectiveDap.addToolBarAction(&m_startDapAction);
|
2023-08-18 15:17:11 +02:00
|
|
|
m_startDapAction.setToolTip(Tr::tr("Start DAP Debugging"));
|
|
|
|
|
m_startDapAction.setText(Tr::tr("Start DAP Debugging"));
|
|
|
|
|
m_startDapAction.setEnabled(true);
|
|
|
|
|
m_startDapAction.setIcon(startIcon(true));
|
|
|
|
|
m_startDapAction.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
|
|
|
|
m_startDapAction.setVisible(true);
|
|
|
|
|
|
|
|
|
|
m_perspectiveDap.useSubPerspectiveSwitcher(EngineManager::dapEngineChooser());
|
|
|
|
|
|
|
|
|
|
m_perspectiveDap.addWindow(engineManagerWindow, Perspective::SplitVertical, nullptr);
|
|
|
|
|
m_perspectiveDap.addWindow(breakpointManagerWindow,
|
|
|
|
|
Perspective::SplitHorizontal,
|
|
|
|
|
engineManagerWindow);
|
|
|
|
|
m_perspectiveDap.addWindow(globalLogWindow,
|
|
|
|
|
Perspective::AddToTab,
|
|
|
|
|
nullptr,
|
|
|
|
|
false,
|
|
|
|
|
Qt::TopDockWidgetArea);
|
|
|
|
|
}
|
2019-09-17 17:13:32 +02:00
|
|
|
|
|
|
|
|
DebuggerPluginPrivate::~DebuggerPluginPrivate()
|
|
|
|
|
{
|
|
|
|
|
qDeleteAll(m_optionPages);
|
|
|
|
|
m_optionPages.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static QString msgParameterMissing(const QString &a)
|
|
|
|
|
{
|
2022-07-05 15:37:08 +02:00
|
|
|
return Tr::tr("Option \"%1\" is missing the parameter.").arg(a);
|
2019-09-17 17:13:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Kit *guessKitFromAbis(const Abis &abis)
|
|
|
|
|
{
|
|
|
|
|
Kit *kit = nullptr;
|
|
|
|
|
|
2023-09-11 08:58:51 +02:00
|
|
|
if (!KitManager::waitForLoaded())
|
|
|
|
|
return kit;
|
|
|
|
|
|
2019-09-17 17:13:32 +02:00
|
|
|
// Try to find a kit via ABI.
|
|
|
|
|
if (!abis.isEmpty()) {
|
|
|
|
|
// Try exact abis.
|
|
|
|
|
kit = KitManager::kit([abis](const Kit *k) {
|
2023-11-24 17:55:50 +01:00
|
|
|
const Abi tcAbi = ToolchainKitAspect::targetAbi(k);
|
2019-09-17 17:13:32 +02:00
|
|
|
return abis.contains(tcAbi) && !DebuggerKitAspect::configurationErrors(k);
|
|
|
|
|
});
|
|
|
|
|
if (!kit) {
|
|
|
|
|
// Or something compatible.
|
|
|
|
|
kit = KitManager::kit([abis](const Kit *k) {
|
2023-11-24 17:55:50 +01:00
|
|
|
const Abi tcAbi = ToolchainKitAspect::targetAbi(k);
|
2019-09-17 17:13:32 +02:00
|
|
|
return !DebuggerKitAspect::configurationErrors(k)
|
|
|
|
|
&& Utils::contains(abis, [tcAbi](const Abi &a) { return a.isCompatibleWith(tcAbi); });
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!kit)
|
|
|
|
|
kit = KitManager::defaultKit();
|
|
|
|
|
|
|
|
|
|
return kit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
|
|
|
|
|
const QStringList::const_iterator &cend, QString *errorMessage)
|
|
|
|
|
{
|
|
|
|
|
const QString &option = *it;
|
|
|
|
|
// '-debug <pid>'
|
|
|
|
|
// '-debug <exe>[,server=<server:port>][,core=<core>][,kit=<kit>][,terminal={0,1}]'
|
|
|
|
|
if (*it == "-debug") {
|
|
|
|
|
++it;
|
|
|
|
|
if (it == cend) {
|
|
|
|
|
*errorMessage = msgParameterMissing(*it);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2019-12-10 11:05:00 +01:00
|
|
|
const qint64 pid = it->toLongLong();
|
2019-09-17 17:13:32 +02:00
|
|
|
const QStringList args = it->split(',');
|
|
|
|
|
|
|
|
|
|
Kit *kit = nullptr;
|
|
|
|
|
DebuggerStartMode startMode = StartExternal;
|
|
|
|
|
FilePath executable;
|
|
|
|
|
QString remoteChannel;
|
2021-09-27 15:52:05 +02:00
|
|
|
FilePath coreFile;
|
2020-06-29 18:14:20 +03:00
|
|
|
QString sysRoot;
|
2019-09-17 17:13:32 +02:00
|
|
|
bool useTerminal = false;
|
|
|
|
|
|
|
|
|
|
if (!pid) {
|
|
|
|
|
for (const QString &arg : args) {
|
|
|
|
|
const QString key = arg.section('=', 0, 0);
|
|
|
|
|
const QString val = arg.section('=', 1, 1);
|
|
|
|
|
if (val.isEmpty()) {
|
|
|
|
|
if (key.isEmpty()) {
|
|
|
|
|
continue;
|
|
|
|
|
} else if (executable.isEmpty()) {
|
|
|
|
|
executable = FilePath::fromString(key);
|
|
|
|
|
} else {
|
2022-07-05 15:37:08 +02:00
|
|
|
*errorMessage = Tr::tr("Only one executable allowed.");
|
2019-09-17 17:13:32 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} else if (key == "kit") {
|
2023-09-11 08:58:51 +02:00
|
|
|
if (KitManager::waitForLoaded()) {
|
|
|
|
|
kit = KitManager::kit(Id::fromString(val));
|
|
|
|
|
if (!kit)
|
|
|
|
|
kit = KitManager::kit(Utils::equal(&Kit::displayName, val));
|
|
|
|
|
}
|
2019-09-17 17:13:32 +02:00
|
|
|
} else if (key == "server") {
|
|
|
|
|
startMode = AttachToRemoteServer;
|
|
|
|
|
remoteChannel = val;
|
|
|
|
|
} else if (key == "core") {
|
2021-01-06 16:56:36 +01:00
|
|
|
startMode = AttachToCore;
|
2021-09-27 15:52:05 +02:00
|
|
|
coreFile = FilePath::fromUserInput(val);
|
2019-09-17 17:13:32 +02:00
|
|
|
} else if (key == "terminal") {
|
|
|
|
|
useTerminal = true;
|
2020-06-29 18:14:20 +03:00
|
|
|
} else if (key == "sysroot") {
|
|
|
|
|
sysRoot = val;
|
2019-09-17 17:13:32 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!kit)
|
|
|
|
|
kit = guessKitFromAbis(Abi::abisOfBinary(executable));
|
|
|
|
|
|
|
|
|
|
auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
|
|
|
|
runControl->setKit(kit);
|
|
|
|
|
auto debugger = new DebuggerRunTool(runControl);
|
|
|
|
|
debugger->setInferiorExecutable(executable);
|
2020-06-29 18:14:20 +03:00
|
|
|
if (!sysRoot.isEmpty())
|
|
|
|
|
debugger->setSysRoot(FilePath::fromUserInput(sysRoot));
|
2019-09-17 17:13:32 +02:00
|
|
|
if (pid) {
|
2021-01-06 16:56:36 +01:00
|
|
|
debugger->setStartMode(AttachToLocalProcess);
|
2019-09-17 17:13:32 +02:00
|
|
|
debugger->setCloseMode(DetachAtClose);
|
|
|
|
|
debugger->setAttachPid(pid);
|
2022-07-05 15:37:08 +02:00
|
|
|
debugger->setRunControlName(Tr::tr("Process %1").arg(pid));
|
|
|
|
|
debugger->setStartMessage(Tr::tr("Attaching to local process %1.").arg(pid));
|
2019-09-17 17:13:32 +02:00
|
|
|
} else if (startMode == AttachToRemoteServer) {
|
|
|
|
|
debugger->setStartMode(AttachToRemoteServer);
|
|
|
|
|
debugger->setRemoteChannel(remoteChannel);
|
2022-07-05 15:37:08 +02:00
|
|
|
debugger->setRunControlName(Tr::tr("Remote: \"%1\"").arg(remoteChannel));
|
|
|
|
|
debugger->setStartMessage(Tr::tr("Attaching to remote server %1.").arg(remoteChannel));
|
2021-01-06 16:56:36 +01:00
|
|
|
} else if (startMode == AttachToCore) {
|
|
|
|
|
debugger->setStartMode(AttachToCore);
|
2019-09-17 17:13:32 +02:00
|
|
|
debugger->setCloseMode(DetachAtClose);
|
2021-09-27 15:52:05 +02:00
|
|
|
debugger->setCoreFilePath(coreFile);
|
2022-07-05 15:37:08 +02:00
|
|
|
debugger->setRunControlName(Tr::tr("Core file \"%1\"").arg(coreFile.toUserOutput()));
|
|
|
|
|
debugger->setStartMessage(Tr::tr("Attaching to core file %1.").arg(coreFile.toUserOutput()));
|
2019-09-17 17:13:32 +02:00
|
|
|
} else {
|
|
|
|
|
debugger->setStartMode(StartExternal);
|
2022-07-05 15:37:08 +02:00
|
|
|
debugger->setRunControlName(Tr::tr("Executable file \"%1\"").arg(executable.toUserOutput()));
|
|
|
|
|
debugger->setStartMessage(Tr::tr("Debugging file %1.").arg(executable.toUserOutput()));
|
2019-09-17 17:13:32 +02:00
|
|
|
}
|
|
|
|
|
debugger->setUseTerminal(useTerminal);
|
|
|
|
|
|
|
|
|
|
m_scheduledStarts.append(debugger);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
// -wincrashevent <event-handle>:<pid>. A handle used for
|
|
|
|
|
// a handshake when attaching to a crashed Windows process.
|
|
|
|
|
// This is created by $QTC/src/tools/qtcdebugger/main.cpp:
|
|
|
|
|
// args << "-wincrashevent"
|
|
|
|
|
// << QString::fromLatin1("%1:%2").arg(argWinCrashEvent).arg(argProcessId);
|
|
|
|
|
if (*it == "-wincrashevent") {
|
|
|
|
|
++it;
|
|
|
|
|
if (it == cend) {
|
|
|
|
|
*errorMessage = msgParameterMissing(*it);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2019-12-10 11:05:00 +01:00
|
|
|
qint64 pid = it->section(':', 1, 1).toLongLong();
|
2019-09-17 17:13:32 +02:00
|
|
|
auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
|
|
|
|
runControl->setKit(findUniversalCdbKit());
|
|
|
|
|
auto debugger = new DebuggerRunTool(runControl);
|
2021-01-06 16:56:36 +01:00
|
|
|
debugger->setStartMode(AttachToCrashedProcess);
|
2019-09-17 17:13:32 +02:00
|
|
|
debugger->setCrashParameter(it->section(':', 0, 0));
|
|
|
|
|
debugger->setAttachPid(pid);
|
2022-07-05 15:37:08 +02:00
|
|
|
debugger->setRunControlName(Tr::tr("Crashed process %1").arg(pid));
|
|
|
|
|
debugger->setStartMessage(Tr::tr("Attaching to crashed process %1").arg(pid));
|
2019-09-17 17:13:32 +02:00
|
|
|
if (pid < 1) {
|
2022-07-05 15:37:08 +02:00
|
|
|
*errorMessage = Tr::tr("The parameter \"%1\" of option \"%2\" "
|
2019-09-17 17:13:32 +02:00
|
|
|
"does not match the pattern <handle>:<pid>.").arg(*it, option);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
m_scheduledStarts.append(debugger);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
*errorMessage = Tr::tr("Invalid debugger option: %1").arg(option);
|
2019-09-17 17:13:32 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerPluginPrivate::parseArguments(const QStringList &args,
|
|
|
|
|
QString *errorMessage)
|
|
|
|
|
{
|
|
|
|
|
const QStringList::const_iterator cend = args.constEnd();
|
|
|
|
|
for (QStringList::const_iterator it = args.constBegin(); it != cend; ++it)
|
|
|
|
|
if (!parseArgument(it, cend, errorMessage))
|
|
|
|
|
return false;
|
2016-03-02 13:57:37 +01:00
|
|
|
return true;
|
2010-07-21 17:06:22 +02:00
|
|
|
}
|
|
|
|
|
|
2019-09-17 17:13:32 +02:00
|
|
|
void DebuggerPluginPrivate::parseCommandLineArguments()
|
|
|
|
|
{
|
|
|
|
|
QString errorMessage;
|
|
|
|
|
if (!parseArguments(m_arguments, &errorMessage)) {
|
2022-07-05 15:37:08 +02:00
|
|
|
errorMessage = Tr::tr("Error evaluating command line arguments: %1")
|
2019-09-17 17:13:32 +02:00
|
|
|
.arg(errorMessage);
|
|
|
|
|
qWarning("%s\n", qPrintable(errorMessage));
|
2020-12-15 10:13:13 +01:00
|
|
|
MessageManager::writeDisrupting(errorMessage);
|
2019-09-17 17:13:32 +02:00
|
|
|
}
|
|
|
|
|
if (!m_scheduledStarts.isEmpty())
|
|
|
|
|
QTimer::singleShot(0, this, &DebuggerPluginPrivate::runScheduled);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-30 07:39:54 +02:00
|
|
|
static void setConfigValue(const Key &name, const QVariant &value)
|
2010-12-02 13:20:06 +01:00
|
|
|
{
|
2016-06-07 17:04:53 +02:00
|
|
|
ICore::settings()->setValue("DebugMode/" + name, value);
|
2010-12-02 13:20:06 +01:00
|
|
|
}
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2023-08-30 07:39:54 +02:00
|
|
|
static QVariant configValue(const Key &name)
|
2011-02-25 13:43:06 +01:00
|
|
|
{
|
2016-06-07 17:04:53 +02:00
|
|
|
return ICore::settings()->value("DebugMode/" + name);
|
2011-02-25 13:43:06 +01:00
|
|
|
}
|
|
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
void DebuggerPluginPrivate::updatePresetState()
|
|
|
|
|
{
|
2023-05-22 13:21:57 +02:00
|
|
|
if (PluginManager::isShuttingDown())
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
return;
|
|
|
|
|
|
2023-02-14 15:47:22 +01:00
|
|
|
Project *startupProject = ProjectManager::startupProject();
|
|
|
|
|
RunConfiguration *startupRunConfig = ProjectManager::startupRunConfiguration();
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
DebuggerEngine *currentEngine = EngineManager::currentEngine();
|
|
|
|
|
|
2023-07-06 18:16:59 +02:00
|
|
|
const auto canRun = ProjectExplorerPlugin::canRunStartupProject(
|
|
|
|
|
ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
2018-10-04 17:25:11 +02:00
|
|
|
|
|
|
|
|
QString startupRunConfigName;
|
|
|
|
|
if (startupRunConfig)
|
|
|
|
|
startupRunConfigName = startupRunConfig->displayName();
|
|
|
|
|
if (startupRunConfigName.isEmpty() && startupProject)
|
|
|
|
|
startupRunConfigName = startupProject->displayName();
|
|
|
|
|
|
2019-01-25 08:02:47 +01:00
|
|
|
// Restrict width, otherwise Creator gets too wide, see QTCREATORBUG-21885
|
2023-07-06 18:16:59 +02:00
|
|
|
const QString startToolTip = canRun ? Tr::tr("Start debugging of startup project")
|
|
|
|
|
: canRun.error();
|
2018-10-04 17:25:11 +02:00
|
|
|
|
|
|
|
|
m_startAction.setToolTip(startToolTip);
|
2022-07-05 15:37:08 +02:00
|
|
|
m_startAction.setText(Tr::tr("Start Debugging of Startup Project"));
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
|
2018-10-25 15:24:39 +02:00
|
|
|
if (!currentEngine) {
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
// No engine running -- or -- we have a running engine but it does not
|
|
|
|
|
// correspond to the current start up project.
|
2023-07-06 18:16:59 +02:00
|
|
|
m_startAction.setEnabled(bool(canRun));
|
2018-10-19 16:08:51 +02:00
|
|
|
m_startAction.setIcon(startIcon(true));
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
m_startAction.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
|
|
|
|
m_startAction.setVisible(true);
|
2023-07-06 18:16:59 +02:00
|
|
|
m_debugWithoutDeployAction.setEnabled(bool(canRun));
|
2018-10-04 15:34:12 +02:00
|
|
|
m_visibleStartAction.setAction(&m_startAction);
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
m_hiddenStopAction.setAction(&m_undisturbableAction);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QTC_ASSERT(currentEngine, return);
|
|
|
|
|
|
|
|
|
|
// We have a current engine, and it belongs to the startup runconfig.
|
|
|
|
|
// The 'state' bits only affect the fat debug button, not the preset start button.
|
|
|
|
|
m_startAction.setIcon(startIcon(false));
|
|
|
|
|
m_startAction.setEnabled(false);
|
|
|
|
|
m_startAction.setVisible(false);
|
|
|
|
|
|
2023-07-06 18:16:59 +02:00
|
|
|
m_debugWithoutDeployAction.setEnabled(bool(canRun));
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
|
|
|
|
|
const DebuggerState state = currentEngine->state();
|
|
|
|
|
|
|
|
|
|
if (state == InferiorStopOk) {
|
|
|
|
|
// F5 continues, Shift-F5 kills. It is "continuable".
|
|
|
|
|
m_startAction.setEnabled(false);
|
|
|
|
|
m_debugWithoutDeployAction.setEnabled(false);
|
2018-10-23 15:32:33 +02:00
|
|
|
m_visibleStartAction.setAction(ActionManager::command(Constants::CONTINUE)->action());
|
|
|
|
|
m_hiddenStopAction.setAction(ActionManager::command(Constants::STOP)->action());
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
} else if (state == InferiorRunOk) {
|
|
|
|
|
// Shift-F5 interrupts. It is also "interruptible".
|
|
|
|
|
m_startAction.setEnabled(false);
|
|
|
|
|
m_debugWithoutDeployAction.setEnabled(false);
|
2018-10-23 15:32:33 +02:00
|
|
|
m_visibleStartAction.setAction(ActionManager::command(Constants::INTERRUPT)->action());
|
|
|
|
|
m_hiddenStopAction.setAction(ActionManager::command(Constants::INTERRUPT)->action());
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
} else if (state == DebuggerFinished) {
|
|
|
|
|
// We don't want to do anything anymore.
|
2023-07-06 18:16:59 +02:00
|
|
|
m_startAction.setEnabled(bool(canRun));
|
|
|
|
|
m_debugWithoutDeployAction.setEnabled(bool(canRun));
|
2018-10-25 15:24:39 +02:00
|
|
|
m_visibleStartAction.setAction(ActionManager::command(DEBUGGER_START)->action());
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
m_hiddenStopAction.setAction(&m_undisturbableAction);
|
|
|
|
|
} else if (state == InferiorUnrunnable) {
|
|
|
|
|
// We don't want to do anything anymore.
|
|
|
|
|
m_startAction.setEnabled(false);
|
|
|
|
|
m_debugWithoutDeployAction.setEnabled(false);
|
2018-10-23 15:32:33 +02:00
|
|
|
m_visibleStartAction.setAction(ActionManager::command(Constants::STOP)->action());
|
|
|
|
|
m_hiddenStopAction.setAction(ActionManager::command(Constants::STOP)->action());
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
} else {
|
2018-10-04 15:34:12 +02:00
|
|
|
// The startup phase should be over once we are here.
|
|
|
|
|
// But treat it as 'undisturbable if we are here by accident.
|
2019-03-22 07:35:48 +01:00
|
|
|
//QTC_CHECK(state != DebuggerNotReady);
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
// Everything else is "undisturbable".
|
|
|
|
|
m_startAction.setEnabled(false);
|
|
|
|
|
m_debugWithoutDeployAction.setEnabled(false);
|
|
|
|
|
m_visibleStartAction.setAction(&m_undisturbableAction);
|
|
|
|
|
m_hiddenStopAction.setAction(&m_undisturbableAction);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME: Decentralize the actions below
|
|
|
|
|
const bool actionsEnabled = currentEngine->debuggerActionsEnabled();
|
|
|
|
|
const bool canDeref = actionsEnabled && currentEngine->hasCapability(AutoDerefPointersCapability);
|
2023-07-13 15:23:29 +02:00
|
|
|
DebuggerSettings &s = settings();
|
|
|
|
|
s.autoDerefPointers.setEnabled(canDeref);
|
|
|
|
|
s.autoDerefPointers.setEnabled(true);
|
|
|
|
|
s.expandStack.setEnabled(actionsEnabled);
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
|
|
|
|
|
m_startAndDebugApplicationAction.setEnabled(true);
|
|
|
|
|
m_attachToQmlPortAction.setEnabled(true);
|
|
|
|
|
m_attachToCoreAction.setEnabled(true);
|
|
|
|
|
m_attachToRemoteServerAction.setEnabled(true);
|
|
|
|
|
m_attachToRunningApplication.setEnabled(true);
|
|
|
|
|
m_attachToUnstartedApplication.setEnabled(true);
|
|
|
|
|
|
2018-09-24 14:41:51 +02:00
|
|
|
m_watchAction.setEnabled(state != DebuggerFinished && state != DebuggerNotReady);
|
2022-01-03 10:30:08 +01:00
|
|
|
m_setOrRemoveBreakpointAction.setEnabled(true);
|
|
|
|
|
m_enableOrDisableBreakpointAction.setEnabled(true);
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerPluginPrivate::onStartupProjectChanged(Project *project)
|
2010-12-02 13:20:06 +01:00
|
|
|
{
|
2018-02-01 10:59:24 +01:00
|
|
|
RunConfiguration *activeRc = nullptr;
|
2016-03-02 13:57:37 +01:00
|
|
|
if (project) {
|
|
|
|
|
Target *target = project->activeTarget();
|
|
|
|
|
if (target)
|
|
|
|
|
activeRc = target->activeRunConfiguration();
|
|
|
|
|
if (!activeRc)
|
|
|
|
|
return;
|
|
|
|
|
}
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
for (DebuggerEngine *engine : EngineManager::engines()) {
|
2016-03-02 13:57:37 +01:00
|
|
|
// Run controls might be deleted during exit.
|
2019-03-22 07:35:48 +01:00
|
|
|
engine->updateState();
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
|
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
updatePresetState();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::attachCore()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2016-03-02 13:57:37 +01:00
|
|
|
AttachCoreDialog dlg(ICore::dialogParent());
|
2010-12-02 13:20:06 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
const QString lastExternalKit = configValue("LastExternalKit").toString();
|
|
|
|
|
if (!lastExternalKit.isEmpty())
|
|
|
|
|
dlg.setKitId(Id::fromString(lastExternalKit));
|
2023-01-03 12:31:52 +01:00
|
|
|
dlg.setSymbolFile(FilePath::fromSettings(configValue("LastExternalExecutableFile")));
|
2023-02-02 14:27:50 +01:00
|
|
|
dlg.setCoreFile(FilePath::fromSettings(configValue("LastLocalCoreFile")));
|
2023-01-03 12:31:52 +01:00
|
|
|
dlg.setOverrideStartScript(FilePath::fromSettings(configValue("LastExternalStartScript")));
|
|
|
|
|
dlg.setSysRoot(FilePath::fromSettings(configValue("LastSysRoot")));
|
2010-12-02 13:20:06 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
if (dlg.exec() != QDialog::Accepted)
|
2010-06-16 11:08:54 +02:00
|
|
|
return;
|
2016-03-02 13:57:37 +01:00
|
|
|
|
2023-01-03 12:31:52 +01:00
|
|
|
setConfigValue("LastExternalExecutableFile", dlg.symbolFile().toSettings());
|
2023-02-02 14:27:50 +01:00
|
|
|
setConfigValue("LastLocalCoreFile", dlg.coreFile().toSettings());
|
2016-03-02 13:57:37 +01:00
|
|
|
setConfigValue("LastExternalKit", dlg.kit()->id().toSetting());
|
2023-01-03 12:31:52 +01:00
|
|
|
setConfigValue("LastExternalStartScript", dlg.overrideStartScript().toSettings());
|
|
|
|
|
setConfigValue("LastSysRoot", dlg.sysRoot().toSettings());
|
2016-03-02 13:57:37 +01:00
|
|
|
|
2019-03-12 15:53:54 +01:00
|
|
|
auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
2019-03-12 17:04:08 +01:00
|
|
|
runControl->setKit(dlg.kit());
|
2023-02-02 14:27:50 +01:00
|
|
|
runControl->setDisplayName(Tr::tr("Core file \"%1\"").arg(dlg.coreFile().toUserOutput()));
|
2019-03-12 17:04:08 +01:00
|
|
|
auto debugger = new DebuggerRunTool(runControl);
|
2023-02-02 14:27:50 +01:00
|
|
|
|
|
|
|
|
debugger->setInferiorExecutable(dlg.symbolFileCopy());
|
|
|
|
|
debugger->setCoreFilePath(dlg.coreFileCopy());
|
2021-01-06 16:56:36 +01:00
|
|
|
debugger->setStartMode(AttachToCore);
|
2017-09-12 12:38:31 +02:00
|
|
|
debugger->setCloseMode(DetachAtClose);
|
|
|
|
|
debugger->setOverrideStartScript(dlg.overrideStartScript());
|
2020-06-29 18:14:20 +03:00
|
|
|
const FilePath sysRoot = dlg.sysRoot();
|
|
|
|
|
if (!sysRoot.isEmpty())
|
|
|
|
|
debugger->setSysRoot(sysRoot);
|
2017-08-24 18:40:37 +02:00
|
|
|
debugger->startRunControl();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2021-06-23 11:24:42 +02:00
|
|
|
void DebuggerPluginPrivate::reloadDebuggingHelpers()
|
|
|
|
|
{
|
|
|
|
|
if (DebuggerEngine *engine = EngineManager::currentEngine())
|
|
|
|
|
engine->reloadDebuggingHelpers();
|
|
|
|
|
else
|
|
|
|
|
DebuggerMainWindow::showStatusMessage(
|
2022-07-05 15:37:08 +02:00
|
|
|
Tr::tr("Reload debugging helpers skipped as no engine is running."), 5000);
|
2021-06-23 11:24:42 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::startRemoteCdbSession()
|
2010-11-19 16:13:22 +01:00
|
|
|
{
|
2023-08-30 07:39:54 +02:00
|
|
|
const Key connectionKey = "CdbRemoteConnection";
|
2016-03-02 13:57:37 +01:00
|
|
|
Kit *kit = findUniversalCdbKit();
|
|
|
|
|
QTC_ASSERT(kit, return);
|
2017-09-07 10:40:22 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
StartRemoteCdbDialog dlg(ICore::dialogParent());
|
|
|
|
|
QString previousConnection = configValue(connectionKey).toString();
|
|
|
|
|
if (previousConnection.isEmpty())
|
2017-09-07 10:40:22 +02:00
|
|
|
previousConnection = "localhost:1234";
|
2016-03-02 13:57:37 +01:00
|
|
|
dlg.setConnection(previousConnection);
|
|
|
|
|
if (dlg.exec() != QDialog::Accepted)
|
|
|
|
|
return;
|
2017-09-07 10:40:22 +02:00
|
|
|
setConfigValue(connectionKey, dlg.connection());
|
2017-08-24 18:40:37 +02:00
|
|
|
|
2019-03-12 15:53:54 +01:00
|
|
|
auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
2019-03-12 17:04:08 +01:00
|
|
|
runControl->setKit(kit);
|
|
|
|
|
auto debugger = new DebuggerRunTool(runControl);
|
2017-09-07 10:40:22 +02:00
|
|
|
debugger->setStartMode(AttachToRemoteServer);
|
|
|
|
|
debugger->setCloseMode(KillAtClose);
|
|
|
|
|
debugger->setRemoteChannel(dlg.connection());
|
2017-08-24 18:40:37 +02:00
|
|
|
debugger->startRunControl();
|
2010-11-19 16:13:22 +01:00
|
|
|
}
|
|
|
|
|
|
2017-10-19 08:29:20 +02:00
|
|
|
class RemoteAttachRunner : public DebuggerRunTool
|
2015-06-10 14:19:42 +02:00
|
|
|
{
|
2017-10-19 08:29:20 +02:00
|
|
|
public:
|
2019-12-10 11:05:00 +01:00
|
|
|
RemoteAttachRunner(RunControl *runControl, ProcessHandle pid)
|
2019-03-12 17:04:08 +01:00
|
|
|
: DebuggerRunTool(runControl)
|
2017-10-19 08:29:20 +02:00
|
|
|
{
|
2018-08-21 08:28:27 +02:00
|
|
|
setId("AttachToRunningProcess");
|
2017-10-19 14:23:43 +02:00
|
|
|
setUsePortsGatherer(true, false);
|
2017-10-19 08:29:20 +02:00
|
|
|
|
2019-12-13 10:30:30 +01:00
|
|
|
auto gdbServer = new DebugServerRunner(runControl, portsGatherer());
|
2017-10-19 08:29:20 +02:00
|
|
|
gdbServer->setUseMulti(false);
|
2019-12-10 11:05:00 +01:00
|
|
|
gdbServer->setAttachPid(pid);
|
2017-10-19 08:29:20 +02:00
|
|
|
|
|
|
|
|
addStartDependency(gdbServer);
|
|
|
|
|
|
|
|
|
|
setStartMode(AttachToRemoteProcess);
|
|
|
|
|
setCloseMode(DetachAtClose);
|
|
|
|
|
|
|
|
|
|
// setInferiorExecutable(localExecutable);
|
|
|
|
|
setUseContinueInsteadOfRun(true);
|
|
|
|
|
setContinueAfterAttach(false);
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2017-10-19 08:29:20 +02:00
|
|
|
};
|
2010-12-01 15:41:08 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::attachToRunningApplication()
|
|
|
|
|
{
|
2019-06-11 10:27:16 +02:00
|
|
|
auto kitChooser = new KitChooser;
|
|
|
|
|
kitChooser->setShowIcons(true);
|
2010-12-01 15:41:08 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
|
2023-02-10 14:44:09 +01:00
|
|
|
dlg->addAcceptButton(Tr::tr("&Attach to Process"));
|
2016-03-02 13:57:37 +01:00
|
|
|
dlg->showAllDevices();
|
|
|
|
|
if (dlg->exec() == QDialog::Rejected) {
|
|
|
|
|
delete dlg;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-05-12 16:48:04 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
|
Kit *kit = kitChooser->currentKit();
|
|
|
|
|
QTC_ASSERT(kit, return);
|
2019-02-06 12:50:51 +01:00
|
|
|
IDevice::ConstPtr device = DeviceKitAspect::device(kit);
|
2016-03-02 13:57:37 +01:00
|
|
|
QTC_ASSERT(device, return);
|
2010-12-02 13:20:06 +01:00
|
|
|
|
2022-02-24 18:42:47 +01:00
|
|
|
const ProcessInfo processInfo = dlg->currentProcess();
|
2017-10-19 08:29:20 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
if (device->type() == PE::DESKTOP_DEVICE_TYPE) {
|
2022-02-24 18:42:47 +01:00
|
|
|
attachToRunningProcess(kit, processInfo, false);
|
2016-03-02 13:57:37 +01:00
|
|
|
} else {
|
2019-03-12 15:53:54 +01:00
|
|
|
auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
2019-03-12 17:04:08 +01:00
|
|
|
runControl->setKit(kit);
|
2019-05-29 08:35:45 +02:00
|
|
|
//: %1: PID
|
2022-07-05 15:37:08 +02:00
|
|
|
runControl->setDisplayName(Tr::tr("Process %1").arg(processInfo.processId));
|
2022-02-24 18:42:47 +01:00
|
|
|
auto debugger = new RemoteAttachRunner(runControl, ProcessHandle(processInfo.processId));
|
2017-10-19 08:29:20 +02:00
|
|
|
debugger->startRunControl();
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
|
|
|
|
}
|
2010-12-02 13:20:06 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::attachToUnstartedApplicationDialog()
|
|
|
|
|
{
|
|
|
|
|
auto dlg = new UnstartedAppWatcherDialog(ICore::dialogParent());
|
2014-06-04 14:45:10 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
connect(dlg, &QDialog::finished, dlg, &QObject::deleteLater);
|
|
|
|
|
connect(dlg, &UnstartedAppWatcherDialog::processFound, this, [this, dlg] {
|
2017-04-11 13:45:37 +02:00
|
|
|
RunControl *rc = attachToRunningProcess(dlg->currentKit(),
|
|
|
|
|
dlg->currentProcess(),
|
|
|
|
|
dlg->continueOnAttach());
|
2016-03-02 13:57:37 +01:00
|
|
|
if (!rc)
|
|
|
|
|
return;
|
2014-06-04 14:45:10 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
if (dlg->hideOnAttach())
|
2017-07-11 17:25:33 +02:00
|
|
|
connect(rc, &RunControl::stopped, dlg, &UnstartedAppWatcherDialog::startWatching);
|
2016-03-02 13:57:37 +01:00
|
|
|
});
|
2014-06-04 14:45:10 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
dlg->show();
|
|
|
|
|
}
|
2014-06-04 14:45:10 +02:00
|
|
|
|
2017-04-11 13:45:37 +02:00
|
|
|
RunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
|
2022-02-24 18:42:47 +01:00
|
|
|
const ProcessInfo &processInfo, bool contAfterAttach)
|
2016-03-02 13:57:37 +01:00
|
|
|
{
|
2018-07-23 22:28:49 +02:00
|
|
|
QTC_ASSERT(kit, return nullptr);
|
2019-02-06 12:50:51 +01:00
|
|
|
IDevice::ConstPtr device = DeviceKitAspect::device(kit);
|
2018-07-23 22:28:49 +02:00
|
|
|
QTC_ASSERT(device, return nullptr);
|
2022-02-24 18:42:47 +01:00
|
|
|
if (processInfo.processId == 0) {
|
2022-07-05 15:37:08 +02:00
|
|
|
AsynchronousMessageBox::warning(Tr::tr("Warning"), Tr::tr("Cannot attach to process with PID 0"));
|
2018-07-23 22:28:49 +02:00
|
|
|
return nullptr;
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2014-06-04 14:45:10 +02:00
|
|
|
|
2023-11-24 17:55:50 +01:00
|
|
|
const Abi tcAbi = ToolchainKitAspect::targetAbi(kit);
|
2016-07-13 10:40:05 +02:00
|
|
|
const bool isWindows = (tcAbi.os() == Abi::WindowsOS);
|
2022-02-24 18:42:47 +01:00
|
|
|
if (isWindows && isWinProcessBeingDebugged(processInfo.processId)) {
|
2017-08-29 11:48:48 +02:00
|
|
|
AsynchronousMessageBox::warning(
|
2023-06-21 15:12:46 +02:00
|
|
|
Tr::tr("Process Already Under Debugger Control"),
|
|
|
|
|
Tr::tr("The process %1 is already under the control of a debugger.\n"
|
|
|
|
|
"%2 cannot attach to it.")
|
|
|
|
|
.arg(processInfo.processId)
|
|
|
|
|
.arg(QGuiApplication::applicationDisplayName()));
|
2018-07-23 22:28:49 +02:00
|
|
|
return nullptr;
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2014-06-04 14:45:10 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
if (device->type() != PE::DESKTOP_DEVICE_TYPE) {
|
2022-07-05 15:37:08 +02:00
|
|
|
AsynchronousMessageBox::warning(Tr::tr("Not a Desktop Device Type"),
|
|
|
|
|
Tr::tr("It is only possible to attach to a locally running process."));
|
2018-07-23 22:28:49 +02:00
|
|
|
return nullptr;
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2014-06-04 14:45:10 +02:00
|
|
|
|
2019-03-12 15:53:54 +01:00
|
|
|
auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
2019-04-09 08:20:38 +02:00
|
|
|
runControl->setKit(kit);
|
2019-05-29 08:35:45 +02:00
|
|
|
//: %1: PID
|
2022-07-05 15:37:08 +02:00
|
|
|
runControl->setDisplayName(Tr::tr("Process %1").arg(processInfo.processId));
|
2019-03-12 17:04:08 +01:00
|
|
|
auto debugger = new DebuggerRunTool(runControl);
|
2022-02-24 18:42:47 +01:00
|
|
|
debugger->setAttachPid(ProcessHandle(processInfo.processId));
|
2022-05-25 09:11:51 +02:00
|
|
|
debugger->setInferiorExecutable(device->filePath(processInfo.executable));
|
2021-01-06 16:56:36 +01:00
|
|
|
debugger->setStartMode(AttachToLocalProcess);
|
2017-09-07 10:40:22 +02:00
|
|
|
debugger->setCloseMode(DetachAtClose);
|
|
|
|
|
debugger->setContinueAfterAttach(contAfterAttach);
|
|
|
|
|
|
2017-08-24 18:40:37 +02:00
|
|
|
debugger->startRunControl();
|
|
|
|
|
|
|
|
|
|
return debugger->runControl();
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2014-06-04 14:45:10 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::attachToQmlPort()
|
|
|
|
|
{
|
2020-06-02 09:10:40 +02:00
|
|
|
AttachToQmlPortDialog dlg(ICore::dialogParent());
|
2014-06-04 14:45:10 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
const QVariant qmlServerPort = configValue("LastQmlServerPort");
|
|
|
|
|
if (qmlServerPort.isValid())
|
|
|
|
|
dlg.setPort(qmlServerPort.toInt());
|
|
|
|
|
else
|
2016-04-19 16:43:30 +02:00
|
|
|
dlg.setPort(-1);
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
const Id kitId = Id::fromSetting(configValue("LastProfile"));
|
|
|
|
|
if (kitId.isValid())
|
|
|
|
|
dlg.setKitId(kitId);
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
if (dlg.exec() != QDialog::Accepted)
|
|
|
|
|
return;
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
Kit *kit = dlg.kit();
|
|
|
|
|
QTC_ASSERT(kit, return);
|
|
|
|
|
setConfigValue("LastQmlServerPort", dlg.port());
|
|
|
|
|
setConfigValue("LastProfile", kit->id().toSetting());
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2019-02-06 12:50:51 +01:00
|
|
|
IDevice::ConstPtr device = DeviceKitAspect::device(kit);
|
2017-09-12 13:12:30 +02:00
|
|
|
QTC_ASSERT(device, return);
|
2017-08-24 18:40:37 +02:00
|
|
|
|
2019-03-12 15:53:54 +01:00
|
|
|
auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
2019-03-12 17:04:08 +01:00
|
|
|
runControl->setKit(kit);
|
|
|
|
|
auto debugger = new DebuggerRunTool(runControl);
|
2017-09-12 13:12:30 +02:00
|
|
|
|
|
|
|
|
QUrl qmlServer = device->toolControlChannel(IDevice::QmlControlChannel);
|
|
|
|
|
qmlServer.setPort(dlg.port());
|
|
|
|
|
debugger->setQmlServer(qmlServer);
|
|
|
|
|
|
2022-05-12 18:43:44 +02:00
|
|
|
SshParameters sshParameters = device->sshParameters();
|
2017-12-19 12:45:46 +01:00
|
|
|
debugger->setRemoteChannel(sshParameters.host(), sshParameters.port());
|
2017-09-12 13:12:30 +02:00
|
|
|
debugger->setStartMode(AttachToQmlServer);
|
|
|
|
|
|
2017-08-24 18:40:37 +02:00
|
|
|
debugger->startRunControl();
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2010-11-08 15:19:13 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::runScheduled()
|
|
|
|
|
{
|
2022-10-07 14:46:06 +02:00
|
|
|
for (DebuggerRunTool *debugger : std::as_const(m_scheduledStarts))
|
2017-08-24 18:40:37 +02:00
|
|
|
debugger->startRunControl();
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2010-11-10 16:33:11 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::editorOpened(IEditor *editor)
|
|
|
|
|
{
|
2020-02-11 14:00:09 +01:00
|
|
|
if (auto widget = TextEditorWidget::fromEditor(editor)) {
|
2016-03-02 13:57:37 +01:00
|
|
|
connect(widget, &TextEditorWidget::markRequested,
|
|
|
|
|
this, &DebuggerPluginPrivate::requestMark);
|
2014-06-05 17:22:51 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
connect(widget, &TextEditorWidget::markContextMenuRequested,
|
|
|
|
|
this, &DebuggerPluginPrivate::requestContextMenu);
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-04-28 15:08:52 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::updateBreakMenuItem(IEditor *editor)
|
|
|
|
|
{
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
BaseTextEditor *textEditor = qobject_cast<BaseTextEditor *>(editor);
|
2022-01-03 10:30:08 +01:00
|
|
|
m_setOrRemoveBreakpointAction.setEnabled(textEditor != nullptr);
|
|
|
|
|
m_enableOrDisableBreakpointAction.setEnabled(textEditor != nullptr);
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2010-11-24 18:36:17 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
|
|
|
|
|
int lineNumber, QMenu *menu)
|
|
|
|
|
{
|
|
|
|
|
TextDocument *document = widget->textDocument();
|
2010-11-24 18:36:17 +01:00
|
|
|
|
2018-08-22 17:35:12 +02:00
|
|
|
const ContextData args = getLocationContext(document, lineNumber);
|
|
|
|
|
const GlobalBreakpoint gbp = BreakpointManager::findBreakpointFromContext(args);
|
2010-11-24 18:36:17 +01:00
|
|
|
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
if (gbp) {
|
2010-12-02 13:20:06 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
// Remove existing breakpoint.
|
2022-07-05 15:37:08 +02:00
|
|
|
auto act = menu->addAction(Tr::tr("Remove Breakpoint"));
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
connect(act, &QAction::triggered, [gbp] { gbp->deleteBreakpoint(); });
|
|
|
|
|
|
2018-08-22 15:19:24 +02:00
|
|
|
// Enable/disable existing breakpoint.
|
|
|
|
|
if (gbp->isEnabled()) {
|
2022-07-05 15:37:08 +02:00
|
|
|
act = menu->addAction(Tr::tr("Disable Breakpoint"));
|
2018-08-22 15:19:24 +02:00
|
|
|
connect(act, &QAction::triggered, [gbp] { gbp->setEnabled(false); });
|
|
|
|
|
} else {
|
2022-07-05 15:37:08 +02:00
|
|
|
act = menu->addAction(Tr::tr("Enable Breakpoint"));
|
2018-08-22 15:19:24 +02:00
|
|
|
connect(act, &QAction::triggered, [gbp] { gbp->setEnabled(true); });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Edit existing breakpoint.
|
2022-07-05 15:37:08 +02:00
|
|
|
act = menu->addAction(Tr::tr("Edit Breakpoint..."));
|
2018-08-22 15:19:24 +02:00
|
|
|
connect(act, &QAction::triggered, [gbp] {
|
|
|
|
|
BreakpointManager::editBreakpoint(gbp, ICore::dialogParent());
|
|
|
|
|
});
|
2010-12-02 13:20:06 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
} else {
|
|
|
|
|
// Handle non-existing breakpoint.
|
|
|
|
|
const QString text = args.address
|
2022-07-05 15:37:08 +02:00
|
|
|
? Tr::tr("Set Breakpoint at 0x%1").arg(args.address, 0, 16)
|
|
|
|
|
: Tr::tr("Set Breakpoint at Line %1").arg(lineNumber);
|
2016-03-02 13:57:37 +01:00
|
|
|
auto act = menu->addAction(text);
|
|
|
|
|
act->setEnabled(args.isValid());
|
2022-12-07 23:20:02 +01:00
|
|
|
connect(act, &QAction::triggered, this, [this, args] {
|
2016-03-02 13:57:37 +01:00
|
|
|
breakpointSetMarginActionTriggered(false, args);
|
|
|
|
|
});
|
2010-12-02 13:20:06 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
// Message trace point
|
|
|
|
|
const QString tracePointText = args.address
|
2022-07-05 15:37:08 +02:00
|
|
|
? Tr::tr("Set Message Tracepoint at 0x%1...").arg(args.address, 0, 16)
|
|
|
|
|
: Tr::tr("Set Message Tracepoint at Line %1...").arg(lineNumber);
|
2016-03-02 13:57:37 +01:00
|
|
|
act = menu->addAction(tracePointText);
|
|
|
|
|
act->setEnabled(args.isValid());
|
2022-12-07 23:20:02 +01:00
|
|
|
connect(act, &QAction::triggered, this, [this, args] {
|
2016-03-02 13:57:37 +01:00
|
|
|
breakpointSetMarginActionTriggered(true, args);
|
|
|
|
|
});
|
|
|
|
|
}
|
2010-12-02 13:20:06 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
// Run to, jump to line below in stopped state.
|
2019-12-10 11:05:00 +01:00
|
|
|
for (const QPointer<DebuggerEngine> &engine : EngineManager::engines()) {
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
if (engine->state() == InferiorStopOk && args.isValid()) {
|
|
|
|
|
menu->addSeparator();
|
|
|
|
|
if (engine->hasCapability(RunToLineCapability)) {
|
|
|
|
|
auto act = menu->addAction(args.address
|
2022-07-05 15:37:08 +02:00
|
|
|
? Tr::tr("Run to Address 0x%1").arg(args.address, 0, 16)
|
2023-06-06 15:44:59 +02:00
|
|
|
: Tr::tr("Run to Line %1").arg(args.textPosition.line));
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
connect(act, &QAction::triggered, this, [args, engine] {
|
2017-06-22 11:21:58 +02:00
|
|
|
QTC_ASSERT(engine, return);
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
engine->executeRunToLine(args);
|
2016-03-02 13:57:37 +01:00
|
|
|
});
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
}
|
|
|
|
|
if (engine->hasCapability(JumpToLineCapability)) {
|
|
|
|
|
auto act = menu->addAction(args.address
|
2022-07-05 15:37:08 +02:00
|
|
|
? Tr::tr("Jump to Address 0x%1").arg(args.address, 0, 16)
|
2023-06-06 15:44:59 +02:00
|
|
|
: Tr::tr("Jump to Line %1").arg(args.textPosition.line));
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
connect(act, &QAction::triggered, this, [args, engine] {
|
|
|
|
|
QTC_ASSERT(engine, return);
|
|
|
|
|
engine->executeJumpToLine(args);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
// Disassemble current function in stopped state.
|
|
|
|
|
if (engine->hasCapability(DisassemblerCapability)) {
|
|
|
|
|
StackFrame frame;
|
2022-11-24 15:21:15 +01:00
|
|
|
frame.function = cppFunctionAt(args.fileName, lineNumber, 1);
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
frame.line = 42; // trick gdb into mixed mode.
|
|
|
|
|
if (!frame.function.isEmpty()) {
|
2022-07-05 15:37:08 +02:00
|
|
|
const QString text = Tr::tr("Disassemble Function \"%1\"")
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
.arg(frame.function);
|
|
|
|
|
auto act = new QAction(text, menu);
|
|
|
|
|
connect(act, &QAction::triggered, this, [frame, engine] {
|
|
|
|
|
QTC_ASSERT(engine, return);
|
|
|
|
|
engine->openDisassemblerView(Location(frame));
|
|
|
|
|
});
|
|
|
|
|
menu->addAction(act);
|
|
|
|
|
}
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-06-11 12:38:54 +02:00
|
|
|
|
2022-01-03 10:30:08 +01:00
|
|
|
void DebuggerPluginPrivate::setOrRemoveBreakpoint()
|
|
|
|
|
{
|
|
|
|
|
const BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor();
|
|
|
|
|
QTC_ASSERT(textEditor, return);
|
|
|
|
|
const int lineNumber = textEditor->currentLine();
|
|
|
|
|
ContextData location = getLocationContext(textEditor->textDocument(), lineNumber);
|
|
|
|
|
if (location.isValid())
|
|
|
|
|
BreakpointManager::setOrRemoveBreakpoint(location);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerPluginPrivate::enableOrDisableBreakpoint()
|
2016-03-02 13:57:37 +01:00
|
|
|
{
|
2022-01-03 10:30:08 +01:00
|
|
|
const BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor();
|
2016-03-02 13:57:37 +01:00
|
|
|
QTC_ASSERT(textEditor, return);
|
|
|
|
|
const int lineNumber = textEditor->currentLine();
|
|
|
|
|
ContextData location = getLocationContext(textEditor->textDocument(), lineNumber);
|
|
|
|
|
if (location.isValid())
|
2022-01-03 10:30:08 +01:00
|
|
|
BreakpointManager::enableOrDisableBreakpoint(location);
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::requestMark(TextEditorWidget *widget, int lineNumber,
|
|
|
|
|
TextMarkRequestKind kind)
|
|
|
|
|
{
|
|
|
|
|
if (kind == BreakpointRequest) {
|
|
|
|
|
ContextData location = getLocationContext(widget->textDocument(), lineNumber);
|
|
|
|
|
if (location.isValid())
|
2022-01-03 10:30:08 +01:00
|
|
|
BreakpointManager::setOrRemoveBreakpoint(location);
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
|
|
|
|
}
|
2010-12-02 18:19:05 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::setInitialState()
|
|
|
|
|
{
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
m_startAndDebugApplicationAction.setEnabled(true);
|
|
|
|
|
m_attachToQmlPortAction.setEnabled(true);
|
|
|
|
|
m_attachToCoreAction.setEnabled(true);
|
|
|
|
|
m_attachToRemoteServerAction.setEnabled(true);
|
|
|
|
|
m_attachToRunningApplication.setEnabled(true);
|
|
|
|
|
m_attachToUnstartedApplication.setEnabled(true);
|
|
|
|
|
|
2018-09-24 14:41:51 +02:00
|
|
|
m_watchAction.setEnabled(false);
|
2022-01-03 10:30:08 +01:00
|
|
|
m_setOrRemoveBreakpointAction.setEnabled(false);
|
|
|
|
|
m_enableOrDisableBreakpointAction.setEnabled(false);
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
//m_snapshotAction.setEnabled(false);
|
|
|
|
|
|
2023-07-13 15:23:29 +02:00
|
|
|
settings().autoDerefPointers.setEnabled(true);
|
|
|
|
|
settings().expandStack.setEnabled(false);
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2009-05-05 17:48:54 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::updateDebugWithoutDeployMenu()
|
|
|
|
|
{
|
2024-02-02 11:16:21 +01:00
|
|
|
const bool state = projectExplorerSettings().deployBeforeRun;
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
m_debugWithoutDeployAction.setVisible(state);
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2009-05-05 17:48:54 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::dumpLog()
|
|
|
|
|
{
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
DebuggerEngine *engine = EngineManager::currentEngine();
|
|
|
|
|
if (!engine)
|
|
|
|
|
return;
|
|
|
|
|
LogWindow *logWindow = engine->logWindow();
|
|
|
|
|
QTC_ASSERT(logWindow, return);
|
|
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
const FilePath filePath = FileUtils::getSaveFilePath(nullptr, Tr::tr("Save Debugger Log"),
|
2022-01-18 17:40:19 +01:00
|
|
|
TemporaryDirectory::masterDirectoryFilePath());
|
2021-08-17 16:36:42 +02:00
|
|
|
if (filePath.isEmpty())
|
2016-03-02 13:57:37 +01:00
|
|
|
return;
|
2021-08-17 16:36:42 +02:00
|
|
|
FileSaver saver(filePath);
|
2016-03-02 13:57:37 +01:00
|
|
|
if (!saver.hasError()) {
|
|
|
|
|
QTextStream ts(saver.file());
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
ts << logWindow->inputContents();
|
2016-03-02 13:57:37 +01:00
|
|
|
ts << "\n\n=======================================\n\n";
|
Debugger: Make most views per-engine instead of singletons
This is a step towards properly supporting multiple debugger
sessions side-by-side.
The combined C++-and-QML engine has been removed, instead a
combined setup creates now two individual engines, under a single
DebuggerRunTool but mostly independent with no combined state
machine. This requires a few more clicks in some cases, but
makes it easier to direct e.g. interrupt requests to the
interesting engine.
Care has been taken to not change the UX of the single debugger
session use case if possible. The fat debug button operates
as-before in that case, i.e. switches to Interrupt if the
single active runconfiguration runs in the debugger etc.
Most views are made per-engine, running an engine creates
a new Perspective, which is destroyed when the run control dies.
The snapshot view remains global and becomes primary source
of information on a "current engine" that receives all menu
and otherwise global input.
There is a new global "Breakpoint Preset" view containing
all "static" breakpoint data. When an engine starts up it
"claims" breakpoint it believes it can handle, but operates
on a copy of the static data. The markers of the static
version are suppressed as long as an engine controls a
breakpoint (that inclusive all resolved locations), but are
re-instatet once the engine quits.
The old Breakpoint class that already contained this split
per-instance was split into a new Breakpoint and a
GlobalBreakpoint class, with a per-engine model for Breakpoints,
and a singleton model containing GlobalBreakpoints.
There is a new CppDebuggerEngine intermediate level serving as
base for C++ (or, rather, "compiled") binary debugging, i.e.
{Gdb,Lldb,Cdb}Engine, taking over bits of the current DebuggerEngine
base that are not applicable to non-binary debuggers.
Change-Id: I9994f4c188379b4aee0c4f379edd4759fbb0bd43
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: hjk <hjk@qt.io>
2018-07-31 12:30:48 +02:00
|
|
|
ts << logWindow->combinedContents();
|
2016-03-02 13:57:37 +01:00
|
|
|
saver.setResult(&ts);
|
|
|
|
|
}
|
2020-06-02 09:10:40 +02:00
|
|
|
saver.finalize(ICore::dialogParent());
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2009-09-30 12:27:03 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::remoteCommand(const QStringList &options)
|
|
|
|
|
{
|
|
|
|
|
if (options.isEmpty())
|
|
|
|
|
return;
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
QString errorMessage;
|
2010-11-10 16:33:11 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
if (!parseArguments(options, &errorMessage)) {
|
|
|
|
|
qWarning("%s", qPrintable(errorMessage));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
runScheduled();
|
|
|
|
|
}
|
2010-11-10 11:39:01 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
void DebuggerPluginPrivate::extensionsInitialized()
|
|
|
|
|
{
|
2023-08-09 10:47:36 +02:00
|
|
|
QTimer::singleShot(0, this, &DebuggerItemManager::restoreDebuggers);
|
2022-09-22 15:24:52 +02:00
|
|
|
|
2017-02-21 10:36:10 +01:00
|
|
|
// If the CppEditor or QmlJS editor plugin is there, we want to add something to
|
|
|
|
|
// the editor context menu.
|
2017-02-22 09:14:33 +01:00
|
|
|
for (Id menuId : { CppEditor::Constants::M_CONTEXT, QmlJSEditor::Constants::M_CONTEXT }) {
|
|
|
|
|
if (ActionContainer *editorContextMenu = ActionManager::actionContainer(menuId)) {
|
2017-02-21 10:36:10 +01:00
|
|
|
auto cmd = editorContextMenu->addSeparator(m_watchCommand->context());
|
|
|
|
|
cmd->setAttribute(Command::CA_Hide);
|
|
|
|
|
cmd = m_watchCommand;
|
|
|
|
|
cmd->action()->setEnabled(true);
|
|
|
|
|
editorContextMenu->addAction(cmd);
|
|
|
|
|
cmd->setAttribute(Command::CA_Hide);
|
|
|
|
|
cmd->setAttribute(Command::CA_NonConfigurable);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-07-07 18:34:05 +02:00
|
|
|
|
2018-08-21 12:30:00 +02:00
|
|
|
DebuggerMainWindow::ensureMainWindowExists();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
2010-05-05 12:41:52 +02:00
|
|
|
|
2019-09-17 17:13:32 +02:00
|
|
|
QWidget *DebuggerPluginPrivate::addSearch(BaseTreeView *treeView)
|
|
|
|
|
{
|
2023-07-13 15:23:29 +02:00
|
|
|
BoolAspect &act = settings().useAlternatingRowColors;
|
|
|
|
|
treeView->setAlternatingRowColors(act());
|
2019-12-09 15:12:55 +01:00
|
|
|
treeView->setProperty(PerspectiveState::savesHeaderKey(), true);
|
2021-03-01 08:59:44 +01:00
|
|
|
connect(&act, &BaseAspect::changed, treeView, [treeView] {
|
2023-07-13 15:23:29 +02:00
|
|
|
treeView->setAlternatingRowColors(settings().useAlternatingRowColors());
|
2021-03-01 08:59:44 +01:00
|
|
|
});
|
2019-09-17 17:13:32 +02:00
|
|
|
|
|
|
|
|
return ItemViewFind::createSearchableWrapper(treeView);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Console *debuggerConsole()
|
|
|
|
|
{
|
|
|
|
|
return &dd->m_console;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QWidget *addSearch(BaseTreeView *treeView)
|
|
|
|
|
{
|
|
|
|
|
return dd->addSearch(treeView);
|
2010-11-10 16:33:11 +01:00
|
|
|
}
|
|
|
|
|
|
2014-10-22 13:04:47 +02:00
|
|
|
void openTextEditor(const QString &titlePattern0, const QString &contents)
|
|
|
|
|
{
|
2023-05-22 13:21:57 +02:00
|
|
|
if (PluginManager::isShuttingDown())
|
2014-10-22 13:04:47 +02:00
|
|
|
return;
|
|
|
|
|
QString titlePattern = titlePattern0;
|
|
|
|
|
IEditor *editor = EditorManager::openEditorWithContents(
|
2015-02-26 20:50:28 +03:00
|
|
|
CC::K_DEFAULT_TEXT_EDITOR_ID, &titlePattern, contents.toUtf8(), QString(),
|
2014-10-22 13:04:47 +02:00
|
|
|
EditorManager::IgnoreNavigationHistory);
|
2015-07-20 17:07:28 +02:00
|
|
|
if (auto textEditor = qobject_cast<BaseTextEditor *>(editor)) {
|
|
|
|
|
QString suggestion = titlePattern;
|
2018-10-07 22:38:47 +03:00
|
|
|
if (!suggestion.contains('.'))
|
|
|
|
|
suggestion.append(".txt");
|
2016-01-14 14:45:01 +01:00
|
|
|
textEditor->textDocument()->setFallbackSaveAsFileName(suggestion);
|
2015-07-20 17:07:28 +02:00
|
|
|
}
|
2014-10-22 13:04:47 +02:00
|
|
|
QTC_ASSERT(editor, return);
|
|
|
|
|
}
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-11-10 11:39:01 +01:00
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// DebuggerPlugin
|
|
|
|
|
//
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2024-01-12 18:16:51 +01:00
|
|
|
class DebuggerPlugin final : public ExtensionSystem::IPlugin
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Debugger.json")
|
2011-02-04 15:08:31 +01:00
|
|
|
|
2024-01-12 18:16:51 +01:00
|
|
|
public:
|
|
|
|
|
DebuggerPlugin();
|
|
|
|
|
~DebuggerPlugin() final;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// IPlugin implementation.
|
|
|
|
|
bool initialize(const QStringList &arguments, QString *errorMessage) final;
|
|
|
|
|
QObject *remoteCommand(const QStringList &options,
|
|
|
|
|
const QString &workingDirectory,
|
|
|
|
|
const QStringList &arguments) final;
|
|
|
|
|
ShutdownFlag aboutToShutdown() final;
|
|
|
|
|
void extensionsInitialized() final;
|
|
|
|
|
|
|
|
|
|
// Called from AppOutputPane::attachToRunControl().
|
|
|
|
|
Q_SLOT void attachExternalApplication(ProjectExplorer::RunControl *rc);
|
|
|
|
|
|
|
|
|
|
// Called from GammaRayIntegration
|
|
|
|
|
Q_SLOT void getEnginesState(QByteArray *json) const;
|
|
|
|
|
|
|
|
|
|
// Called from DockerDevice
|
|
|
|
|
Q_SLOT void autoDetectDebuggersForDevice(const Utils::FilePaths &searchPaths,
|
|
|
|
|
const QString &detectionId,
|
|
|
|
|
QString *logMessage);
|
|
|
|
|
Q_SLOT void removeDetectedDebuggers(const QString &detectionId, QString *logMessage);
|
|
|
|
|
Q_SLOT void listDetectedDebuggers(const QString &detectionId, QString *logMessage);
|
|
|
|
|
|
|
|
|
|
Q_SLOT void attachToProcess(const qint64 processId, const Utils::FilePath &executable);
|
|
|
|
|
};
|
2011-02-04 15:08:31 +01:00
|
|
|
|
2010-11-10 11:39:01 +01:00
|
|
|
DebuggerPlugin::DebuggerPlugin()
|
2010-07-13 15:57:34 +02:00
|
|
|
{
|
2018-10-07 22:38:47 +03:00
|
|
|
setObjectName("DebuggerPlugin");
|
2016-02-24 14:42:52 +01:00
|
|
|
m_instance = this;
|
2020-02-11 12:55:31 +01:00
|
|
|
|
|
|
|
|
qRegisterMetaType<PerspectiveState>("Utils::PerspectiveState");
|
2010-08-18 13:54:12 +02:00
|
|
|
}
|
|
|
|
|
|
2010-11-10 11:39:01 +01:00
|
|
|
DebuggerPlugin::~DebuggerPlugin()
|
2010-08-18 13:54:12 +02:00
|
|
|
{
|
2014-10-22 13:04:47 +02:00
|
|
|
delete dd;
|
2018-07-23 22:28:49 +02:00
|
|
|
dd = nullptr;
|
|
|
|
|
m_instance = nullptr;
|
2016-02-24 14:42:52 +01:00
|
|
|
}
|
|
|
|
|
|
2011-12-06 15:39:25 +01:00
|
|
|
IPlugin::ShutdownFlag DebuggerPlugin::aboutToShutdown()
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
2018-01-26 12:26:43 +01:00
|
|
|
ExtensionSystem::PluginManager::removeObject(this);
|
2024-01-12 18:16:51 +01:00
|
|
|
|
|
|
|
|
disconnect(ProjectManager::instance(), &ProjectManager::startupProjectChanged, dd, nullptr);
|
|
|
|
|
|
|
|
|
|
dd->m_shutdownTimer.setInterval(0);
|
|
|
|
|
dd->m_shutdownTimer.setSingleShot(true);
|
|
|
|
|
|
|
|
|
|
connect(&dd->m_shutdownTimer, &QTimer::timeout, this, [this] {
|
|
|
|
|
DebuggerMainWindow::doShutdown();
|
|
|
|
|
|
|
|
|
|
dd->m_shutdownTimer.stop();
|
|
|
|
|
|
|
|
|
|
delete dd->m_mode;
|
|
|
|
|
dd->m_mode = nullptr;
|
|
|
|
|
emit asynchronousShutdownFinished();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (EngineManager::shutDown()) {
|
|
|
|
|
// If any engine is aborting we give them extra three seconds.
|
|
|
|
|
dd->m_shutdownTimer.setInterval(3000);
|
|
|
|
|
}
|
|
|
|
|
dd->m_shutdownTimer.start();
|
|
|
|
|
|
2017-07-07 09:23:26 +03:00
|
|
|
return AsynchronousShutdown;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2013-03-11 18:15:49 +02:00
|
|
|
QObject *DebuggerPlugin::remoteCommand(const QStringList &options,
|
2015-03-09 10:59:58 +02:00
|
|
|
const QString &workingDirectory,
|
|
|
|
|
const QStringList &list)
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
2019-07-23 10:58:00 +02:00
|
|
|
Q_UNUSED(workingDirectory)
|
|
|
|
|
Q_UNUSED(list)
|
2015-03-09 10:59:58 +02:00
|
|
|
dd->remoteCommand(options);
|
2018-07-23 22:28:49 +02:00
|
|
|
return nullptr;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2010-11-10 11:39:01 +01:00
|
|
|
void DebuggerPlugin::extensionsInitialized()
|
2010-11-05 13:35:31 +01:00
|
|
|
{
|
2014-10-22 13:04:47 +02:00
|
|
|
dd->extensionsInitialized();
|
2010-11-05 13:35:31 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
} // namespace Internal
|
|
|
|
|
|
|
|
|
|
static bool buildTypeAccepted(QFlags<ToolMode> toolMode, BuildConfiguration::BuildType buildType)
|
|
|
|
|
{
|
|
|
|
|
if (buildType == BuildConfiguration::Unknown)
|
|
|
|
|
return true;
|
|
|
|
|
if (buildType == BuildConfiguration::Debug && (toolMode & DebugMode))
|
|
|
|
|
return true;
|
|
|
|
|
if (buildType == BuildConfiguration::Release && (toolMode & ReleaseMode))
|
|
|
|
|
return true;
|
|
|
|
|
if (buildType == BuildConfiguration::Profile && (toolMode & ProfileMode))
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2016-02-29 12:11:18 +01:00
|
|
|
|
2017-04-12 10:06:41 +02:00
|
|
|
static BuildConfiguration::BuildType startupBuildType()
|
|
|
|
|
{
|
2016-03-02 13:57:37 +01:00
|
|
|
BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown;
|
2023-02-14 15:47:22 +01:00
|
|
|
if (RunConfiguration *runConfig = ProjectManager::startupRunConfiguration()) {
|
2017-04-12 10:06:41 +02:00
|
|
|
if (const BuildConfiguration *buildConfig = runConfig->target()->activeBuildConfiguration())
|
|
|
|
|
buildType = buildConfig->buildType();
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2017-04-12 10:06:41 +02:00
|
|
|
return buildType;
|
|
|
|
|
}
|
2016-02-29 12:11:18 +01:00
|
|
|
|
2017-04-12 10:06:41 +02:00
|
|
|
void showCannotStartDialog(const QString &text)
|
|
|
|
|
{
|
2020-06-02 09:10:40 +02:00
|
|
|
auto errorDialog = new QMessageBox(ICore::dialogParent());
|
2017-09-29 12:24:39 +02:00
|
|
|
errorDialog->setAttribute(Qt::WA_DeleteOnClose);
|
2017-04-12 10:06:41 +02:00
|
|
|
errorDialog->setIcon(QMessageBox::Warning);
|
|
|
|
|
errorDialog->setWindowTitle(text);
|
2022-07-05 15:37:08 +02:00
|
|
|
errorDialog->setText(Tr::tr("Cannot start %1 without a project. Please open the project "
|
2017-04-12 10:06:41 +02:00
|
|
|
"and try again.").arg(text));
|
|
|
|
|
errorDialog->setStandardButtons(QMessageBox::Ok);
|
|
|
|
|
errorDialog->setDefaultButton(QMessageBox::Ok);
|
|
|
|
|
errorDialog->show();
|
|
|
|
|
}
|
2016-02-29 12:11:18 +01:00
|
|
|
|
2017-04-12 10:06:41 +02:00
|
|
|
bool wantRunTool(ToolMode toolMode, const QString &toolName)
|
|
|
|
|
{
|
2016-03-02 13:57:37 +01:00
|
|
|
// Check the project for whether the build config is in the correct mode
|
|
|
|
|
// if not, notify the user and urge him to use the correct mode.
|
2017-04-12 10:06:41 +02:00
|
|
|
BuildConfiguration::BuildType buildType = startupBuildType();
|
|
|
|
|
if (!buildTypeAccepted(toolMode, buildType)) {
|
2016-03-02 13:57:37 +01:00
|
|
|
QString currentMode;
|
|
|
|
|
switch (buildType) {
|
|
|
|
|
case BuildConfiguration::Debug:
|
2022-07-05 15:37:08 +02:00
|
|
|
currentMode = Tr::tr("Debug");
|
2016-03-02 13:57:37 +01:00
|
|
|
break;
|
|
|
|
|
case BuildConfiguration::Profile:
|
2022-07-05 15:37:08 +02:00
|
|
|
currentMode = Tr::tr("Profile");
|
2016-03-02 13:57:37 +01:00
|
|
|
break;
|
|
|
|
|
case BuildConfiguration::Release:
|
2022-07-05 15:37:08 +02:00
|
|
|
currentMode = Tr::tr("Release");
|
2016-03-02 13:57:37 +01:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
QTC_CHECK(false);
|
|
|
|
|
}
|
2016-02-29 12:11:18 +01:00
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
QString toolModeString;
|
2017-04-12 10:06:41 +02:00
|
|
|
switch (toolMode) {
|
2016-03-02 13:57:37 +01:00
|
|
|
case DebugMode:
|
2022-07-05 15:37:08 +02:00
|
|
|
toolModeString = Tr::tr("in Debug mode");
|
2016-03-02 13:57:37 +01:00
|
|
|
break;
|
|
|
|
|
case ProfileMode:
|
2022-07-05 15:37:08 +02:00
|
|
|
toolModeString = Tr::tr("in Profile mode");
|
2016-03-02 13:57:37 +01:00
|
|
|
break;
|
|
|
|
|
case ReleaseMode:
|
2022-07-05 15:37:08 +02:00
|
|
|
toolModeString = Tr::tr("in Release mode");
|
2016-03-02 13:57:37 +01:00
|
|
|
break;
|
|
|
|
|
case SymbolsMode:
|
2022-07-05 15:37:08 +02:00
|
|
|
toolModeString = Tr::tr("with debug symbols (Debug or Profile mode)");
|
2016-03-02 13:57:37 +01:00
|
|
|
break;
|
|
|
|
|
case OptimizedMode:
|
2022-07-05 15:37:08 +02:00
|
|
|
toolModeString = Tr::tr("on optimized code (Profile or Release mode)");
|
2016-03-02 13:57:37 +01:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
QTC_CHECK(false);
|
|
|
|
|
}
|
2022-07-05 15:37:08 +02:00
|
|
|
const QString title = Tr::tr("Run %1 in %2 Mode?").arg(toolName).arg(currentMode);
|
|
|
|
|
const QString message = Tr::tr("<html><head/><body><p>You are trying "
|
2016-03-02 13:57:37 +01:00
|
|
|
"to run the tool \"%1\" on an application in %2 mode. "
|
|
|
|
|
"The tool is designed to be used %3.</p><p>"
|
|
|
|
|
"Run-time characteristics differ significantly between "
|
|
|
|
|
"optimized and non-optimized binaries. Analytical "
|
|
|
|
|
"findings for one mode may or may not be relevant for "
|
|
|
|
|
"the other.</p><p>"
|
|
|
|
|
"Running tools that need debug symbols on binaries that "
|
|
|
|
|
"don't provide any may lead to missing function names "
|
|
|
|
|
"or otherwise insufficient output.</p><p>"
|
|
|
|
|
"Do you want to continue and run the tool in %2 mode?</p></body></html>")
|
|
|
|
|
.arg(toolName).arg(currentMode).arg(toolModeString);
|
2023-04-28 08:39:20 +02:00
|
|
|
if (Utils::CheckableMessageBox::question(ICore::dialogParent(),
|
|
|
|
|
title,
|
|
|
|
|
message,
|
2023-09-22 16:15:27 +02:00
|
|
|
Key("AnalyzerCorrectModeWarning"))
|
2023-04-28 08:39:20 +02:00
|
|
|
!= QMessageBox::Yes)
|
|
|
|
|
return false;
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
2016-02-29 12:11:18 +01:00
|
|
|
|
2017-04-12 10:06:41 +02:00
|
|
|
return true;
|
2016-02-29 12:11:18 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-02 13:57:37 +01:00
|
|
|
QAction *createStartAction()
|
|
|
|
|
{
|
2023-02-10 14:44:09 +01:00
|
|
|
auto action = new QAction(Tr::tr("Start"), m_instance);
|
2016-05-30 16:29:51 +02:00
|
|
|
action->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR.icon());
|
2016-03-02 13:57:37 +01:00
|
|
|
action->setEnabled(true);
|
|
|
|
|
return action;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAction *createStopAction()
|
|
|
|
|
{
|
2023-02-10 14:44:09 +01:00
|
|
|
auto action = new QAction(Tr::tr("Stop"), m_instance);
|
2016-08-03 17:55:54 +02:00
|
|
|
action->setIcon(Utils::Icons::STOP_SMALL_TOOLBAR.icon());
|
2016-03-02 13:57:37 +01:00
|
|
|
action->setEnabled(true);
|
|
|
|
|
return action;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void enableMainWindow(bool on)
|
|
|
|
|
{
|
2018-08-21 12:30:00 +02:00
|
|
|
DebuggerMainWindow::instance()->setEnabled(on);
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void showPermanentStatusMessage(const QString &message)
|
|
|
|
|
{
|
2018-08-21 12:30:00 +02:00
|
|
|
DebuggerMainWindow::showStatusMessage(message, -1);
|
2016-03-02 13:57:37 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-09 19:16:14 +01:00
|
|
|
namespace Internal {
|
2016-03-02 10:49:06 +02:00
|
|
|
|
2023-02-09 10:14:59 +01:00
|
|
|
bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
2016-03-09 19:16:14 +01:00
|
|
|
{
|
2023-02-09 10:14:59 +01:00
|
|
|
Q_UNUSED(errorMessage)
|
2016-03-09 19:16:14 +01:00
|
|
|
|
2023-02-09 10:14:59 +01:00
|
|
|
// Needed for call from AppOutputPane::attachToRunControl() and GammarayIntegration.
|
|
|
|
|
ExtensionSystem::PluginManager::addObject(this);
|
2016-03-09 19:16:14 +01:00
|
|
|
|
2023-02-09 10:14:59 +01:00
|
|
|
dd = new DebuggerPluginPrivate(arguments);
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_TESTS
|
2024-01-18 18:30:14 +01:00
|
|
|
addTestCreator(createDebuggerTest);
|
2023-02-09 10:14:59 +01:00
|
|
|
#endif
|
2012-01-26 13:14:00 +01:00
|
|
|
|
2023-02-09 10:14:59 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2012-01-23 16:45:00 +01:00
|
|
|
|
2024-01-12 18:16:51 +01:00
|
|
|
void DebuggerPlugin::attachToProcess(const qint64 processId, const Utils::FilePath &executable)
|
|
|
|
|
{
|
|
|
|
|
ProcessInfo processInfo;
|
|
|
|
|
processInfo.processId = processId;
|
|
|
|
|
processInfo.executable = executable.toString();
|
|
|
|
|
|
|
|
|
|
auto kitChooser = new KitChooser;
|
|
|
|
|
kitChooser->setShowIcons(true);
|
|
|
|
|
kitChooser->populate();
|
|
|
|
|
Kit *kit = kitChooser->currentKit();
|
|
|
|
|
|
|
|
|
|
dd->attachToRunningProcess(kit, processInfo, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerPlugin::attachExternalApplication(RunControl *rc)
|
|
|
|
|
{
|
|
|
|
|
ProcessHandle pid = rc->applicationProcessHandle();
|
|
|
|
|
auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
|
|
|
|
runControl->setTarget(rc->target());
|
|
|
|
|
runControl->setDisplayName(Tr::tr("Process %1").arg(pid.pid()));
|
|
|
|
|
auto debugger = new DebuggerRunTool(runControl);
|
|
|
|
|
debugger->setInferiorExecutable(rc->targetFilePath());
|
|
|
|
|
debugger->setAttachPid(pid);
|
|
|
|
|
debugger->setStartMode(AttachToLocalProcess);
|
|
|
|
|
debugger->setCloseMode(DetachAtClose);
|
|
|
|
|
debugger->startRunControl();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerPlugin::getEnginesState(QByteArray *json) const
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(json, return);
|
|
|
|
|
QVariantMap result {
|
|
|
|
|
{"version", 1}
|
|
|
|
|
};
|
|
|
|
|
QVariantMap states;
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
DebuggerEngine *currentEngine = EngineManager::currentEngine();
|
|
|
|
|
for (DebuggerEngine *engine : EngineManager::engines()) {
|
|
|
|
|
states[QString::number(i)] = QVariantMap({
|
|
|
|
|
{"current", engine == currentEngine},
|
|
|
|
|
{"pid", engine->inferiorPid()},
|
|
|
|
|
{"state", engine->state()}
|
|
|
|
|
});
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!states.isEmpty())
|
|
|
|
|
result["states"] = states;
|
|
|
|
|
|
|
|
|
|
*json = QJsonDocument(QJsonObject::fromVariantMap(result)).toJson();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerPlugin::autoDetectDebuggersForDevice(const FilePaths &searchPaths,
|
|
|
|
|
const QString &detectionSource,
|
|
|
|
|
QString *logMessage)
|
|
|
|
|
{
|
|
|
|
|
DebuggerItemManager::autoDetectDebuggersForDevice(searchPaths, detectionSource, logMessage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerPlugin::removeDetectedDebuggers(const QString &detectionSource, QString *logMessage)
|
|
|
|
|
{
|
|
|
|
|
DebuggerItemManager::removeDetectedDebuggers(detectionSource, logMessage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerPlugin::listDetectedDebuggers(const QString &detectionSource, QString *logMessage)
|
|
|
|
|
{
|
|
|
|
|
DebuggerItemManager::listDetectedDebuggers(detectionSource, logMessage);
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-05 15:37:08 +02:00
|
|
|
} // Internal
|
|
|
|
|
} // Debugger
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "debuggerplugin.moc"
|