1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "debuggerplugin.h"
36 #include "debuggerstartparameters.h"
37 #include "debuggeractions.h"
38 #include "debuggerconstants.h"
39 #include "debuggercore.h"
40 #include "debuggerdialogs.h"
41 #include "debuggerengine.h"
42 #include "debuggermainwindow.h"
43 #include "debuggerrunner.h"
44 #include "debuggerruncontrolfactory.h"
45 #include "debuggerstringutils.h"
46 #include "debuggertooltip.h"
48 #include "breakpoint.h"
49 #include "breakhandler.h"
50 #include "breakwindow.h"
51 #include "consolewindow.h"
52 #include "disassembleragent.h"
53 #include "logwindow.h"
54 #include "moduleswindow.h"
55 #include "moduleshandler.h"
56 #include "registerwindow.h"
57 #include "snapshotwindow.h"
58 #include "stackhandler.h"
59 #include "stackwindow.h"
60 #include "sourcefileswindow.h"
61 #include "threadswindow.h"
62 #include "watchhandler.h"
63 #include "watchwindow.h"
64 #include "watchutils.h"
66 #include "snapshothandler.h"
67 #include "threadshandler.h"
68 #include "gdb/gdboptionspage.h"
70 #include "ui_commonoptionspage.h"
71 #include "ui_dumperoptionpage.h"
73 #include <coreplugin/actionmanager/actionmanager.h>
74 #include <coreplugin/actionmanager/actioncontainer.h>
75 #include <coreplugin/actionmanager/command.h>
76 #include <coreplugin/uniqueidmanager.h>
77 #include <coreplugin/imode.h>
78 #include <coreplugin/coreconstants.h>
79 #include <coreplugin/dialogs/ioptionspage.h>
80 #include <coreplugin/editormanager/editormanager.h>
81 #include <coreplugin/findplaceholder.h>
82 #include <coreplugin/icontext.h>
83 #include <coreplugin/icore.h>
84 #include <coreplugin/imode.h>
85 #include <coreplugin/icorelistener.h>
86 #include <coreplugin/manhattanstyle.h>
87 #include <coreplugin/minisplitter.h>
88 #include <coreplugin/modemanager.h>
90 #include <cppeditor/cppeditorconstants.h>
91 #include <cplusplus/ModelManagerInterface.h>
93 #include <extensionsystem/pluginmanager.h>
95 #include <projectexplorer/project.h>
96 #include <projectexplorer/projectexplorer.h>
97 #include <projectexplorer/projectexplorerconstants.h>
98 #include <projectexplorer/session.h>
99 #include <projectexplorer/target.h>
100 #include <projectexplorer/toolchain.h>
101 #include <projectexplorer/toolchaintype.h>
103 #include <qt4projectmanager/qt4projectmanagerconstants.h>
105 #include <texteditor/basetexteditor.h>
106 #include <texteditor/fontsettings.h>
107 #include <texteditor/texteditorsettings.h>
109 #include <utils/qtcassert.h>
110 #include <utils/savedaction.h>
111 #include <utils/styledbar.h>
113 #include <qml/scriptconsole.h>
115 #include <QtCore/QTimer>
116 #include <QtCore/QtPlugin>
117 #include <QtGui/QComboBox>
118 #include <QtGui/QDockWidget>
119 #include <QtGui/QFileDialog>
120 #include <QtGui/QMenu>
121 #include <QtGui/QMessageBox>
122 #include <QtGui/QPushButton>
123 #include <QtGui/QTextBlock>
124 #include <QtGui/QTextCursor>
125 #include <QtGui/QToolButton>
126 #include <QtGui/QTreeWidget>
130 #define DEBUG_STATE 1
132 //# define STATE_DEBUG(s)
133 // do { QString msg; QTextStream ts(&msg); ts << s;
134 // showMessage(msg, LogDebug); } while (0)
135 # define STATE_DEBUG(s) do { qDebug() << s; } while(0)
137 # define STATE_DEBUG(s)
140 // Note: the Debugger process itself and any helper processes like
141 // gdbserver, the trk client etc are referred to as 'Engine',
142 // whereas the debugged process is referred to as 'Inferior'.
144 // Transitions marked by '---' are done in the individual engines.
145 // Transitions marked by '+-+' are done in the base DebuggerEngine.
146 // Transitions marked by '*' are done asynchronously.
147 // The GdbEngine->setupEngine() function is described in more detail below.
149 // The engines are responsible for local roll-back to the last
150 // acknowledged state before calling notify*Failed. I.e. before calling
151 // notifyEngineSetupFailed() any process started during setupEngine()
152 // so far must be terminated.
158 // EngineSetupRequested
160 // (calls *Engine->setupEngine())
165 // SetupOk} SetupFailed}
167 // + `+-+-+> EngineSetupFailed
169 // + [calls RunControl->startFailed]
171 // + DebuggerFinished
175 // [calls RunControl->StartSuccessful]
177 // InferiorSetupRequested
179 // (calls *Engine->setupInferior())
183 // Inferior- Inferior-
184 // SetupOk} SetupFailed}
186 // + ` +-+-> InferiorSetupFailed +-+-+-+-+-+->.
189 // EngineRunRequested +
191 // (calls *Engine->runEngine()) +
194 // | (core) | (attach) | | +
196 // {notify- {notifyER&- {notifyER&- {notify- +
197 // Inferior- Inferior- Inferior- EngineRun- +
198 // Unrunnable} StopOk} RunOk} Failed} +
200 // InferiorUnrunnable + InferiorRunOk + +
202 // InferiorStopOk EngineRunFailed +
204 // `-+-+-+-+-+-+-+-+-+-+-+>-+
207 // #Interrupt@InferiorRunOk# +
209 // InferiorStopRequested +
210 // #SpontaneousStop + +
211 // @InferiorRunOk# (calls *Engine-> +
212 // + interruptInferior()) +
214 // Spontaneous- {notify- {notify- +
215 // Inferior- Inferior- Inferior- +
216 // StopOk} StopOk} StopFailed} +
219 // InferiorStopOk + +
223 // #Stop@InferiorUnrunnable# + +
224 // #Creator Close Event# + +
226 // InferiorShutdownRequested +
228 // (calls *Engine->shutdownInferior()) +
230 // {notify- {notify- +
231 // Inferior- Inferior- +
232 // ShutdownOk} ShutdownFailed} +
235 // #Inferior exited# + + +
237 // {notifyInferior- + + +
242 // InferiorShutdownOk InferiorShutdownFailed +
244 // EngineShutdownRequested +
246 // (calls *Engine->shutdownEngine()) <+-+-+-+-+-+-+-+-+-+-+-+-+-+'
251 // ShutdownOk} ShutdownFailed}
253 // EngineShutdownOk EngineShutdownFailed
259 /* Here is a matching graph as a GraphViz graph. View it using
261 grep "^sg1:" debuggerplugin.cpp | cut -c5- | dot -osg1.ps -Tps && gv sg1.ps
263 sg1: digraph DebuggerStates {
264 sg1: DebuggerNotReady -> EngineSetupRequested
265 sg1: EngineSetupRequested -> EngineSetupOk [ label="notifyEngineSetupOk", style="dashed" ];
266 sg1: EngineSetupRequested -> EngineSetupFailed [ label= "notifyEngineSetupFailed", style="dashed"];
267 sg1: EngineSetupFailed -> DebuggerFinished [ label= "RunControl::StartFailed" ];
268 sg1: EngineSetupOk -> InferiorSetupRequested [ label= "RunControl::StartSuccessful" ];
269 sg1: InferiorSetupRequested -> InferiorSetupFailed [ label="notifyInferiorFailed", style="dashed" ];
270 sg1: InferiorSetupRequested -> EngineRunRequested [ label="notifyInferiorSetupOk", style="dashed" ];
271 sg1: InferiorSetupFailed -> EngineShutdownRequested
272 sg1: EngineRunRequested -> InferiorUnrunnable [ label="notifyInferiorUnrunnable", style="dashed" ];
273 sg1: EngineRunRequested -> InferiorStopOk [ label="notifyEngineRunAndInferiorStopOk", style="dashed" ];
274 sg1: EngineRunRequested -> InferiorRunOk [ label="notifyEngineRunAndInferiorRunOk", style="dashed" ];
275 sg1: EngineRunRequested -> EngineRunFailed [ label="notifyEngineRunFailed", style="dashed" ];
276 sg1: EngineRunFailed -> EngineShutdownRequested
277 sg1: InferiorRunOk -> InferiorStopOk [ label="SpontaneousStop\nnotifyInferiorSpontaneousStop", style="dashed" ];
278 sg1: InferiorRunOk -> InferiorStopRequested [ label="User stop\nEngine::interruptInferior", style="dashed"];
279 sg1: InferiorStopRequested -> InferiorStopOk [ label="notifyInferiorStopOk", style="dashed" ];
280 sg1: InferiorStopRequested -> InferiorShutdownRequested [ label="notifyInferiorStopFailed", style="dashed" ];
281 sg1: InferiorStopOk -> InferiorRunRequested [ label="User\nEngine::continueInferior" ];
282 sg1: InferiorRunRequested -> InferiorRunOk [ label="notifyInferiorRunOk", style="dashed"];
283 sg1: InferiorRunRequested -> InferiorRunFailed [ label="notifyInferiorRunFailed", style="dashed"];
284 sg1: InferiorRunFailed -> InferiorStopOk
285 sg1: InferiorShutdownRequested -> InferiorShutdownOk [ label= "Engine::shutdownInferior\nnotifyInferiorShutdownOk", style="dashed" ];
286 sg1: InferiorShutdownRequested -> InferiorShutdownFailed [ label="Engine::shutdownInferior\nnotifyInferiorShutdownFailed", style="dashed" ];
287 sg1: InferiorExited -> InferiorShutdownOk [ label="notifyInferiorExited", style="dashed"];
288 sg1: InferiorShutdownOk -> EngineShutdownRequested
289 sg1: InferiorShutdownFailed -> EngineShutdownRequested
290 sg1: EngineShutdownRequested -> EngineShutdownOk [ label="Engine::shutdownEngine\nnotifyEngineShutdownOk", style="dashed" ];
291 sg1: EngineShutdownRequested -> EngineShutdownFailed [ label="Engine::shutdownEngine\nnotifyEngineShutdownFailed", style="dashed" ];
292 sg1: EngineShutdownOk -> DebuggerFinished [ style = "dotted" ];
293 sg1: EngineShutdownFailed -> DebuggerFinished [ style = "dotted" ];
296 // Additional signalling: {notifyInferiorIll} {notifyEngineIll}
299 // GdbEngine specific startup. All happens in EngineSetupRequested state
301 // Transitions marked by '---' are done in the individual adapters.
302 // Transitions marked by '+-+' are done in the GdbEngine.
304 // GdbEngine::setupEngine()
306 // (calls *Adapter->startAdapter())
308 // | `---> handleAdapterStartFailed()
310 // | {notifyEngineSetupFailed}
312 // handleAdapterStarted()
314 // {notifyEngineSetupOk}
318 // GdbEngine::setupInferior()
320 // (calls *Adapter->prepareInferior())
322 // | `---> handlePrepareInferiorFailed()
324 // | {notifyInferiorSetupFailed}
326 // handleInferiorPrepared()
328 // {notifyInferiorSetupOk}
334 using namespace Core;
335 using namespace Debugger::Constants;
336 using namespace ProjectExplorer;
337 using namespace TextEditor;
339 namespace CC = Core::Constants;
340 namespace PE = ProjectExplorer::Constants;
344 namespace Constants {
346 const char * const M_DEBUG_START_DEBUGGING = "QtCreator.Menu.Debug.StartDebugging";
348 const char * const STARTEXTERNAL = "Debugger.StartExternal";
349 const char * const ATTACHEXTERNAL = "Debugger.AttachExternal";
350 const char * const ATTACHCORE = "Debugger.AttachCore";
351 const char * const ATTACHTCF = "Debugger.AttachTcf";
352 const char * const ATTACHREMOTE = "Debugger.AttachRemote";
353 const char * const ATTACHREMOTECDB = "Debugger.AttachRemoteCDB";
354 const char * const STARTREMOTELLDB = "Debugger.StartRemoteLLDB";
355 const char * const DETACH = "Debugger.Detach";
357 const char * const RUN_TO_LINE1 = "Debugger.RunToLine1";
358 const char * const RUN_TO_LINE2 = "Debugger.RunToLine2";
359 const char * const RUN_TO_FUNCTION = "Debugger.RunToFunction";
360 const char * const JUMP_TO_LINE1 = "Debugger.JumpToLine1";
361 const char * const JUMP_TO_LINE2 = "Debugger.JumpToLine2";
362 const char * const RETURN_FROM_FUNCTION = "Debugger.ReturnFromFunction";
363 const char * const SNAPSHOT = "Debugger.Snapshot";
364 const char * const TOGGLE_BREAK = "Debugger.ToggleBreak";
365 const char * const BREAK_BY_FUNCTION = "Debugger.BreakByFunction";
366 const char * const BREAK_AT_MAIN = "Debugger.BreakAtMain";
367 const char * const ADD_TO_WATCH1 = "Debugger.AddToWatch1";
368 const char * const ADD_TO_WATCH2 = "Debugger.AddToWatch2";
369 const char * const OPERATE_BY_INSTRUCTION = "Debugger.OperateByInstruction";
370 const char * const FRAME_UP = "Debugger.FrameUp";
371 const char * const FRAME_DOWN = "Debugger.FrameDown";
374 const char * const STOP_KEY = "Shift+Ctrl+Y";
375 const char * const RESET_KEY = "Ctrl+Shift+F5";
376 const char * const STEP_KEY = "Ctrl+Shift+I";
377 const char * const STEPOUT_KEY = "Ctrl+Shift+T";
378 const char * const NEXT_KEY = "Ctrl+Shift+O";
379 const char * const REVERSE_KEY = "";
380 const char * const RUN_TO_LINE_KEY = "Shift+F8";
381 const char * const RUN_TO_FUNCTION_KEY = "Ctrl+F6";
382 const char * const JUMP_TO_LINE_KEY = "Ctrl+D,Ctrl+L";
383 const char * const TOGGLE_BREAK_KEY = "F8";
384 const char * const BREAK_BY_FUNCTION_KEY = "Ctrl+D,Ctrl+F";
385 const char * const BREAK_AT_MAIN_KEY = "Ctrl+D,Ctrl+M";
386 const char * const ADD_TO_WATCH_KEY = "Ctrl+D,Ctrl+W";
387 const char * const SNAPSHOT_KEY = "Ctrl+D,Ctrl+S";
389 const char * const STOP_KEY = "Shift+F5";
390 const char * const RESET_KEY = "Ctrl+Shift+F5";
391 const char * const STEP_KEY = "F11";
392 const char * const STEPOUT_KEY = "Shift+F11";
393 const char * const NEXT_KEY = "F10";
394 const char * const REVERSE_KEY = "F12";
395 const char * const RUN_TO_LINE_KEY = "";
396 const char * const RUN_TO_FUNCTION_KEY = "";
397 const char * const JUMP_TO_LINE_KEY = "";
398 const char * const TOGGLE_BREAK_KEY = "F9";
399 const char * const BREAK_BY_FUNCTION_KEY = "";
400 const char * const BREAK_AT_MAIN_KEY = "";
401 const char * const ADD_TO_WATCH_KEY = "Ctrl+Alt+Q";
402 const char * const SNAPSHOT_KEY = "Ctrl+D,Ctrl+S";
405 } // namespace Constants
409 void addCdb2OptionPages(QList<Core::IOptionsPage*> *);
416 // The createCdbEngine function takes a list of options pages it can add to.
417 // This allows for having a "enabled" toggle on the page independently
418 // of the engine. That's good for not enabling the related ActiveX control
421 void addGdbOptionPages(QList<IOptionsPage*> *opts);
422 void addScriptOptionPages(QList<IOptionsPage*> *opts);
423 void addTcfOptionPages(QList<IOptionsPage*> *opts);
426 void addLldbOptionPages(QList<IOptionsPage*> *opts);
429 static SessionManager *sessionManager()
431 return ProjectExplorerPlugin::instance()->session();
434 static QToolButton *toolButton(QAction *action)
436 QToolButton *button = new QToolButton;
437 button->setDefaultAction(action);
441 struct AttachRemoteParameters
443 AttachRemoteParameters() : attachPid(0), winCrashEvent(0) {}
447 QString attachTarget; // core file name or server:port
448 // Event handle for attaching to crashed Windows processes.
449 quint64 winCrashEvent;
452 void AttachRemoteParameters::clear()
454 attachPid = winCrashEvent = 0;
455 attachTarget.clear();
459 ///////////////////////////////////////////////////////////////////////
463 ///////////////////////////////////////////////////////////////////////
465 class DummyEngine : public DebuggerEngine
470 DummyEngine() : DebuggerEngine(DebuggerStartParameters()) {}
473 void setupEngine() {}
474 void setupInferior() {}
476 void shutdownEngine() {}
477 void shutdownInferior() {}
478 void executeDebuggerCommand(const QString &) {}
479 unsigned debuggerCapabilities() const { return 0; }
480 bool acceptsBreakpoint(BreakpointId) const { return false; }
483 static DebuggerEngine *dummyEngine()
485 static DummyEngine dummy;
490 ///////////////////////////////////////////////////////////////////////
494 ///////////////////////////////////////////////////////////////////////
496 class DebugMode : public IMode
499 DebugMode() : m_widget(0) { setObjectName(QLatin1String("DebugMode")); }
503 // Make sure the editor manager does not get deleted.
504 //EditorManager::instance()->setParent(0);
509 QString displayName() const { return DebuggerPlugin::tr("Debug"); }
510 QIcon icon() const { return QIcon(__(":/fancyactionbar/images/mode_Debug.png")); }
511 int priority() const { return P_MODE_DEBUG; }
513 QString id() const { return MODE_DEBUG; }
514 QString type() const { return CC::MODE_EDIT_TYPE; }
515 Context context() const
516 { return Context(CC::C_EDITORMANAGER, C_DEBUGMODE, CC::C_NAVIGATION_PANE); }
517 QString contextHelpId() const { return QString(); }
523 ///////////////////////////////////////////////////////////////////////
527 ///////////////////////////////////////////////////////////////////////
529 class CommonOptionsPage : public Core::IOptionsPage
532 CommonOptionsPage() {}
536 { return _(DEBUGGER_COMMON_SETTINGS_ID); }
537 QString displayName() const
538 { return QCoreApplication::translate("Debugger", DEBUGGER_COMMON_SETTINGS_NAME); }
539 QString category() const
540 { return _(DEBUGGER_SETTINGS_CATEGORY); }
541 QString displayCategory() const
542 { return QCoreApplication::translate("Debugger", DEBUGGER_SETTINGS_TR_CATEGORY); }
543 QIcon categoryIcon() const
544 { return QIcon(QLatin1String(DEBUGGER_COMMON_SETTINGS_CATEGORY_ICON)); }
546 QWidget *createPage(QWidget *parent);
547 void apply() { m_group.apply(ICore::instance()->settings()); }
548 void finish() { m_group.finish(); }
549 virtual bool matches(const QString &s) const;
552 Ui::CommonOptionsPage m_ui;
553 Utils::SavedActionSet m_group;
554 QString m_searchKeywords;
557 QWidget *CommonOptionsPage::createPage(QWidget *parent)
559 QWidget *w = new QWidget(parent);
563 m_group.insert(debuggerCore()->action(ListSourceFiles),
564 m_ui.checkBoxListSourceFiles);
565 m_group.insert(debuggerCore()->action(UseAlternatingRowColors),
566 m_ui.checkBoxUseAlternatingRowColors);
567 m_group.insert(debuggerCore()->action(UseToolTipsInMainEditor),
568 m_ui.checkBoxUseToolTipsInMainEditor);
569 m_group.insert(debuggerCore()->action(CloseBuffersOnExit),
570 m_ui.checkBoxCloseBuffersOnExit);
571 m_group.insert(debuggerCore()->action(SwitchModeOnExit),
572 m_ui.checkBoxSwitchModeOnExit);
573 m_group.insert(debuggerCore()->action(AutoDerefPointers), 0);
574 m_group.insert(debuggerCore()->action(UseToolTipsInLocalsView), 0);
575 m_group.insert(debuggerCore()->action(UseToolTipsInBreakpointsView), 0);
576 m_group.insert(debuggerCore()->action(UseAddressInBreakpointsView), 0);
577 m_group.insert(debuggerCore()->action(UseAddressInStackView), 0);
578 m_group.insert(debuggerCore()->action(MaximalStackDepth),
579 m_ui.spinBoxMaximalStackDepth);
580 m_group.insert(debuggerCore()->action(ShowStdNamespace), 0);
581 m_group.insert(debuggerCore()->action(ShowQtNamespace), 0);
582 m_group.insert(debuggerCore()->action(SortStructMembers), 0);
583 m_group.insert(debuggerCore()->action(LogTimeStamps), 0);
584 m_group.insert(debuggerCore()->action(VerboseLog), 0);
585 m_group.insert(debuggerCore()->action(BreakOnThrow), 0);
586 m_group.insert(debuggerCore()->action(BreakOnCatch), 0);
588 Utils::SavedAction *registerAction = debuggerCore()->action(RegisterForPostMortem);
589 m_group.insert(registerAction,
590 m_ui.checkBoxRegisterForPostMortem);
591 connect(registerAction, SIGNAL(toggled(bool)),
592 m_ui.checkBoxRegisterForPostMortem, SLOT(setChecked(bool)));
595 if (m_searchKeywords.isEmpty()) {
596 QLatin1Char sep(' ');
597 QTextStream(&m_searchKeywords)
598 << sep << m_ui.checkBoxUseAlternatingRowColors->text()
599 << sep << m_ui.checkBoxUseToolTipsInMainEditor->text()
600 << sep << m_ui.checkBoxListSourceFiles->text()
602 << sep << m_ui.checkBoxRegisterForPostMortem->text()
604 << sep << m_ui.checkBoxCloseBuffersOnExit->text()
605 << sep << m_ui.checkBoxSwitchModeOnExit->text()
606 << sep << m_ui.labelMaximalStackDepth->text()
608 m_searchKeywords.remove(QLatin1Char('&'));
611 m_ui.checkBoxRegisterForPostMortem->setVisible(false);
616 bool CommonOptionsPage::matches(const QString &s) const
618 return m_searchKeywords.contains(s, Qt::CaseInsensitive);
621 ///////////////////////////////////////////////////////////////////////
623 // DebuggingHelperOptionPage
625 ///////////////////////////////////////////////////////////////////////
627 static bool oxygenStyle()
629 const ManhattanStyle *ms = qobject_cast<const ManhattanStyle *>(qApp->style());
630 return ms && !qstrcmp("OxygenStyle", ms->baseStyle()->metaObject()->className());
633 class DebuggingHelperOptionPage : public Core::IOptionsPage
635 Q_OBJECT // Needs tr-context.
637 DebuggingHelperOptionPage() {}
640 QString id() const { return _("Z.DebuggingHelper"); }
641 QString displayName() const { return tr("Debugging Helper"); }
642 QString category() const { return _(DEBUGGER_SETTINGS_CATEGORY); }
643 QString displayCategory() const
644 { return QCoreApplication::translate("Debugger", DEBUGGER_SETTINGS_TR_CATEGORY); }
645 QIcon categoryIcon() const
646 { return QIcon(QLatin1String(DEBUGGER_COMMON_SETTINGS_CATEGORY_ICON)); }
648 QWidget *createPage(QWidget *parent);
649 void apply() { m_group.apply(ICore::instance()->settings()); }
650 void finish() { m_group.finish(); }
651 virtual bool matches(const QString &s) const;
654 Ui::DebuggingHelperOptionPage m_ui;
655 Utils::SavedActionSet m_group;
656 QString m_searchKeywords;
659 QWidget *DebuggingHelperOptionPage::createPage(QWidget *parent)
661 QWidget *w = new QWidget(parent);
664 m_ui.dumperLocationChooser->setExpectedKind(Utils::PathChooser::Command);
665 m_ui.dumperLocationChooser->setPromptDialogTitle(tr("Choose DebuggingHelper Location"));
666 m_ui.dumperLocationChooser->setInitialBrowsePathBackup(
667 ICore::instance()->resourcePath() + "../../lib");
670 m_group.insert(debuggerCore()->action(UseDebuggingHelpers),
671 m_ui.debuggingHelperGroupBox);
672 m_group.insert(debuggerCore()->action(UseCustomDebuggingHelperLocation),
673 m_ui.customLocationGroupBox);
674 // Suppress Oxygen style's giving flat group boxes bold titles.
676 m_ui.customLocationGroupBox->setStyleSheet(_("QGroupBox::title { font: ; }"));
678 m_group.insert(debuggerCore()->action(CustomDebuggingHelperLocation),
679 m_ui.dumperLocationChooser);
681 m_group.insert(debuggerCore()->action(UseCodeModel),
682 m_ui.checkBoxUseCodeModel);
683 m_group.insert(debuggerCore()->action(ShowThreadNames),
684 m_ui.checkBoxShowThreadNames);
689 cmd = am->registerAction(m_dumpLogAction,
690 DUMP_LOG, globalcontext);
691 //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+L")));
692 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+F11")));
693 mdebug->addAction(cmd);
697 if (m_searchKeywords.isEmpty()) {
698 QTextStream(&m_searchKeywords)
699 << ' ' << m_ui.debuggingHelperGroupBox->title()
700 << ' ' << m_ui.customLocationGroupBox->title()
701 << ' ' << m_ui.dumperLocationLabel->text()
702 << ' ' << m_ui.checkBoxUseCodeModel->text()
703 << ' ' << m_ui.checkBoxShowThreadNames->text();
704 m_searchKeywords.remove(QLatin1Char('&'));
709 bool DebuggingHelperOptionPage::matches(const QString &s) const
711 return m_searchKeywords.contains(s, Qt::CaseInsensitive);
715 ///////////////////////////////////////////////////////////////////////
719 ///////////////////////////////////////////////////////////////////////
721 static QString msgParameterMissing(const QString &a)
723 return DebuggerPlugin::tr("Option '%1' is missing the parameter.").arg(a);
726 static QString msgInvalidNumericParameter(const QString &a, const QString &number)
728 return DebuggerPlugin::tr("The parameter '%1' of option '%2' is not a number.").arg(number, a);
731 static bool parseArgument(QStringList::const_iterator &it,
732 const QStringList::const_iterator &cend,
733 AttachRemoteParameters *attachRemoteParameters,
734 unsigned *enabledEngines, QString *errorMessage)
736 const QString &option = *it;
738 // '-debug <corefile>'
739 // '-debug <server:port>'
740 if (*it == _("-debug")) {
743 *errorMessage = msgParameterMissing(*it);
747 attachRemoteParameters->attachPid = it->toULongLong(&ok);
749 attachRemoteParameters->attachTarget = *it;
752 // -wincrashevent <event-handle>. A handle used for
753 // a handshake when attaching to a crashed Windows process.
754 if (*it == _("-wincrashevent")) {
757 *errorMessage = msgParameterMissing(*it);
761 attachRemoteParameters->winCrashEvent = it->toULongLong(&ok);
763 *errorMessage = msgInvalidNumericParameter(option, *it);
769 if (option == _("-disable-cdb")) {
770 *enabledEngines &= ~CdbEngineType;
773 if (option == _("-disable-gdb")) {
774 *enabledEngines &= ~GdbEngineType;
777 if (option == _("-disable-qmldb")) {
778 *enabledEngines &= ~QmlEngineType;
781 if (option == _("-disable-sdb")) {
782 *enabledEngines &= ~ScriptEngineType;
785 if (option == _("-disable-tcf")) {
786 *enabledEngines &= ~TcfEngineType;
789 if (option == _("-disable-lldb")) {
790 *enabledEngines &= ~LldbEngineType;
794 *errorMessage = DebuggerPlugin::tr("Invalid debugger option: %1").arg(option);
798 static bool parseArguments(const QStringList &args,
799 AttachRemoteParameters *attachRemoteParameters,
800 unsigned *enabledEngines, QString *errorMessage)
802 attachRemoteParameters->clear();
803 const QStringList::const_iterator cend = args.constEnd();
804 for (QStringList::const_iterator it = args.constBegin(); it != cend; ++it)
805 if (!parseArgument(it, cend, attachRemoteParameters, enabledEngines, errorMessage))
807 if (Constants::Internal::debug)
808 qDebug().nospace() << args << "engines=0x"
809 << QString::number(*enabledEngines, 16)
810 << " pid" << attachRemoteParameters->attachPid
811 << " target" << attachRemoteParameters->attachTarget << '\n';
816 ///////////////////////////////////////////////////////////////////////
820 ///////////////////////////////////////////////////////////////////////
822 static bool isDebuggable(IEditor *editor)
824 // Only blacklist Qml. Whitelisting would fail on C++ code in files
825 // with strange names, more harm would be done this way.
826 // IFile *file = editor->file();
827 // return !(file && file->mimeType() == "application/x-qml");
828 // Nowadays, even Qml is debuggable.
835 ContextData() : lineNumber(0), address(0) {}
843 } // namespace Internal
844 } // namespace Debugger
846 Q_DECLARE_METATYPE(Debugger::Internal::ContextData)
848 ///////////////////////////////////////////////////////////////////////
852 ///////////////////////////////////////////////////////////////////////
857 struct DebuggerActions
859 QAction *continueAction;
860 QAction *exitAction; // on the application output button if "Stop" is possible
861 QAction *interruptAction; // on the fat debug button if "Pause" is possible
862 QAction *undisturbableAction; // on the fat debug button if nothing can be done
863 QAction *resetAction; // FIXME: Should not be needed in a stable release
865 QAction *stepOutAction;
866 QAction *runToLineAction; // Debug menu
867 QAction *runToFunctionAction;
868 QAction *jumpToLineAction; // in the Debug menu
869 QAction *returnFromFunctionAction;
871 //QAction *snapshotAction;
872 QAction *watchAction1; // in the Debug menu
873 QAction *watchAction2; // in the text editor context menu
874 QAction *breakAction;
876 QAction *reverseDirectionAction;
877 QAction *frameUpAction;
878 QAction *frameDownAction;
881 static DebuggerPluginPrivate *theDebuggerCore = 0;
884 ///////////////////////////////////////////////////////////////////////
886 // DebuggerPluginPrivate
888 ///////////////////////////////////////////////////////////////////////
890 class DebuggerPluginPrivate : public DebuggerCore
895 explicit DebuggerPluginPrivate(DebuggerPlugin *plugin);
896 ~DebuggerPluginPrivate();
898 bool initialize(const QStringList &arguments, QString *errorMessage);
899 void extensionsInitialized();
900 void aboutToShutdown();
902 void connectEngine(DebuggerEngine *engine);
903 void disconnectEngine() { connectEngine(0); }
904 DebuggerEngine *currentEngine() const { return m_currentEngine; }
907 void selectThread(int index)
909 currentEngine()->selectThread(index);
912 void breakpointSetMarginActionTriggered()
914 const QAction *action = qobject_cast<const QAction *>(sender());
915 QTC_ASSERT(action, return);
916 const ContextData data = action->data().value<ContextData>();
918 toggleBreakpointByAddress(data.address);
920 toggleBreakpointByFileAndLine(data.fileName, data.lineNumber);
923 void breakpointRemoveMarginActionTriggered()
925 const QAction *act = qobject_cast<QAction *>(sender());
926 QTC_ASSERT(act, return);
927 m_breakHandler->removeBreakpoint(act->data().toInt());
930 void breakpointEnableMarginActionTriggered()
932 const QAction *act = qobject_cast<QAction *>(sender());
933 QTC_ASSERT(act, return);
934 breakHandler()->setEnabled(act->data().toInt(), true);
937 void breakpointDisableMarginActionTriggered()
939 const QAction *act = qobject_cast<QAction *>(sender());
940 QTC_ASSERT(act, return);
941 breakHandler()->setEnabled(act->data().toInt(), false);
944 void updateWatchersHeader(int section, int, int newSize)
946 m_watchersWindow->header()->resizeSection(section, newSize);
949 void sourceFilesDockToggled(bool on)
951 if (on && m_currentEngine->state() == InferiorStopOk)
952 m_currentEngine->reloadSourceFiles();
955 void modulesDockToggled(bool on)
957 if (on && m_currentEngine->state() == InferiorStopOk)
958 m_currentEngine->reloadModules();
961 void registerDockToggled(bool on)
963 if (on && m_currentEngine->state() == InferiorStopOk)
964 m_currentEngine->reloadRegisters();
967 void synchronizeBreakpoints()
969 showMessage("ATTEMPT SYNC", LogDebug);
970 for (int i = 0, n = m_snapshotHandler->size(); i != n; ++i) {
971 if (DebuggerEngine *engine = m_snapshotHandler->at(i))
972 engine->attemptBreakpointSynchronization();
976 void synchronizeWatchers()
978 for (int i = 0, n = m_snapshotHandler->size(); i != n; ++i) {
979 if (DebuggerEngine *engine = m_snapshotHandler->at(i))
980 engine->watchHandler()->updateWatchers();
984 void editorOpened(Core::IEditor *editor);
985 void setBusyCursor(bool busy);
986 void requestMark(TextEditor::ITextEditor *editor, int lineNumber);
987 void showToolTip(TextEditor::ITextEditor *editor,
988 const QPoint &pnt, int pos, bool *handled);
989 void requestContextMenu(TextEditor::ITextEditor *editor,
990 int lineNumber, QMenu *menu);
992 void activatePreviousMode();
993 void activateDebugMode();
994 void toggleBreakpoint();
995 void toggleBreakpointByFileAndLine(const QString &fileName, int lineNumber);
996 void toggleBreakpointByAddress(quint64 address);
997 void onModeChanged(Core::IMode *mode);
998 void showSettingsDialog();
1000 void debugProject();
1001 void startExternalApplication();
1002 void startRemoteCdbSession();
1003 void startRemoteApplication();
1004 void startRemoteEngine();
1005 void attachExternalApplication();
1006 void attachExternalApplication
1007 (qint64 pid, const QString &binary, const QString &crashParameter);
1008 bool attachCmdLine();
1010 void attachCore(const QString &core, const QString &exeFileName);
1011 void attachRemote(const QString &spec);
1012 void attachRemoteTcf();
1014 void enableReverseDebuggingTriggered(const QVariant &value);
1015 void languagesChanged();
1016 void showStatusMessage(const QString &msg, int timeout = -1);
1017 void openMemoryEditor();
1019 const CPlusPlus::Snapshot &cppCodeModelSnapshot() const;
1021 void showQtDumperLibraryWarning(const QString &details);
1022 DebuggerMainWindow *mainWindow() const { return m_mainWindow; }
1023 bool isDockVisible(const QString &objectName) const
1024 { return mainWindow()->isDockVisible(objectName); }
1026 bool hasSnapshots() const { return m_snapshotHandler->size(); }
1027 void createNewDock(QWidget *widget);
1029 void runControlStarted(DebuggerEngine *engine);
1030 void runControlFinished(DebuggerEngine *engine);
1031 DebuggerLanguages activeLanguages() const;
1032 QString gdbBinaryForToolChain(int toolChain) const;
1033 void remoteCommand(const QStringList &options, const QStringList &);
1035 bool isReverseDebugging() const;
1037 BreakHandler *breakHandler() const { return m_breakHandler; }
1038 SnapshotHandler *snapshotHandler() const { return m_snapshotHandler; }
1040 void setConfigValue(const QString &name, const QVariant &value);
1041 QVariant configValue(const QString &name) const;
1043 DebuggerRunControl *createDebugger(const DebuggerStartParameters &sp,
1044 RunConfiguration *rc = 0);
1045 void startDebugger(RunControl *runControl);
1046 void displayDebugger(DebuggerEngine *engine, bool updateEngine = true);
1049 void cleanupViews();
1050 void setInitialState();
1052 void fontSettingsChanged(const TextEditor::FontSettings &settings);
1054 void updateState(DebuggerEngine *engine);
1055 void updateWatchersWindow();
1056 void onCurrentProjectChanged(ProjectExplorer::Project *project);
1058 void clearStatusMessage();
1060 void sessionLoaded();
1061 void aboutToUnloadSession();
1062 void aboutToSaveSession();
1064 void executeDebuggerCommand();
1065 void scriptExpressionEntered(const QString &expression);
1066 void coreShutdown();
1069 void updateDebugActions();
1071 void handleExecDetach()
1073 currentEngine()->resetLocation();
1074 currentEngine()->detachDebugger();
1077 void handleExecContinue()
1079 currentEngine()->resetLocation();
1080 currentEngine()->continueInferior();
1083 void handleExecInterrupt()
1085 currentEngine()->resetLocation();
1086 currentEngine()->requestInterruptInferior();
1089 void handleExecReset()
1091 currentEngine()->resetLocation();
1092 currentEngine()->notifyEngineIll(); // FIXME: Check.
1095 void handleExecStep()
1097 currentEngine()->resetLocation();
1098 if (boolSetting(OperateByInstruction))
1099 currentEngine()->executeStepI();
1101 currentEngine()->executeStep();
1104 void handleExecNext()
1106 currentEngine()->resetLocation();
1107 if (boolSetting(OperateByInstruction))
1108 currentEngine()->executeNextI();
1110 currentEngine()->executeNext();
1113 void handleExecStepOut()
1115 currentEngine()->resetLocation();
1116 currentEngine()->executeStepOut();
1119 void handleExecReturn()
1121 currentEngine()->resetLocation();
1122 currentEngine()->executeReturn();
1125 void handleExecJumpToLine()
1128 currentEngine()->resetLocation();
1131 if (currentTextEditorPosition(&fileName, &lineNumber))
1132 currentEngine()->executeJumpToLine(fileName, lineNumber);
1135 void handleExecRunToLine()
1138 currentEngine()->resetLocation();
1141 if (currentTextEditorPosition(&fileName, &lineNumber))
1142 currentEngine()->executeRunToLine(fileName, lineNumber);
1145 void handleExecRunToFunction()
1147 currentEngine()->resetLocation();
1148 ITextEditor *textEditor = currentTextEditor();
1149 QTC_ASSERT(textEditor, return);
1150 QPlainTextEdit *ed = qobject_cast<QPlainTextEdit*>(textEditor->widget());
1153 QTextCursor cursor = ed->textCursor();
1154 QString functionName = cursor.selectedText();
1155 if (functionName.isEmpty()) {
1156 const QTextBlock block = cursor.block();
1157 const QString line = block.text();
1158 foreach (const QString &str, line.trimmed().split('(')) {
1160 for (int i = str.size(); --i >= 0; ) {
1161 if (!str.at(i).isLetterOrNumber())
1172 if (!functionName.isEmpty())
1173 currentEngine()->executeRunToFunction(functionName);
1176 void slotEditBreakpoint()
1178 const QAction *act = qobject_cast<QAction *>(sender());
1179 QTC_ASSERT(act, return);
1180 const BreakpointId id = act->data().toInt();
1181 QTC_ASSERT(id > 0, return);
1182 BreakWindow::editBreakpoint(id, mainWindow());
1185 void slotRunToLine()
1187 const QAction *action = qobject_cast<const QAction *>(sender());
1188 QTC_ASSERT(action, return);
1189 const ContextData data = action->data().value<ContextData>();
1190 currentEngine()->executeRunToLine(data.fileName, data.lineNumber);
1193 void slotJumpToLine()
1195 const QAction *action = qobject_cast<const QAction *>(sender());
1196 QTC_ASSERT(action, return);
1197 const ContextData data = action->data().value<ContextData>();
1198 currentEngine()->executeJumpToLine(data.fileName, data.lineNumber);
1201 void handleAddToWatchWindow()
1203 // Requires a selection, but that's the only case we want anyway.
1204 EditorManager *editorManager = EditorManager::instance();
1207 IEditor *editor = editorManager->currentEditor();
1210 ITextEditor *textEditor = qobject_cast<ITextEditor*>(editor);
1214 QPlainTextEdit *ptEdit = qobject_cast<QPlainTextEdit*>(editor->widget());
1216 tc = ptEdit->textCursor();
1218 if (tc.hasSelection()) {
1219 exp = tc.selectedText();
1222 exp = cppExpressionAt(textEditor, tc.position(), &line, &column);
1226 currentEngine()->watchHandler()->watchExpression(exp);
1229 void handleExecExit()
1231 currentEngine()->exitDebugger();
1234 void handleFrameDown()
1236 currentEngine()->frameDown();
1239 void handleFrameUp()
1241 currentEngine()->frameUp();
1244 void handleOperateByInstructionTriggered(bool operateByInstructionTriggered)
1246 // Go to source only if we have the file.
1247 if (currentEngine()->stackHandler()->currentIndex() >= 0) {
1248 const StackFrame frame = currentEngine()->stackHandler()->currentFrame();
1249 if (operateByInstructionTriggered || frame.isUsable()) {
1250 currentEngine()->gotoLocation(Location(frame, true));
1255 bool isActiveDebugLanguage(int lang) const
1257 return m_mainWindow->activeDebugLanguages() & lang;
1260 QVariant sessionValue(const QString &name);
1261 void setSessionValue(const QString &name, const QVariant &value);
1262 QIcon locationMarkIcon() const { return m_locationMarkIcon; }
1264 void openTextEditor(const QString &titlePattern0, const QString &contents);
1265 void clearCppCodeModelSnapshot();
1266 void showMessage(const QString &msg, int channel, int timeout = -1);
1268 Utils::SavedAction *action(int code) const;
1269 bool boolSetting(int code) const;
1270 QString stringSetting(int code) const;
1272 void showModuleSymbols(const QString &moduleName, const Symbols &symbols);
1275 DebuggerMainWindow *m_mainWindow;
1276 DebuggerRunControlFactory *m_debuggerRunControlFactory;
1278 QString m_previousMode;
1279 Context m_continuableContext;
1280 Context m_interruptibleContext;
1281 Context m_undisturbableContext;
1282 Context m_finishedContext;
1283 Context m_anyContext;
1284 AttachRemoteParameters m_attachRemoteParameters;
1286 QAction *m_debugAction;
1287 QAction *m_startExternalAction;
1288 QAction *m_startRemoteAction;
1289 QAction *m_startRemoteCdbAction;
1290 QAction *m_startRemoteLldbAction;
1291 QAction *m_attachExternalAction;
1292 QAction *m_attachCoreAction;
1293 QAction *m_attachTcfAction;
1294 QAction *m_detachAction;
1295 QToolButton *m_reverseToolButton;
1299 QIcon m_continueIcon;
1300 QIcon m_interruptIcon;
1301 QIcon m_locationMarkIcon;
1303 QLabel *m_statusLabel;
1304 QComboBox *m_threadBox;
1306 DebuggerActions m_actions;
1308 BreakWindow *m_breakWindow;
1309 BreakHandler *m_breakHandler;
1310 //ConsoleWindow *m_consoleWindow;
1311 QTreeView *m_returnWindow;
1312 QTreeView *m_localsWindow;
1313 QTreeView *m_watchersWindow;
1314 QAbstractItemView *m_registerWindow;
1315 QAbstractItemView *m_modulesWindow;
1316 QAbstractItemView *m_snapshotWindow;
1317 SourceFilesWindow *m_sourceFilesWindow;
1318 QAbstractItemView *m_stackWindow;
1319 QAbstractItemView *m_threadsWindow;
1320 LogWindow *m_logWindow;
1321 ScriptConsole *m_scriptConsoleWindow;
1324 QTimer m_statusTimer;
1325 QString m_lastPermanentStatusMessage;
1327 mutable CPlusPlus::Snapshot m_codeModelSnapshot;
1328 DebuggerPlugin *m_plugin;
1330 SnapshotHandler *m_snapshotHandler;
1331 bool m_shuttingDown;
1332 DebuggerEngine *m_currentEngine;
1333 DebuggerSettings *m_debuggerSettings;
1334 QSettings *m_coreSettings;
1335 bool m_gdbBinariesChanged;
1336 uint m_cmdLineEnabledEngines;
1339 DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin)
1341 qRegisterMetaType<WatchData>("WatchData");
1342 qRegisterMetaType<ContextData>("ContextData");
1343 qRegisterMetaType<DebuggerStartParameters>("DebuggerStartParameters");
1345 QTC_ASSERT(!theDebuggerCore, /**/);
1346 theDebuggerCore = this;
1350 m_startRemoteCdbAction = 0;
1351 m_shuttingDown = false;
1359 m_watchersWindow = 0;
1360 m_registerWindow = 0;
1361 m_modulesWindow = 0;
1362 m_snapshotWindow = 0;
1363 m_sourceFilesWindow = 0;
1365 m_threadsWindow = 0;
1367 m_scriptConsoleWindow = 0;
1369 m_continuableContext = Context(0);
1370 m_interruptibleContext = Context(0);
1371 m_undisturbableContext = Context(0);
1372 m_finishedContext = Context(0);
1373 m_anyContext = Context(0);
1376 m_snapshotHandler = 0;
1377 m_currentEngine = 0;
1378 m_debuggerSettings = 0;
1380 m_gdbBinariesChanged = true;
1381 m_cmdLineEnabledEngines = AllEngineTypes;
1383 m_reverseToolButton = 0;
1385 m_startExternalAction = 0;
1386 m_startRemoteAction = 0;
1387 m_startRemoteCdbAction = 0;
1388 m_startRemoteLldbAction = 0;
1389 m_attachExternalAction = 0;
1390 m_attachCoreAction = 0;
1391 m_attachTcfAction = 0;
1395 DebuggerPluginPrivate::~DebuggerPluginPrivate()
1397 delete m_debuggerSettings;
1398 m_debuggerSettings = 0;
1400 delete m_mainWindow;
1403 delete m_snapshotHandler;
1404 m_snapshotHandler = 0;
1407 DebuggerCore *debuggerCore()
1409 return theDebuggerCore;
1412 bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
1413 QString *errorMessage)
1415 // Do not fail to load the whole plugin if something goes wrong here.
1416 if (!parseArguments(arguments, &m_attachRemoteParameters,
1417 &m_cmdLineEnabledEngines, errorMessage)) {
1418 *errorMessage = tr("Error evaluating command line arguments: %1")
1419 .arg(*errorMessage);
1420 qWarning("%s\n", qPrintable(*errorMessage));
1421 errorMessage->clear();
1425 m_mainWindow = new DebuggerMainWindow;
1430 void DebuggerPluginPrivate::setConfigValue(const QString &name, const QVariant &value)
1432 m_coreSettings->setValue(_("DebugMode/") + name, value);
1435 QVariant DebuggerPluginPrivate::configValue(const QString &name) const
1437 const QVariant value = m_coreSettings->value(_("DebugMode/") + name);
1438 if (value.isValid())
1440 // Legacy (pre-2.1): Check old un-namespaced-settings.
1441 return m_coreSettings->value(name);
1444 void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project)
1446 RunConfiguration *activeRc = 0;
1448 Target *target = project->activeTarget();
1449 QTC_ASSERT(target, return);
1450 activeRc = target->activeRunConfiguration();
1451 QTC_ASSERT(activeRc, /**/);
1453 for (int i = 0, n = m_snapshotHandler->size(); i != n; ++i) {
1454 // Run controls might be deleted during exit.
1455 if (DebuggerEngine *engine = m_snapshotHandler->at(i)) {
1456 DebuggerRunControl *runControl = engine->runControl();
1457 RunConfiguration *rc = runControl->runConfiguration();
1458 if (rc == activeRc) {
1459 m_snapshotHandler->setCurrentIndex(i);
1460 updateState(engine);
1465 // No corresponding debugger found. So we are ready to start one.
1466 ICore *core = ICore::instance();
1467 core->updateAdditionalContexts(m_anyContext, Context());
1470 void DebuggerPluginPrivate::languagesChanged()
1472 const bool debuggerIsCPP =
1473 m_mainWindow->activeDebugLanguages() & CppLanguage;
1474 //qDebug() << "DEBUGGER IS CPP: " << debuggerIsCPP;
1475 m_startExternalAction->setVisible(debuggerIsCPP);
1476 m_attachExternalAction->setVisible(debuggerIsCPP);
1477 m_attachCoreAction->setVisible(debuggerIsCPP);
1478 m_startRemoteAction->setVisible(debuggerIsCPP);
1479 m_detachAction->setVisible(debuggerIsCPP);
1482 void DebuggerPluginPrivate::debugProject()
1484 ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
1485 if (Project *pro = pe->startupProject())
1486 pe->runProject(pro, Constants::DEBUGMODE);
1489 void DebuggerPluginPrivate::startExternalApplication()
1491 DebuggerStartParameters sp;
1492 StartExternalDialog dlg(mainWindow());
1493 dlg.setExecutableFile(
1494 configValue(_("LastExternalExecutableFile")).toString());
1495 dlg.setExecutableArguments(
1496 configValue(_("LastExternalExecutableArguments")).toString());
1497 dlg.setWorkingDirectory(
1498 configValue(_("LastExternalWorkingDirectory")).toString());
1499 if (dlg.exec() != QDialog::Accepted)
1502 setConfigValue(_("LastExternalExecutableFile"),
1503 dlg.executableFile());
1504 setConfigValue(_("LastExternalExecutableArguments"),
1505 dlg.executableArguments());
1506 setConfigValue(_("LastExternalWorkingDirectory"),
1507 dlg.workingDirectory());
1508 sp.executable = dlg.executableFile();
1509 sp.startMode = StartExternal;
1510 sp.workingDirectory = dlg.workingDirectory();
1511 if (!dlg.executableArguments().isEmpty())
1512 sp.processArgs = dlg.executableArguments();
1513 // Fixme: 1 of 3 testing hacks.
1514 if (sp.processArgs.startsWith(__("@tcf@ ")) || sp.processArgs.startsWith(__("@sym@ ")))
1515 sp.toolChainType = ToolChain_RVCT2_ARMV5;
1517 if (dlg.breakAtMain()) {
1519 // FIXME: wrong on non-Qt based binaries
1520 breakHandler()->breakByFunction("qMain");
1522 breakHandler()->breakByFunction("main");
1526 if (RunControl *rc = m_debuggerRunControlFactory->create(sp))
1530 void DebuggerPluginPrivate::attachExternalApplication()
1532 AttachExternalDialog dlg(mainWindow());
1533 if (dlg.exec() == QDialog::Accepted)
1534 attachExternalApplication(dlg.attachPID(), dlg.executable(), QString());
1537 void DebuggerPluginPrivate::attachExternalApplication
1538 (qint64 pid, const QString &binary, const QString &crashParameter)
1541 QMessageBox::warning(mainWindow(), tr("Warning"),
1542 tr("Cannot attach to PID 0"));
1545 DebuggerStartParameters sp;
1547 sp.displayName = tr("Process %1").arg(pid);
1548 sp.executable = binary;
1549 sp.crashParameter = crashParameter;
1550 sp.startMode = crashParameter.isEmpty() ? AttachExternal : AttachCrashedExternal;
1551 if (DebuggerRunControl *rc = createDebugger(sp))
1555 void DebuggerPluginPrivate::attachCore()
1557 AttachCoreDialog dlg(mainWindow());
1558 dlg.setExecutableFile(configValue(_("LastExternalExecutableFile")).toString());
1559 dlg.setCoreFile(configValue(_("LastExternalCoreFile")).toString());
1560 if (dlg.exec() != QDialog::Accepted)
1562 setConfigValue(_("LastExternalExecutableFile"), dlg.executableFile());
1563 setConfigValue(_("LastExternalCoreFile"), dlg.coreFile());
1564 attachCore(dlg.coreFile(), dlg.executableFile());
1567 void DebuggerPluginPrivate::attachCore(const QString &core, const QString &exe)
1569 DebuggerStartParameters sp;
1570 sp.executable = exe;
1572 sp.displayName = tr("Core file \"%1\"").arg(core);
1573 sp.startMode = AttachCore;
1574 if (DebuggerRunControl *rc = createDebugger(sp))
1578 void DebuggerPluginPrivate::attachRemote(const QString &spec)
1580 // spec is: executable@server:port@architecture
1581 DebuggerStartParameters sp;
1582 sp.executable = spec.section('@', 0, 0);
1583 sp.remoteChannel = spec.section('@', 1, 1);
1584 sp.remoteArchitecture = spec.section('@', 2, 2);
1585 sp.displayName = tr("Remote: \"%1\"").arg(sp.remoteChannel);
1586 sp.startMode = AttachToRemote;
1587 if (DebuggerRunControl *rc = createDebugger(sp))
1591 void DebuggerPluginPrivate::startRemoteCdbSession()
1593 const QString connectionKey = _("CdbRemoteConnection");
1594 DebuggerStartParameters sp;
1595 sp.toolChainType = ToolChain_MSVC;
1596 sp.startMode = AttachToRemote;
1597 StartRemoteCdbDialog dlg(mainWindow());
1598 QString previousConnection = configValue(connectionKey).toString();
1599 if (previousConnection.isEmpty())
1600 previousConnection = QLatin1String("localhost:1234");
1601 dlg.setConnection(previousConnection);
1602 if (dlg.exec() != QDialog::Accepted)
1604 sp.remoteChannel = dlg.connection();
1605 setConfigValue(connectionKey, sp.remoteChannel);
1606 if (RunControl *rc = createDebugger(sp))
1610 void DebuggerPluginPrivate::startRemoteApplication()
1612 DebuggerStartParameters sp;
1613 StartRemoteDialog dlg(mainWindow());
1615 arches.append(_("i386:x86-64:intel"));
1616 arches.append(_("i386"));
1617 arches.append(_("arm"));
1618 QString lastUsed = configValue(_("LastRemoteArchitecture")).toString();
1619 if (!arches.contains(lastUsed))
1620 arches.prepend(lastUsed);
1621 dlg.setRemoteArchitectures(arches);
1622 QStringList gnuTargets;
1623 gnuTargets.append(_("auto"));
1624 gnuTargets.append(_("i686-linux-gnu"));
1625 gnuTargets.append(_("x86_64-linux-gnu"));
1626 gnuTargets.append(_("arm-none-linux-gnueabi"));
1627 const QString lastUsedGnuTarget
1628 = configValue(_("LastGnuTarget")).toString();
1629 if (!gnuTargets.contains(lastUsedGnuTarget))
1630 gnuTargets.prepend(lastUsedGnuTarget);
1631 dlg.setGnuTargets(gnuTargets);
1632 dlg.setRemoteChannel(
1633 configValue(_("LastRemoteChannel")).toString());
1634 dlg.setLocalExecutable(
1635 configValue(_("LastLocalExecutable")).toString());
1636 dlg.setDebugger(configValue(_("LastDebugger")).toString());
1637 dlg.setRemoteArchitecture(lastUsed);
1638 dlg.setGnuTarget(lastUsedGnuTarget);
1639 dlg.setServerStartScript(
1640 configValue(_("LastServerStartScript")).toString());
1641 dlg.setUseServerStartScript(
1642 configValue(_("LastUseServerStartScript")).toBool());
1643 dlg.setSysRoot(configValue(_("LastSysroot")).toString());
1644 if (dlg.exec() != QDialog::Accepted)
1646 setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel());
1647 setConfigValue(_("LastLocalExecutable"), dlg.localExecutable());
1648 setConfigValue(_("LastDebugger"), dlg.debugger());
1649 setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture());
1650 setConfigValue(_("LastGnuTarget"), dlg.gnuTarget());
1651 setConfigValue(_("LastServerStartScript"), dlg.serverStartScript());
1652 setConfigValue(_("LastUseServerStartScript"), dlg.useServerStartScript());
1653 setConfigValue(_("LastSysroot"), dlg.sysRoot());
1654 sp.remoteChannel = dlg.remoteChannel();
1655 sp.remoteArchitecture = dlg.remoteArchitecture();
1656 sp.gnuTarget = dlg.gnuTarget();
1657 sp.executable = dlg.localExecutable();
1658 sp.displayName = dlg.localExecutable();
1659 sp.debuggerCommand = dlg.debugger(); // Override toolchain-detection.
1660 if (!sp.debuggerCommand.isEmpty())
1661 sp.toolChainType = ToolChain_INVALID;
1662 sp.startMode = AttachToRemote;
1663 sp.useServerStartScript = dlg.useServerStartScript();
1664 sp.serverStartScript = dlg.serverStartScript();
1665 sp.sysRoot = dlg.sysRoot();
1666 if (RunControl *rc = createDebugger(sp))
1670 void DebuggerPluginPrivate::startRemoteEngine()
1672 DebuggerStartParameters sp;
1673 StartRemoteEngineDialog dlg(mainWindow());
1674 if (dlg.exec() != QDialog::Accepted)
1677 sp.connParams.host = dlg.host();
1678 sp.connParams.uname = dlg.username();
1679 sp.connParams.pwd = dlg.password();
1681 sp.connParams.timeout = 5;
1682 sp.connParams.authType = SshConnectionParameters::AuthByPwd;
1683 sp.connParams.port = 22;
1684 sp.connParams.proxyType = SshConnectionParameters::NoProxy;
1686 sp.executable = dlg.inferiorPath();
1687 sp.serverStartScript = dlg.enginePath();
1688 sp.startMode = StartRemoteEngine;
1689 if (RunControl *rc = createDebugger(sp))
1693 void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &value)
1695 QTC_ASSERT(m_reverseToolButton, return);
1696 m_reverseToolButton->setVisible(value.toBool());
1697 m_actions.reverseDirectionAction->setChecked(false);
1698 m_actions.reverseDirectionAction->setEnabled(value.toBool());
1701 void DebuggerPluginPrivate::attachRemoteTcf()
1703 DebuggerStartParameters sp;
1704 AttachTcfDialog dlg(mainWindow());
1706 arches.append(_("i386:x86-64:intel"));
1707 dlg.setRemoteArchitectures(arches);
1708 dlg.setRemoteChannel(
1709 configValue(_("LastTcfRemoteChannel")).toString());
1710 dlg.setRemoteArchitecture(
1711 configValue(_("LastTcfRemoteArchitecture")).toString());
1712 dlg.setServerStartScript(
1713 configValue(_("LastTcfServerStartScript")).toString());
1714 dlg.setUseServerStartScript(
1715 configValue(_("LastTcfUseServerStartScript")).toBool());
1716 if (dlg.exec() != QDialog::Accepted)
1718 setConfigValue(_("LastTcfRemoteChannel"), dlg.remoteChannel());
1719 setConfigValue(_("LastTcfRemoteArchitecture"), dlg.remoteArchitecture());
1720 setConfigValue(_("LastTcfServerStartScript"), dlg.serverStartScript());
1721 setConfigValue(_("LastTcfUseServerStartScript"), dlg.useServerStartScript());
1722 sp.remoteChannel = dlg.remoteChannel();
1723 sp.remoteArchitecture = dlg.remoteArchitecture();
1724 sp.serverStartScript = dlg.serverStartScript();
1725 sp.startMode = AttachTcf;
1726 if (dlg.useServerStartScript())
1727 sp.serverStartScript = dlg.serverStartScript();
1728 if (RunControl *rc = createDebugger(sp))
1732 bool DebuggerPluginPrivate::attachCmdLine()
1734 if (m_attachRemoteParameters.attachPid) {
1735 showStatusMessage(tr("Attaching to PID %1.")
1736 .arg(m_attachRemoteParameters.attachPid));
1737 const QString crashParameter = m_attachRemoteParameters.winCrashEvent
1738 ? QString::number(m_attachRemoteParameters.winCrashEvent) : QString();
1739 attachExternalApplication(m_attachRemoteParameters.attachPid,
1740 QString(), crashParameter);
1743 const QString target = m_attachRemoteParameters.attachTarget;
1744 if (target.isEmpty())
1746 if (target.indexOf(':') > 0) {
1747 showStatusMessage(tr("Attaching to remote server %1.").arg(target));
1748 attachRemote(target);
1750 showStatusMessage(tr("Attaching to core %1.").arg(target));
1751 attachCore(target, QString());
1756 void DebuggerPluginPrivate::editorOpened(IEditor *editor)
1758 if (!isDebuggable(editor))
1760 ITextEditor *textEditor = qobject_cast<ITextEditor *>(editor);
1764 SIGNAL(markRequested(TextEditor::ITextEditor*,int)),
1765 SLOT(requestMark(TextEditor::ITextEditor*,int)));
1767 SIGNAL(tooltipOverrideRequested(TextEditor::ITextEditor*,QPoint,int,bool*)),
1768 SLOT(showToolTip(TextEditor::ITextEditor*,QPoint,int,bool*)));
1770 SIGNAL(markContextMenuRequested(TextEditor::ITextEditor*,int,QMenu*)),
1771 SLOT(requestContextMenu(TextEditor::ITextEditor*,int,QMenu*)));
1774 void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor,
1775 int lineNumber, QMenu *menu)
1777 if (!isDebuggable(editor))
1780 BreakpointId id = BreakpointId();
1782 quint64 address = 0;
1785 args.lineNumber = lineNumber;
1787 if (editor->property("DisassemblerView").toBool()) {
1788 args.fileName = editor->file()->fileName();
1789 QString line = editor->contents()
1790 .section('\n', lineNumber - 1, lineNumber - 1);
1791 BreakpointResponse needle;
1792 needle.type = BreakpointByAddress;
1793 needle.address = DisassemblerAgent::addressFromDisassemblyLine(line);
1794 args.address = needle.address;
1795 needle.lineNumber = -1;
1796 id = breakHandler()->findSimilarBreakpoint(needle);
1798 args.fileName = editor->file()->fileName();
1799 id = breakHandler()->findBreakpointByFileAndLine(fileName, lineNumber);
1803 // Remove existing breakpoint.
1804 QAction *act = new QAction(menu);
1805 act->setData(int(id));
1806 act->setText(tr("Remove Breakpoint %1").arg(id));
1807 connect(act, SIGNAL(triggered()),
1808 SLOT(breakpointRemoveMarginActionTriggered()));
1809 menu->addAction(act);
1811 // Enable/disable existing breakpoint.
1812 act = new QAction(menu);
1813 act->setData(int(id));
1814 if (breakHandler()->isEnabled(id)) {
1815 act->setText(tr("Disable Breakpoint %1").arg(id));
1816 connect(act, SIGNAL(triggered()),
1817 SLOT(breakpointDisableMarginActionTriggered()));
1819 act->setText(tr("Enable Breakpoint %1").arg(id));
1820 connect(act, SIGNAL(triggered()),
1821 SLOT(breakpointEnableMarginActionTriggered()));
1823 menu->addAction(act);
1825 // Edit existing breakpoint.
1826 act = new QAction(menu);
1827 act->setText(tr("Edit Breakpoint %1...").arg(id));
1828 connect(act, SIGNAL(triggered()), SLOT(slotEditBreakpoint()));
1829 act->setData(int(id));
1830 menu->addAction(act);
1832 // Handle non-existing breakpoint.
1833 const QString text = address ?
1834 tr("Set Breakpoint at 0x%1").arg(address, 0, 16) :
1835 tr("Set Breakpoint at line %1").arg(lineNumber);
1836 QAction *act = new QAction(text, menu);
1837 act->setData(QVariant::fromValue(args));
1838 connect(act, SIGNAL(triggered()),
1839 SLOT(breakpointSetMarginActionTriggered()));
1840 menu->addAction(act);
1842 // Run to, jump to line below in stopped state.
1843 if (currentEngine()->state() == InferiorStopOk) {
1844 menu->addSeparator();
1845 const QString runText =
1846 DebuggerEngine::tr("Run to Line %1").arg(lineNumber);
1847 QAction *runToLineAction = new QAction(runText, menu);
1848 runToLineAction->setData(QVariant::fromValue(args));
1849 connect(runToLineAction, SIGNAL(triggered()), SLOT(slotRunToLine()));
1850 menu->addAction(runToLineAction);
1851 if (currentEngine()->debuggerCapabilities() & JumpToLineCapability) {
1852 const QString jumpText =
1853 DebuggerEngine::tr("Jump to Line %1").arg(lineNumber);
1854 QAction *jumpToLineAction = new QAction(jumpText, menu);
1855 menu->addAction(runToLineAction);
1856 jumpToLineAction->setData(QVariant::fromValue(args));
1857 connect(jumpToLineAction, SIGNAL(triggered()), SLOT(slotJumpToLine()));
1858 menu->addAction(jumpToLineAction);
1863 void DebuggerPluginPrivate::toggleBreakpoint()
1865 ITextEditor *textEditor = currentTextEditor();
1866 QTC_ASSERT(textEditor, return);
1867 const int lineNumber = textEditor->currentLine();
1868 if (textEditor->property("DisassemblerView").toBool()) {
1869 QString line = textEditor->contents()
1870 .section('\n', lineNumber - 1, lineNumber - 1);
1871 quint64 address = DisassemblerAgent::addressFromDisassemblyLine(line);
1872 toggleBreakpointByAddress(address);
1873 } else if (lineNumber >= 0) {
1874 toggleBreakpointByFileAndLine(textEditor->file()->fileName(), lineNumber);
1878 void DebuggerPluginPrivate::toggleBreakpointByFileAndLine(const QString &fileName,
1881 BreakHandler *handler = m_breakHandler;
1883 handler->findBreakpointByFileAndLine(fileName, lineNumber, true);
1885 id = handler->findBreakpointByFileAndLine(fileName, lineNumber, false);
1888 handler->removeBreakpoint(id);
1890 BreakpointParameters data(BreakpointByFileAndLine);
1891 data.fileName = fileName;
1892 data.lineNumber = lineNumber;
1893 handler->appendBreakpoint(data);
1895 synchronizeBreakpoints();
1898 void DebuggerPluginPrivate::toggleBreakpointByAddress(quint64 address)
1900 BreakHandler *handler = m_breakHandler;
1901 BreakpointId id = handler->findBreakpointByAddress(address);
1904 handler->removeBreakpoint(id);
1906 BreakpointParameters data(BreakpointByAddress);
1907 data.address = address;
1908 handler->appendBreakpoint(data);
1910 synchronizeBreakpoints();
1913 void DebuggerPluginPrivate::requestMark(ITextEditor *editor, int lineNumber)
1915 if (editor->property("DisassemblerView").toBool()) {
1916 QString line = editor->contents()
1917 .section('\n', lineNumber - 1, lineNumber - 1);
1918 quint64 address = DisassemblerAgent::addressFromDisassemblyLine(line);
1919 toggleBreakpointByAddress(address);
1920 } else if (editor->file()) {
1921 toggleBreakpointByFileAndLine(editor->file()->fileName(), lineNumber);
1925 void DebuggerPluginPrivate::showToolTip(ITextEditor *editor,
1926 const QPoint &point, int pos, bool *handled)
1928 if (!isDebuggable(editor))
1930 if (!boolSetting(UseToolTipsInMainEditor))
1932 if (!currentEngine())
1934 if (currentEngine()->state() != InferiorStopOk)
1936 QTC_ASSERT(handled, return);
1938 currentEngine()->setToolTipExpression(point, editor, pos);
1941 DebuggerRunControl *DebuggerPluginPrivate::createDebugger
1942 (const DebuggerStartParameters &sp, RunConfiguration *rc)
1944 return m_debuggerRunControlFactory->create(sp, rc);
1947 // If updateEngine is set, the engine will update its threads/modules and so forth.
1948 void DebuggerPluginPrivate::displayDebugger(DebuggerEngine *engine, bool updateEngine)
1950 QTC_ASSERT(engine, return);
1952 connectEngine(engine);
1954 engine->updateAll();
1955 engine->updateViews();
1958 void DebuggerPluginPrivate::startDebugger(RunControl *rc)
1960 QTC_ASSERT(rc, return);
1961 ProjectExplorerPlugin::instance()->startRunControl(rc, Constants::DEBUGMODE);
1965 void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine)
1968 engine = dummyEngine();
1970 if (m_currentEngine == engine)
1973 if (m_currentEngine)
1974 m_currentEngine->resetLocation();
1975 m_currentEngine = engine;
1977 m_localsWindow->setModel(engine->localsModel());
1978 m_modulesWindow->setModel(engine->modulesModel());
1979 m_registerWindow->setModel(engine->registerModel());
1980 m_returnWindow->setModel(engine->returnModel());
1981 m_sourceFilesWindow->setModel(engine->sourceFilesModel());
1982 m_stackWindow->setModel(engine->stackModel());
1983 m_threadsWindow->setModel(engine->threadsModel());
1984 m_threadBox->setModel(engine->threadsModel());
1985 m_threadBox->setModelColumn(ThreadData::NameColumn);
1986 m_watchersWindow->setModel(engine->watchersModel());
1989 static void changeFontSize(QWidget *widget, qreal size)
1991 QFont font = widget->font();
1992 font.setPointSizeF(size);
1993 widget->setFont(font);
1996 void DebuggerPluginPrivate::fontSettingsChanged
1997 (const TextEditor::FontSettings &settings)
1999 qreal size = settings.fontZoom() * settings.fontSize() / 100.;
2000 changeFontSize(m_breakWindow, size);
2001 changeFontSize(m_logWindow, size);
2002 changeFontSize(m_localsWindow, size);
2003 changeFontSize(m_modulesWindow, size);
2004 //changeFontSize(m_consoleWindow, size);
2005 changeFontSize(m_registerWindow, size);
2006 changeFontSize(m_returnWindow, size);
2007 changeFontSize(m_sourceFilesWindow, size);
2008 changeFontSize(m_stackWindow, size);
2009 changeFontSize(m_threadsWindow, size);
2010 changeFontSize(m_watchersWindow, size);
2013 void DebuggerPluginPrivate::cleanupViews()
2015 m_actions.reverseDirectionAction->setChecked(false);
2016 m_actions.reverseDirectionAction->setEnabled(false);
2017 hideDebuggerToolTip();
2019 if (!boolSetting(CloseBuffersOnExit))
2022 EditorManager *editorManager = EditorManager::instance();
2023 QTC_ASSERT(editorManager, return);
2024 QList<IEditor *> toClose;
2025 foreach (IEditor *editor, editorManager->openedEditors()) {
2026 if (editor->property(Constants::OPENED_BY_DEBUGGER).toBool()) {
2027 // Close disassembly views. Close other opened files
2028 // if they are not modified and not current editor.
2029 if (editor->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()
2030 || (!editor->file()->isModified()
2031 && editor != editorManager->currentEditor())) {
2032 toClose.append(editor);
2034 editor->setProperty(Constants::OPENED_BY_DEBUGGER, false);
2038 editorManager->closeEditors(toClose);
2041 void DebuggerPluginPrivate::setBusyCursor(bool busy)
2043 //STATE_DEBUG("BUSY FROM: " << m_busy << " TO: " << busy);
2047 QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor);
2048 m_breakWindow->setCursor(cursor);
2049 //m_consoleWindow->setCursor(cursor);
2050 m_localsWindow->setCursor(cursor);
2051 m_modulesWindow->setCursor(cursor);
2052 m_logWindow->setCursor(cursor);
2053 m_registerWindow->setCursor(cursor);
2054 m_returnWindow->setCursor(cursor);
2055 m_sourceFilesWindow->setCursor(cursor);
2056 m_stackWindow->setCursor(cursor);
2057 m_threadsWindow->setCursor(cursor);
2058 m_watchersWindow->setCursor(cursor);
2059 m_snapshotWindow->setCursor(cursor);
2060 m_scriptConsoleWindow->setCursor(cursor);
2063 void DebuggerPluginPrivate::setInitialState()
2065 m_watchersWindow->setVisible(false);
2066 m_returnWindow->setVisible(false);
2067 setBusyCursor(false);
2068 m_actions.reverseDirectionAction->setChecked(false);
2069 m_actions.reverseDirectionAction->setEnabled(false);
2070 hideDebuggerToolTip();
2072 m_startExternalAction->setEnabled(true);
2073 m_attachExternalAction->setEnabled(true);
2075 m_attachCoreAction->setEnabled(false);
2077 m_attachCoreAction->setEnabled(true);
2079 m_startRemoteAction->setEnabled(true);
2080 m_detachAction->setEnabled(false);
2082 m_actions.watchAction1->setEnabled(true);
2083 m_actions.watchAction2->setEnabled(true);
2084 m_actions.breakAction->setEnabled(true);
2085 //m_actions.snapshotAction->setEnabled(false);
2086 action(OperateByInstruction)->setEnabled(false);
2088 m_actions.exitAction->setEnabled(false);
2089 m_actions.resetAction->setEnabled(false);
2091 m_actions.stepAction->setEnabled(false);
2092 m_actions.stepOutAction->setEnabled(false);
2093 m_actions.runToLineAction->setEnabled(false);
2094 m_actions.runToFunctionAction->setEnabled(false);
2095 m_actions.returnFromFunctionAction->setEnabled(false);
2096 m_actions.jumpToLineAction->setEnabled(false);
2097 m_actions.nextAction->setEnabled(false);
2099 action(AutoDerefPointers)->setEnabled(true);
2100 action(ExpandStack)->setEnabled(false);
2101 action(ExecuteCommand)->setEnabled(false);
2103 m_scriptConsoleWindow->setEnabled(false);
2106 void DebuggerPluginPrivate::updateWatchersWindow()
2108 m_watchersWindow->setVisible(
2109 m_watchersWindow->model()->rowCount(QModelIndex()) > 0);
2110 m_returnWindow->setVisible(
2111 m_returnWindow->model()->rowCount(QModelIndex()) > 0);
2114 void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
2116 QTC_ASSERT(engine, return);
2117 QTC_ASSERT(m_watchersWindow->model(), return);
2118 QTC_ASSERT(m_returnWindow->model(), return);
2119 QTC_ASSERT(!engine->isSlaveEngine(), return);
2121 m_threadBox->setCurrentIndex(engine->threadsHandler()->currentThread());
2123 updateWatchersWindow();
2125 const DebuggerState state = engine->state();
2126 //showMessage(QString("PLUGIN SET STATE: ")
2127 // + DebuggerEngine::stateName(state), LogStatus);
2128 //qDebug() << "PLUGIN SET STATE: " << state;
2130 static DebuggerState previousState = DebuggerNotReady;
2131 if (state == previousState)
2134 bool actionsEnabled = DebuggerEngine::debuggerActionsEnabled(state);
2136 ICore *core = ICore::instance();
2137 ActionManager *am = core->actionManager();
2138 if (state == DebuggerNotReady) {
2139 QTC_ASSERT(false, /* We use the Core m_debugAction here */);
2140 // F5 starts debugging. It is "startable".
2141 m_actions.interruptAction->setEnabled(false);
2142 m_actions.continueAction->setEnabled(false);
2143 m_actions.exitAction->setEnabled(false);
2144 am->command(Constants::STOP)->setKeySequence(QKeySequence());
2145 am->command(Constants::DEBUG)->setKeySequence(QKeySequence(DEBUG_KEY));
2146 core->updateAdditionalContexts(m_anyContext, Context());
2147 } else if (state == InferiorStopOk) {
2148 // F5 continues, Shift-F5 kills. It is "continuable".
2149 m_actions.interruptAction->setEnabled(false);
2150 m_actions.continueAction->setEnabled(true);
2151 m_actions.exitAction->setEnabled(true);
2152 am->command(Constants::STOP)->setKeySequence(QKeySequence(STOP_KEY));
2153 am->command(Constants::DEBUG)->setKeySequence(QKeySequence(DEBUG_KEY));
2154 core->updateAdditionalContexts(m_anyContext, m_continuableContext);
2155 } else if (state == InferiorRunOk) {
2156 // Shift-F5 interrupts. It is also "interruptible".
2157 m_actions.interruptAction->setEnabled(true);
2158 m_actions.continueAction->setEnabled(false);
2159 m_actions.exitAction->setEnabled(false);
2160 am->command(Constants::STOP)->setKeySequence(QKeySequence());
2161 am->command(Constants::DEBUG)->setKeySequence(QKeySequence(STOP_KEY));
2162 core->updateAdditionalContexts(m_anyContext, m_interruptibleContext);
2163 } else if (state == DebuggerFinished) {
2164 // We don't want to do anything anymore.
2165 m_actions.interruptAction->setEnabled(false);
2166 m_actions.continueAction->setEnabled(false);
2167 m_actions.exitAction->setEnabled(false);
2168 am->command(Constants::STOP)->setKeySequence(QKeySequence());
2169 am->command(Constants::DEBUG)->setKeySequence(QKeySequence(DEBUG_KEY));
2170 //core->updateAdditionalContexts(m_anyContext, m_finishedContext);
2171 m_codeModelSnapshot = CPlusPlus::Snapshot();
2172 core->updateAdditionalContexts(m_anyContext, Context());
2173 setBusyCursor(false);
2175 } else if (state == InferiorUnrunnable) {
2176 // We don't want to do anything anymore.
2177 m_actions.interruptAction->setEnabled(false);
2178 m_actions.continueAction->setEnabled(false);
2179 m_actions.exitAction->setEnabled(true);
2180 am->command(Constants::STOP)->setKeySequence(QKeySequence(STOP_KEY));
2181 am->command(Constants::DEBUG)->setKeySequence(QKeySequence(STOP_KEY));
2182 core->updateAdditionalContexts(m_anyContext, m_finishedContext);
2184 // Everything else is "undisturbable".
2185 m_actions.interruptAction->setEnabled(false);
2186 m_actions.continueAction->setEnabled(false);
2187 m_actions.exitAction->setEnabled(false);
2188 am->command(Constants::STOP)->setKeySequence(QKeySequence());
2189 am->command(Constants::DEBUG)->setKeySequence(QKeySequence());
2190 core->updateAdditionalContexts(m_anyContext, m_undisturbableContext);
2193 m_startExternalAction->setEnabled(true);
2194 m_attachExternalAction->setEnabled(true);
2196 m_attachCoreAction->setEnabled(false);
2198 m_attachCoreAction->setEnabled(true);
2200 m_startRemoteAction->setEnabled(true);
2202 const bool isCore = engine->startParameters().startMode == AttachCore;
2203 const bool stopped = state == InferiorStopOk;
2204 const bool detachable = stopped && !isCore;
2205 m_detachAction->setEnabled(detachable);
2208 QApplication::alert(mainWindow(), 3000);
2210 const uint caps = engine->debuggerCapabilities();
2211 const bool canReverse = (caps & ReverseSteppingCapability)
2212 && boolSetting(EnableReverseDebugging);
2213 m_actions.reverseDirectionAction->setEnabled(canReverse);
2215 m_actions.watchAction1->setEnabled(true);
2216 m_actions.watchAction2->setEnabled(true);
2217 m_actions.breakAction->setEnabled(true);
2218 //m_actions.snapshotAction->setEnabled(stopped && (caps & SnapshotCapability));
2220 action(OperateByInstruction)->setEnabled(stopped || isCore);
2222 m_actions.resetAction->setEnabled(state != DebuggerNotReady
2223 && state != DebuggerFinished);
2225 m_actions.stepAction->setEnabled(stopped);
2226 m_actions.stepOutAction->setEnabled(stopped);
2227 m_actions.runToLineAction->setEnabled(stopped);
2228 m_actions.runToFunctionAction->setEnabled(stopped);
2229 m_actions.returnFromFunctionAction->
2230 setEnabled(stopped && (caps & ReturnFromFunctionCapability));
2232 const bool canJump = stopped && (caps & JumpToLineCapability);
2233 m_actions.jumpToLineAction->setEnabled(canJump);
2235 m_actions.nextAction->setEnabled(stopped);
2237 const bool canDeref = actionsEnabled && (caps & AutoDerefPointersCapability);
2238 action(AutoDerefPointers)->setEnabled(canDeref);
2239 action(AutoDerefPointers)->setEnabled(true);
2240 action(ExpandStack)->setEnabled(actionsEnabled);
2241 action(ExecuteCommand)->setEnabled(state == InferiorStopOk);
2243 const bool notbusy = state == InferiorStopOk
2244 || state == DebuggerNotReady
2245 || state == DebuggerFinished
2246 || state == InferiorUnrunnable;
2247 setBusyCursor(!notbusy);
2249 m_scriptConsoleWindow->setEnabled(stopped);
2252 void DebuggerPluginPrivate::updateDebugActions()
2254 ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
2255 Project *project = pe->startupProject();
2256 m_debugAction->setEnabled(pe->canRun(project, Constants::DEBUGMODE));
2259 void DebuggerPluginPrivate::onModeChanged(IMode *mode)
2261 // FIXME: This one gets always called, even if switching between modes
2262 // different then the debugger mode. E.g. Welcome and Help mode and
2263 // also on shutdown.
2265 m_mainWindow->onModeChanged(mode);
2267 if (mode->id() != Constants::MODE_DEBUG)
2270 EditorManager *editorManager = EditorManager::instance();
2271 if (editorManager->currentEditor())
2272 editorManager->currentEditor()->widget()->setFocus();
2275 void DebuggerPluginPrivate::showSettingsDialog()
2277 ICore::instance()->showOptionsDialog(
2278 _(DEBUGGER_SETTINGS_CATEGORY),
2279 _(DEBUGGER_COMMON_SETTINGS_ID));
2282 void DebuggerPluginPrivate::dumpLog()
2284 QString fileName = QFileDialog::getSaveFileName(mainWindow(),
2285 tr("Save Debugger Log"), QDir::tempPath());
2286 if (fileName.isEmpty())
2288 QFile file(fileName);
2289 if (!file.open(QIODevice::WriteOnly))
2291 QTextStream ts(&file);
2292 ts << m_logWindow->inputContents();
2293 ts << "\n\n=======================================\n\n";
2294 ts << m_logWindow->combinedContents();
2297 void DebuggerPluginPrivate::clearStatusMessage()
2299 m_statusLabel->setText(m_lastPermanentStatusMessage);
2302 /*! Activates the previous mode when the current mode is the debug mode. */
2303 void DebuggerPluginPrivate::activatePreviousMode()
2305 ModeManager *modeManager = ICore::instance()->modeManager();
2307 if (modeManager->currentMode() == modeManager->mode(MODE_DEBUG)
2308 && !m_previousMode.isEmpty()) {
2309 modeManager->activateMode(m_previousMode);
2310 m_previousMode.clear();
2314 void DebuggerPluginPrivate::activateDebugMode()
2316 m_actions.reverseDirectionAction->setChecked(false);
2317 m_actions.reverseDirectionAction->setEnabled(false);
2318 ModeManager *modeManager = ModeManager::instance();
2319 m_previousMode = modeManager->currentMode()->id();
2320 modeManager->activateMode(_(MODE_DEBUG));
2323 void DebuggerPluginPrivate::sessionLoaded()
2325 m_breakHandler->loadSessionData();
2326 dummyEngine()->watchHandler()->loadSessionData();
2329 void DebuggerPluginPrivate::aboutToUnloadSession()
2331 m_breakHandler->removeSessionData();
2332 // Stop debugging the active project when switching sessions.
2333 // Note that at startup, session switches may occur, which interfere
2334 // with command-line debugging startup.
2335 // FIXME ABC: Still wanted? Iterate?
2336 //if (d->m_engine && state() != DebuggerNotReady
2337 // && engine()->sp().startMode == StartInternal)
2338 // d->m_engine->shutdown();
2341 void DebuggerPluginPrivate::aboutToSaveSession()
2343 dummyEngine()->watchHandler()->loadSessionData();
2344 m_breakHandler->saveSessionData();
2347 void DebuggerPluginPrivate::executeDebuggerCommand()
2349 if (QAction *action = qobject_cast<QAction *>(sender()))
2350 currentEngine()->executeDebuggerCommand(action->data().toString());
2353 void DebuggerPluginPrivate::showStatusMessage(const QString &msg0, int timeout)
2355 showMessage(msg0, LogStatus);
2357 msg.replace(QLatin1Char('\n'), QString());
2358 m_statusLabel->setText(msg);
2360 m_statusTimer.setSingleShot(true);
2361 m_statusTimer.start(timeout);
2363 m_lastPermanentStatusMessage = msg;
2364 m_statusTimer.stop();
2368 void DebuggerPluginPrivate::scriptExpressionEntered(const QString &expression)
2370 currentEngine()->executeDebuggerCommand(expression);
2373 void DebuggerPluginPrivate::openMemoryEditor()
2375 AddressDialog dialog;
2376 if (dialog.exec() == QDialog::Accepted)
2377 currentEngine()->openMemoryView(dialog.address());
2380 void DebuggerPluginPrivate::coreShutdown()
2382 m_shuttingDown = true;
2385 const CPlusPlus::Snapshot &DebuggerPluginPrivate::cppCodeModelSnapshot() const
2387 if (m_codeModelSnapshot.isEmpty() && action(UseCodeModel)->isChecked())
2388 m_codeModelSnapshot = CPlusPlus::CppModelManagerInterface::instance()->snapshot();
2389 return m_codeModelSnapshot;
2392 void DebuggerPluginPrivate::setSessionValue(const QString &name, const QVariant &value)
2394 QTC_ASSERT(sessionManager(), return);
2395 sessionManager()->setValue(name, value);
2396 //qDebug() << "SET SESSION VALUE: " << name;
2399 QVariant DebuggerPluginPrivate::sessionValue(const QString &name)
2401 QTC_ASSERT(sessionManager(), return QVariant());
2402 //qDebug() << "GET SESSION VALUE: " << name;
2403 return sessionManager()->value(name);
2406 void DebuggerPluginPrivate::openTextEditor(const QString &titlePattern0,
2407 const QString &contents)
2411 QString titlePattern = titlePattern0;
2412 EditorManager *editorManager = EditorManager::instance();
2413 QTC_ASSERT(editorManager, return);
2414 IEditor *editor = editorManager->openEditorWithContents(
2415 CC::K_DEFAULT_TEXT_EDITOR_ID, &titlePattern, contents);
2416 QTC_ASSERT(editor, return);
2417 editorManager->activateEditor(editor, EditorManager::IgnoreNavigationHistory);
2421 void DebuggerPluginPrivate::clearCppCodeModelSnapshot()
2423 m_codeModelSnapshot = CPlusPlus::Snapshot();
2426 void DebuggerPluginPrivate::showMessage(const QString &msg, int channel, int timeout)
2428 //qDebug() << "PLUGIN OUTPUT: " << channel << msg;
2429 //ConsoleWindow *cw = m_consoleWindow;
2430 QTC_ASSERT(m_logWindow, return);
2433 // This will append to m_logWindow's output pane, too.
2434 showStatusMessage(msg, timeout);
2437 m_logWindow->showInput(LogMisc, msg);
2438 m_logWindow->showOutput(LogMisc, msg);
2441 m_logWindow->showInput(LogInput, msg);
2442 m_logWindow->showOutput(LogInput, msg);
2444 case ScriptConsoleOutput:
2445 m_scriptConsoleWindow->appendResult(msg);
2448 m_logWindow->showOutput(channel, msg);
2449 QAction *action = m_mainWindow->dockWidget(_(DOCKWIDGET_OUTPUT))
2450 ->toggleViewAction();
2451 if (!action->isChecked())
2456 m_logWindow->showOutput(channel, msg);
2461 void DebuggerPluginPrivate::showQtDumperLibraryWarning(const QString &details)
2463 QMessageBox dialog(mainWindow());
2464 QPushButton *qtPref = dialog.addButton(tr("Open Qt4 Options"),
2465 QMessageBox::ActionRole);
2466 QPushButton *helperOff = dialog.addButton(tr("Turn off Helper Usage"),
2467 QMessageBox::ActionRole);
2468 QPushButton *justContinue = dialog.addButton(tr("Continue Anyway"),
2469 QMessageBox::AcceptRole);
2470 dialog.setDefaultButton(justContinue);
2471 dialog.setWindowTitle(tr("Debugging Helper Missing"));
2472 dialog.setText(tr("The debugger could not load the debugging helper library."));
2473 dialog.setInformativeText(tr(
2474 "The debugging helper is used to nicely format the values of some Qt "
2475 "and Standard Library data types. "
2476 "It must be compiled for each used Qt version separately. "
2477 "On the Qt4 options page, select a Qt installation "
2478 "and click Rebuild."));
2479 if (!details.isEmpty())
2480 dialog.setDetailedText(details);
2482 if (dialog.clickedButton() == qtPref) {
2483 ICore::instance()->showOptionsDialog(
2484 _(Qt4ProjectManager::Constants::QT_SETTINGS_CATEGORY),
2485 _(Qt4ProjectManager::Constants::QTVERSION_SETTINGS_PAGE_ID));
2486 } else if (dialog.clickedButton() == helperOff) {
2487 action(UseDebuggingHelpers)->setValue(qVariantFromValue(false), false);
2491 void DebuggerPluginPrivate::createNewDock(QWidget *widget)
2493 QDockWidget *dockWidget =
2494 m_mainWindow->createDockWidget(CppLanguage, widget);
2495 dockWidget->setWindowTitle(widget->windowTitle());
2496 dockWidget->setFeatures(QDockWidget::DockWidgetClosable);
2500 void DebuggerPluginPrivate::runControlStarted(DebuggerEngine *engine)
2502 activateDebugMode();
2503 QString toolChainName =
2504 ToolChain::toolChainName(engine->startParameters().toolChainType);
2505 const QString message = tr("Starting debugger '%1' for tool chain '%2'...")
2506 .arg(engine->objectName()).arg(toolChainName);
2507 showMessage(message, StatusBar);
2508 showMessage(m_debuggerSettings->dump(), LogDebug);
2509 m_snapshotHandler->appendSnapshot(engine);
2510 connectEngine(engine);
2513 void DebuggerPluginPrivate::runControlFinished(DebuggerEngine *engine)
2515 m_snapshotHandler->removeSnapshot(engine);
2516 if (m_snapshotHandler->size() == 0) {
2517 // Last engine quits.
2519 if (boolSetting(SwitchModeOnExit))
2520 activatePreviousMode();
2522 // Connect to some existing engine.
2523 m_snapshotHandler->activateSnapshot(0);
2527 void DebuggerPluginPrivate::remoteCommand(const QStringList &options,
2528 const QStringList &)
2530 if (options.isEmpty())
2533 unsigned enabledEngines = 0;
2534 QString errorMessage;
2536 if (!parseArguments(options,
2537 &m_attachRemoteParameters, &enabledEngines, &errorMessage)) {
2538 qWarning("%s", qPrintable(errorMessage));
2542 if (!attachCmdLine())
2543 qWarning("%s", qPrintable(
2544 _("Incomplete remote attach command received: %1").
2545 arg(options.join(QString(QLatin1Char(' '))))));
2548 QString DebuggerPluginPrivate::gdbBinaryForToolChain(int toolChain) const
2550 return GdbOptionsPage::gdbBinaryToolChainMap.key(toolChain);
2553 DebuggerLanguages DebuggerPluginPrivate::activeLanguages() const
2555 QTC_ASSERT(m_mainWindow, return AnyLanguage);
2556 return m_mainWindow->activeDebugLanguages();
2559 bool DebuggerPluginPrivate::isReverseDebugging() const
2561 return m_actions.reverseDirectionAction->isChecked();
2564 QMessageBox *showMessageBox(int icon, const QString &title,
2565 const QString &text, int buttons)
2567 QMessageBox *mb = new QMessageBox(QMessageBox::Icon(icon),
2568 title, text, QMessageBox::StandardButtons(buttons),
2569 debuggerCore()->mainWindow());
2570 mb->setAttribute(Qt::WA_DeleteOnClose);
2575 void DebuggerPluginPrivate::extensionsInitialized()
2577 ICore *core = ICore::instance();
2578 QTC_ASSERT(core, return);
2579 m_coreSettings = core->settings();
2580 m_debuggerSettings = new DebuggerSettings(m_coreSettings);
2582 m_continuableContext = Context("Gdb.Continuable");
2583 m_interruptibleContext = Context("Gdb.Interruptible");
2584 m_undisturbableContext = Context("Gdb.Undisturbable");
2585 m_finishedContext = Context("Gdb.Finished");
2586 m_anyContext.add(m_continuableContext);
2587 m_anyContext.add(m_interruptibleContext);
2588 m_anyContext.add(m_undisturbableContext);
2589 m_anyContext.add(m_finishedContext);
2591 connect(core, SIGNAL(coreAboutToClose()), this, SLOT(coreShutdown()));
2593 Core::ActionManager *am = core->actionManager();
2594 QTC_ASSERT(am, return);
2596 const Context globalcontext(CC::C_GLOBAL);
2597 const Context cppDebuggercontext(C_CPPDEBUGGER);
2598 const Context qmlDebuggerContext(C_QMLDEBUGGER);
2599 const Context cppeditorcontext(CppEditor::Constants::C_CPPEDITOR);
2601 m_startIcon = QIcon(_(":/debugger/images/debugger_start_small.png"));
2602 m_startIcon.addFile(__(":/debugger/images/debugger_start.png"));
2603 m_exitIcon = QIcon(_(":/debugger/images/debugger_stop_small.png"));
2604 m_exitIcon.addFile(__(":/debugger/images/debugger_stop.png"));
2605 m_continueIcon = QIcon(__(":/debugger/images/debugger_continue_small.png"));
2606 m_continueIcon.addFile(__(":/debugger/images/debugger_continue.png"));
2607 m_interruptIcon = QIcon(_(":/debugger/images/debugger_interrupt_small.png"));
2608 m_interruptIcon.addFile(__(":/debugger/images/debugger_interrupt.png"));
2609 m_locationMarkIcon = QIcon(_(":/debugger/images/location_16.png"));
2613 m_statusLabel = new QLabel;
2614 m_statusLabel->setMinimumSize(QSize(30, 10));
2616 m_breakHandler = new BreakHandler;
2617 m_breakWindow = new BreakWindow;
2618 m_breakWindow->setObjectName(DOCKWIDGET_BREAK);
2619 m_breakWindow->setModel(m_breakHandler->model());
2621 //m_consoleWindow = new ConsoleWindow;
2622 //m_consoleWindow->setObjectName(QLatin1String("CppDebugConsole"));
2623 m_modulesWindow = new ModulesWindow;
2624 m_modulesWindow->setObjectName(DOCKWIDGET_MODULES);
2625 m_logWindow = new LogWindow;
2626 m_logWindow->setObjectName(DOCKWIDGET_OUTPUT);
2627 m_registerWindow = new RegisterWindow;
2628 m_registerWindow->setObjectName(DOCKWIDGET_REGISTER);
2629 m_stackWindow = new StackWindow;
2630 m_stackWindow->setObjectName(DOCKWIDGET_STACK);
2631 m_sourceFilesWindow = new SourceFilesWindow;
2632 m_sourceFilesWindow->setObjectName(DOCKWIDGET_SOURCE_FILES);
2633 m_threadsWindow = new ThreadsWindow;
2634 m_threadsWindow->setObjectName(DOCKWIDGET_THREADS);
2635 m_returnWindow = new WatchWindow(WatchWindow::ReturnType);
2636 m_returnWindow->setObjectName(QLatin1String("CppDebugReturn"));
2637 m_localsWindow = new WatchWindow(WatchWindow::LocalsType);
2638 m_localsWindow->setObjectName(QLatin1String("CppDebugLocals"));
2639 m_watchersWindow = new WatchWindow(WatchWindow::WatchersType);
2640 m_watchersWindow->setObjectName(QLatin1String("CppDebugWatchers"));
2641 m_scriptConsoleWindow = new ScriptConsole;
2642 m_scriptConsoleWindow->setWindowTitle(tr("QML Script Console"));
2643 m_scriptConsoleWindow->setObjectName(DOCKWIDGET_QML_SCRIPTCONSOLE);
2644 connect(m_scriptConsoleWindow, SIGNAL(expressionEntered(QString)),
2645 SLOT(scriptExpressionEntered(QString)));
2648 m_snapshotHandler = new SnapshotHandler;
2649 m_snapshotWindow = new SnapshotWindow(m_snapshotHandler);
2650 m_snapshotWindow->setObjectName(DOCKWIDGET_SNAPSHOTS);
2651 m_snapshotWindow->setModel(m_snapshotHandler->model());
2654 connect(m_localsWindow->header(), SIGNAL(sectionResized(int,int,int)),
2655 SLOT(updateWatchersHeader(int,int,int)), Qt::QueuedConnection);
2659 act = m_actions.continueAction = new QAction(tr("Continue"), this);
2660 act->setIcon(m_continueIcon);
2661 connect(act, SIGNAL(triggered()), SLOT(handleExecContinue()));
2663 act = m_actions.exitAction = new QAction(tr("Exit Debugger"), this);
2664 act->setIcon(m_exitIcon);
2665 connect(act, SIGNAL(triggered()), SLOT(handleExecExit()));
2667 act = m_actions.interruptAction = new QAction(tr("Interrupt"), this);
2668 act->setIcon(m_interruptIcon);
2669 connect(act, SIGNAL(triggered()), SLOT(handleExecInterrupt()));
2671 // A "disabled pause" seems to be a good choice.
2672 act = m_actions.undisturbableAction = new QAction(tr("Debugger is Busy"), this);
2673 act->setIcon(m_interruptIcon);
2674 act->setEnabled(false);
2676 act = m_actions.resetAction = new QAction(tr("Abort Debugging"), this);
2677 act->setToolTip(tr("Aborts debugging and "
2678 "resets the debugger to the initial state."));
2679 connect(act, SIGNAL(triggered()), SLOT(handleExecReset()));
2681 act = m_actions.nextAction = new QAction(tr("Step Over"), this);
2682 act->setIcon(QIcon(__(":/debugger/images/debugger_stepover_small.png")));
2683 connect(act, SIGNAL(triggered()), SLOT(handleExecNext()));
2685 act = m_actions.stepAction = new QAction(tr("Step Into"), this);
2686 act->setIcon(QIcon(__(":/debugger/images/debugger_stepinto_small.png")));
2687 connect(act, SIGNAL(triggered()), SLOT(handleExecStep()));
2689 act = m_actions.stepOutAction = new QAction(tr("Step Out"), this);
2690 act->setIcon(QIcon(__(":/debugger/images/debugger_stepout_small.png")));
2691 connect(act, SIGNAL(triggered()), SLOT(handleExecStepOut()));
2693 act = m_actions.runToLineAction = new QAction(tr("Run to Line"), this);
2694 connect(act, SIGNAL(triggered()), SLOT(handleExecRunToLine()));
2696 act = m_actions.runToFunctionAction =
2697 new QAction(tr("Run to Outermost Function"), this);
2698 connect(act, SIGNAL(triggered()), SLOT(handleExecRunToFunction()));
2700 act = m_actions.returnFromFunctionAction =
2701 new QAction(tr("Immediately Return From Inner Function"), this);
2702 connect(act, SIGNAL(triggered()), SLOT(handleExecReturn()));
2704 act = m_actions.jumpToLineAction = new QAction(tr("Jump to Line"), this);
2705 connect(act, SIGNAL(triggered()), SLOT(handleExecJumpToLine()));
2707 act = m_actions.breakAction = new QAction(tr("Toggle Breakpoint"), this);
2709 act = m_actions.watchAction1 = new QAction(tr("Add to Watch Window"), this);
2710 connect(act, SIGNAL(triggered()), SLOT(handleAddToWatchWindow()));
2712 act = m_actions.watchAction2 = new QAction(tr("Add to Watch Window"), this);
2713 connect(act, SIGNAL(triggered()), SLOT(handleAddToWatchWindow()));
2715 //m_actions.snapshotAction = new QAction(tr("Create Snapshot"), this);
2716 //m_actions.snapshotAction->setProperty(Role, RequestCreateSnapshotRole);
2717 //m_actions.snapshotAction->setIcon(
2718 // QIcon(__(":/debugger/images/debugger_snapshot_small.png")));
2720 act = m_actions.reverseDirectionAction =
2721 new QAction(tr("Reverse Direction"), this);
2722 act->setCheckable(true);
2723 act->setChecked(false);
2724 act->setCheckable(false);
2725 act->setIcon(QIcon(__(":/debugger/images/debugger_reversemode_16.png")));
2726 act->setIconVisibleInMenu(false);
2728 act = m_actions.frameDownAction = new QAction(tr("Move to Called Frame"), this);
2729 connect(act, SIGNAL(triggered()), SLOT(handleFrameDown()));
2731 act = m_actions.frameUpAction = new QAction(tr("Move to Calling Frame"), this);
2732 connect(act, SIGNAL(triggered()), SLOT(handleFrameUp()));
2734 connect(action(OperateByInstruction), SIGNAL(triggered(bool)),
2735 SLOT(handleOperateByInstructionTriggered(bool)));
2737 connect(&m_statusTimer, SIGNAL(timeout()), SLOT(clearStatusMessage()));
2739 connect(action(ExecuteCommand), SIGNAL(triggered()),
2740 SLOT(executeDebuggerCommand()));
2742 ActionContainer *debugMenu =
2743 am->actionContainer(ProjectExplorer::Constants::M_DEBUG);
2746 QDockWidget *dock = 0;
2747 dock = m_mainWindow->createDockWidget(CppLanguage, m_modulesWindow);
2748 connect(dock->toggleViewAction(), SIGNAL(toggled(bool)),
2749 SLOT(modulesDockToggled(bool)), Qt::QueuedConnection);
2751 dock = m_mainWindow->createDockWidget(CppLanguage, m_registerWindow);
2752 connect(dock->toggleViewAction(), SIGNAL(toggled(bool)),
2753 SLOT(registerDockToggled(bool)), Qt::QueuedConnection);
2755 dock = m_mainWindow->createDockWidget(CppLanguage, m_sourceFilesWindow);
2756 connect(dock->toggleViewAction(), SIGNAL(toggled(bool)),
2757 SLOT(sourceFilesDockToggled(bool)), Qt::QueuedConnection);
2759 dock = m_mainWindow->createDockWidget(AnyLanguage, m_logWindow);
2760 dock->setProperty(DOCKWIDGET_DEFAULT_AREA, Qt::TopDockWidgetArea);
2762 m_mainWindow->createDockWidget(CppLanguage, m_breakWindow);
2763 //m_mainWindow->createDockWidget(CppLanguage, m_consoleWindow);
2764 m_mainWindow->createDockWidget(CppLanguage, m_snapshotWindow);
2765 m_mainWindow->createDockWidget(CppLanguage, m_stackWindow);
2766 m_mainWindow->createDockWidget(CppLanguage, m_threadsWindow);
2767 m_mainWindow->createDockWidget(QmlLanguage, m_scriptConsoleWindow);
2769 QSplitter *localsAndWatchers = new Core::MiniSplitter(Qt::Vertical);
2770 localsAndWatchers->setObjectName(DOCKWIDGET_WATCHERS);
2771 localsAndWatchers->setWindowTitle(m_localsWindow->windowTitle());
2772 localsAndWatchers->addWidget(m_localsWindow);
2773 localsAndWatchers->addWidget(m_returnWindow);
2774 localsAndWatchers->addWidget(m_watchersWindow);
2775 localsAndWatchers->setStretchFactor(0, 3);
2776 localsAndWatchers->setStretchFactor(1, 1);
2777 localsAndWatchers->setStretchFactor(2, 1);
2779 dock = m_mainWindow->createDockWidget(CppLanguage, localsAndWatchers);
2780 dock->setProperty(DOCKWIDGET_DEFAULT_AREA, Qt::RightDockWidgetArea);
2782 m_debuggerSettings->readSettings();
2783 GdbOptionsPage::readGdbBinarySettings();
2785 // Register factory of DebuggerRunControl.
2786 m_debuggerRunControlFactory = new DebuggerRunControlFactory
2787 (m_plugin, DebuggerEngineType(m_cmdLineEnabledEngines));
2788 m_plugin->addAutoReleasedObject(m_debuggerRunControlFactory);
2790 // The main "Start Debugging" action.
2791 act = m_debugAction = new QAction(this);
2792 QIcon debuggerIcon(":/projectexplorer/images/debugger_start_small.png");
2793 debuggerIcon.addFile(":/projectexplorer/images/debugger_start.png");
2794 act->setIcon(debuggerIcon);
2795 act->setText(tr("Start Debugging"));
2796 connect(act, SIGNAL(triggered()), this, SLOT(debugProject()));
2798 // Handling of external applications.
2799 act = m_startExternalAction = new QAction(this);
2800 act->setText(tr("Start and Debug External Application..."));
2801 connect(act, SIGNAL(triggered()), SLOT(startExternalApplication()));
2803 act = m_startRemoteLldbAction = new QAction(this);
2804 act->setText(tr("Start and Debug External Application with External Engine..."));
2805 connect(act, SIGNAL(triggered()), SLOT(startRemoteEngine()));
2807 act = m_attachExternalAction = new QAction(this);
2808 act->setText(tr("Attach to Running External Application..."));
2809 connect(act, SIGNAL(triggered()), SLOT(attachExternalApplication()));
2811 act = m_attachCoreAction = new QAction(this);
2812 act->setText(tr("Attach to Core..."));
2813 connect(act, SIGNAL(triggered()), SLOT(attachCore()));
2815 act = m_attachTcfAction = new QAction(this);
2816 act->setText(tr("Attach to Running Tcf Agent..."));
2817 act->setToolTip(tr("This attaches to a running "
2818 "'Target Communication Framework' agent."));
2819 connect(act, SIGNAL(triggered()), SLOT(attachRemoteTcf()));
2821 act = m_startRemoteAction = new QAction(this);
2822 act->setText(tr("Start and Attach to Remote Application..."));
2823 connect(act, SIGNAL(triggered()), SLOT(startRemoteApplication()));
2826 m_startRemoteCdbAction = new QAction(tr("Attach to Remote CDB Session..."), this);
2827 connect(m_startRemoteCdbAction, SIGNAL(triggered()), SLOT(startRemoteCdbSession()));
2830 act = m_detachAction = new QAction(this);
2831 act->setText(tr("Detach Debugger"));
2832 connect(act, SIGNAL(triggered()), SLOT(handleExecDetach()));
2835 ActionContainer *mstart = am->actionContainer(PE::M_DEBUG_STARTDEBUGGING);
2837 cmd = am->registerAction(m_debugAction, Constants::DEBUG, globalcontext);
2838 cmd->setAttribute(Core::Command::CA_UpdateText);
2839 cmd->setAttribute(Core::Command::CA_UpdateIcon);
2840 cmd->setDefaultText(tr("Start Debugging"));
2841 cmd->setDefaultKeySequence(QKeySequence(Constants::DEBUG_KEY));
2842 mstart->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
2843 Core::ICore::instance()->modeManager()->addAction(cmd, Constants::P_ACTION_DEBUG);
2845 cmd = am->registerAction(m_actions.continueAction,
2846 Constants::DEBUG, m_continuableContext);
2847 mstart->addAction(cmd, CC::G_DEFAULT_ONE);
2849 cmd = am->registerAction(m_startExternalAction,
2850 Constants::STARTEXTERNAL, globalcontext);
2851 cmd->setAttribute(Command::CA_Hide);
2852 mstart->addAction(cmd, CC::G_DEFAULT_ONE);
2854 cmd = am->registerAction(m_startRemoteLldbAction,
2855 Constants::STARTREMOTELLDB, globalcontext);
2856 cmd->setAttribute(Command::CA_Hide);
2857 mstart->addAction(cmd, CC::G_DEFAULT_ONE);
2859 cmd = am->registerAction(m_attachExternalAction,
2860 Constants::ATTACHEXTERNAL, globalcontext);
2861 cmd->setAttribute(Command::CA_Hide);
2862 mstart->addAction(cmd, CC::G_DEFAULT_ONE);
2864 cmd = am->registerAction(m_attachCoreAction,
2865 Constants::ATTACHCORE, globalcontext);
2867 cmd->setAttribute(Command::CA_Hide);
2868 mstart->addAction(cmd, CC::G_DEFAULT_ONE);
2870 cmd = am->registerAction(m_attachTcfAction,
2871 Constants::ATTACHTCF, globalcontext);
2872 mstart->addAction(cmd, CC::G_DEFAULT_ONE);
2874 cmd = am->registerAction(m_startRemoteAction,
2875 Constants::ATTACHREMOTE, globalcontext);
2876 cmd->setAttribute(Command::CA_Hide);
2877 mstart->addAction(cmd, CC::G_DEFAULT_ONE);
2879 if (m_startRemoteCdbAction) {
2880 cmd = am->registerAction(m_startRemoteCdbAction,
2881 Constants::ATTACHREMOTECDB, globalcontext);
2882 cmd->setAttribute(Command::CA_Hide);
2883 mstart->addAction(cmd, CC::G_DEFAULT_ONE);
2886 cmd = am->registerAction(m_detachAction,
2887 Constants::DETACH, globalcontext);
2888 cmd->setAttribute(Command::CA_Hide);
2889 debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
2891 cmd = am->registerAction(m_actions.exitAction,
2892 Constants::STOP, globalcontext);
2893 //cmd->setDefaultKeySequence(QKeySequence(Constants::STOP_KEY));
2894 cmd->setDefaultText(tr("Stop Debugger"));
2895 debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
2897 cmd = am->registerAction(m_actions.interruptAction,
2898 Constants::DEBUG, m_interruptibleContext);
2899 cmd->setDefaultText(tr("Interrupt Debugger"));
2901 cmd = am->registerAction(m_actions.undisturbableAction,
2902 Constants::DEBUG, m_undisturbableContext);
2903 cmd->setDefaultText(tr("Debugger is Busy"));
2905 cmd = am->registerAction(m_actions.resetAction,
2906 Constants::RESET, globalcontext);
2907 //cmd->setDefaultKeySequence(QKeySequence(Constants::RESET_KEY));
2908 cmd->setDefaultText(tr("Reset Debugger"));
2909 debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
2911 QAction *sep = new QAction(this);
2912 sep->setSeparator(true);
2913 cmd = am->registerAction(sep, _("Debugger.Sep.Step"), globalcontext);
2914 debugMenu->addAction(cmd);
2916 cmd = am->registerAction(m_actions.nextAction,
2917 Constants::NEXT, cppDebuggercontext);
2918 cmd->setDefaultKeySequence(QKeySequence(Constants::NEXT_KEY));
2919 cmd->setAttribute(Command::CA_Hide);
2920 debugMenu->addAction(cmd);
2922 cmd = am->registerAction(m_actions.stepAction,
2923 Constants::STEP, cppDebuggercontext);
2924 cmd->setDefaultKeySequence(QKeySequence(Constants::STEP_KEY));
2925 cmd->setAttribute(Command::CA_Hide);
2926 debugMenu->addAction(cmd);
2928 cmd = am->registerAction(m_actions.stepOutAction,
2929 Constants::STEPOUT, cppDebuggercontext);
2930 cmd->setDefaultKeySequence(QKeySequence(Constants::STEPOUT_KEY));
2931 cmd->setAttribute(Command::CA_Hide);
2932 debugMenu->addAction(cmd);
2934 cmd = am->registerAction(m_actions.runToLineAction,
2935 Constants::RUN_TO_LINE1, cppDebuggercontext);
2936 cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_LINE_KEY));
2937 cmd->setAttribute(Command::CA_Hide);
2938 debugMenu->addAction(cmd);
2940 cmd = am->registerAction(m_actions.runToFunctionAction,
2941 Constants::RUN_TO_FUNCTION, cppDebuggercontext);
2942 cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_FUNCTION_KEY));
2943 cmd->setAttribute(Command::CA_Hide);
2944 debugMenu->addAction(cmd);
2946 cmd = am->registerAction(m_actions.jumpToLineAction,
2947 Constants::JUMP_TO_LINE1, cppDebuggercontext);
2948 cmd->setAttribute(Command::CA_Hide);
2949 debugMenu->addAction(cmd);
2951 cmd = am->registerAction(m_actions.returnFromFunctionAction,
2952 Constants::RETURN_FROM_FUNCTION, cppDebuggercontext);
2953 cmd->setAttribute(Command::CA_Hide);
2954 debugMenu->addAction(cmd);
2956 cmd = am->registerAction(m_actions.reverseDirectionAction,
2957 Constants::REVERSE, cppDebuggercontext);
2958 cmd->setDefaultKeySequence(QKeySequence(Constants::REVERSE_KEY));
2959 cmd->setAttribute(Command::CA_Hide);
2960 debugMenu->addAction(cmd);
2962 sep = new QAction(this);
2963 sep->setSeparator(true);
2964 cmd = am->registerAction(sep, _("Debugger.Sep.Break"), globalcontext);
2965 debugMenu->addAction(cmd);
2967 //cmd = am->registerAction(m_actions.snapshotAction,
2968 // Constants::SNAPSHOT, cppDebuggercontext);
2969 //cmd->setDefaultKeySequence(QKeySequence(Constants::SNAPSHOT_KEY));
2970 //cmd->setAttribute(Command::CA_Hide);
2971 //debugMenu->addAction(cmd);
2973 cmd = am->registerAction(m_actions.frameDownAction,
2974 Constants::FRAME_DOWN, cppDebuggercontext);
2975 cmd = am->registerAction(m_actions.frameUpAction,
2976 Constants::FRAME_UP, cppDebuggercontext);
2978 cmd = am->registerAction(action(OperateByInstruction),
2979 Constants::OPERATE_BY_INSTRUCTION, cppDebuggercontext);
2980 cmd->setAttribute(Command::CA_Hide);
2981 debugMenu->addAction(cmd);
2983 cmd = am->registerAction(m_actions.breakAction,
2984 Constants::TOGGLE_BREAK, globalcontext);
2985 cmd->setDefaultKeySequence(QKeySequence(Constants::TOGGLE_BREAK_KEY));
2986 debugMenu->addAction(cmd);
2987 connect(m_actions.breakAction, SIGNAL(triggered()),
2988 SLOT(toggleBreakpoint()));
2990 sep = new QAction(this);
2991 sep->setSeparator(true);
2992 cmd = am->registerAction(sep, _("Debugger.Sep.Watch"), globalcontext);
2993 debugMenu->addAction(cmd);
2995 cmd = am->registerAction(m_actions.watchAction1,
2996 Constants::ADD_TO_WATCH1, cppeditorcontext);
2997 cmd->action()->setEnabled(true);
2998 //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+W")));
2999 debugMenu->addAction(cmd);
3001 // If the CppEditor plugin is there, we want to add something to
3002 // the editor context menu.
3003 if (ActionContainer *editorContextMenu =
3004 am->actionContainer(CppEditor::Constants::M_CONTEXT)) {
3005 cmd = am->registerAction(sep, _("Debugger.Sep.Views"),
3006 cppDebuggercontext);
3007 editorContextMenu->addAction(cmd);
3008 cmd->setAttribute(Command::CA_Hide);
3010 cmd = am->registerAction(m_actions.watchAction2,
3011 Constants::ADD_TO_WATCH2, cppDebuggercontext);
3012 cmd->action()->setEnabled(true);
3013 editorContextMenu->addAction(cmd);
3014 cmd->setAttribute(Command::CA_Hide);
3017 m_plugin->addAutoReleasedObject(new CommonOptionsPage);
3018 QList<Core::IOptionsPage *> engineOptionPages;
3019 if (m_cmdLineEnabledEngines & GdbEngineType)
3020 addGdbOptionPages(&engineOptionPages);
3022 addCdb2OptionPages(&engineOptionPages);
3025 if (m_cmdLineEnabledEngines & LldbEngineType)
3026 addLldbOptionPages(&engineOptionPages);
3029 //if (m_cmdLineEnabledEngines & ScriptEngineType)
3030 // addScriptOptionPages(&engineOptionPages);
3031 //if (m_cmdLineEnabledEngines & TcfEngineType)
3032 // addTcfOptionPages(&engineOptionPages);
3033 foreach (Core::IOptionsPage *op, engineOptionPages)
3034 m_plugin->addAutoReleasedObject(op);
3035 m_plugin->addAutoReleasedObject(new DebuggingHelperOptionPage);
3037 connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)),
3038 SLOT(onModeChanged(Core::IMode*)));
3042 m_plugin->addAutoReleasedObject(new DebugMode);
3049 connect(TextEditorSettings::instance(),
3050 SIGNAL(fontSettingsChanged(TextEditor::FontSettings)),
3051 SLOT(fontSettingsChanged(TextEditor::FontSettings)));
3054 connect(sessionManager(), SIGNAL(sessionLoaded()),
3055 SLOT(sessionLoaded()));
3056 connect(sessionManager(), SIGNAL(aboutToSaveSession()),
3057 SLOT(aboutToSaveSession()));
3058 connect(sessionManager(), SIGNAL(aboutToUnloadSession()),
3059 SLOT(aboutToUnloadSession()));
3060 connect(ProjectExplorerPlugin::instance(), SIGNAL(updateRunActions()),
3061 SLOT(updateDebugActions()));
3064 QObject *editorManager = core->editorManager();
3065 connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)),
3066 SLOT(editorOpened(Core::IEditor*)));
3068 // Application interaction
3069 connect(action(SettingsDialog), SIGNAL(triggered()),
3070 SLOT(showSettingsDialog()));
3073 QWidget *toolbarContainer = new QWidget;
3075 QHBoxLayout *hbox = new QHBoxLayout(toolbarContainer);
3077 hbox->setSpacing(0);
3078 hbox->addWidget(toolButton(am->command(Constants::DEBUG)->action()));
3079 hbox->addWidget(toolButton(am->command(STOP)->action()));
3080 hbox->addWidget(toolButton(am->command(NEXT)->action()));
3081 hbox->addWidget(toolButton(am->command(STEP)->action()));
3082 hbox->addWidget(toolButton(am->command(STEPOUT)->action()));
3083 hbox->addWidget(toolButton(am->command(OPERATE_BY_INSTRUCTION)->action()));
3085 //hbox->addWidget(new Utils::StyledSeparator);
3086 m_reverseToolButton = toolButton(am->command(REVERSE)->action());
3087 hbox->addWidget(m_reverseToolButton);
3088 //m_reverseToolButton->hide();
3090 hbox->addWidget(new Utils::StyledSeparator);
3091 hbox->addWidget(new QLabel(tr("Threads:")));
3093 m_threadBox = new QComboBox;
3094 connect(m_threadBox, SIGNAL(activated(int)), SLOT(selectThread(int)));
3096 hbox->addWidget(m_threadBox);
3097 hbox->addSpacerItem(new QSpacerItem(4, 0));
3098 hbox->addWidget(m_statusLabel, 10);
3100 m_mainWindow->setToolbar(CppLanguage, toolbarContainer);
3102 connect(action(EnableReverseDebugging),
3103 SIGNAL(valueChanged(QVariant)),
3104 SLOT(enableReverseDebuggingTriggered(QVariant)));
3109 connect(sessionManager(),
3110 SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
3111 SLOT(onCurrentProjectChanged(ProjectExplorer::Project*)));
3113 QTC_ASSERT(m_coreSettings, /**/);
3114 m_watchersWindow->setVisible(false);
3115 m_returnWindow->setVisible(false);
3117 // time gdb -i mi -ex 'debuggerplugin.cpp:800' -ex r -ex q bin/qtcreator.bin
3118 const QByteArray env = qgetenv("QTC_DEBUGGER_TEST");
3119 //qDebug() << "EXTENSIONS INITIALIZED:" << env;
3120 // if (!env.isEmpty())
3121 // m_plugin->runTest(QString::fromLocal8Bit(env));
3122 if (m_attachRemoteParameters.attachPid
3123 || !m_attachRemoteParameters.attachTarget.isEmpty())
3124 QTimer::singleShot(0, this, SLOT(attachCmdLine()));
3127 Utils::SavedAction *DebuggerPluginPrivate::action(int code) const
3129 return m_debuggerSettings->item(code);
3132 bool DebuggerPluginPrivate::boolSetting(int code) const
3134 return m_debuggerSettings->item(code)->value().toBool();
3137 QString DebuggerPluginPrivate::stringSetting(int code) const
3139 return m_debuggerSettings->item(code)->value().toString();
3142 void DebuggerPluginPrivate::showModuleSymbols(const QString &moduleName,
3143 const Symbols &symbols)
3145 QTreeWidget *w = new QTreeWidget;
3146 w->setColumnCount(5);
3147 w->setRootIsDecorated(false);
3148 w->setAlternatingRowColors(true);
3149 w->setSortingEnabled(true);
3150 w->setObjectName("Symbols." + moduleName);
3152 header.append(tr("Symbol"));
3153 header.append(tr("Address"));
3154 header.append(tr("Code"));
3155 header.append(tr("Section"));
3156 header.append(tr("Name"));
3157 w->setHeaderLabels(header);
3158 w->setWindowTitle(tr("Symbols in \"%1\"").arg(moduleName));
3159 foreach (const Symbol &s, symbols) {
3160 QTreeWidgetItem *it = new QTreeWidgetItem;
3161 it->setData(0, Qt::DisplayRole, s.name);
3162 it->setData(1, Qt::DisplayRole, s.address);
3163 it->setData(2, Qt::DisplayRole, s.state);
3164 it->setData(3, Qt::DisplayRole, s.section);
3165 it->setData(4, Qt::DisplayRole, s.demangled);
3166 w->addTopLevelItem(it);
3171 void DebuggerPluginPrivate::aboutToShutdown()
3173 disconnect(sessionManager(),
3174 SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
3176 m_debuggerSettings->writeSettings();
3177 m_mainWindow->writeSettings();
3178 if (GdbOptionsPage::gdbBinariesChanged)
3179 GdbOptionsPage::writeGdbBinarySettings();
3182 } // namespace Internal
3185 ///////////////////////////////////////////////////////////////////////
3189 ///////////////////////////////////////////////////////////////////////
3191 using namespace Debugger::Internal;
3193 DebuggerPlugin::DebuggerPlugin()
3195 theDebuggerCore = new DebuggerPluginPrivate(this);
3198 DebuggerPlugin::~DebuggerPlugin()
3200 delete theDebuggerCore;
3201 theDebuggerCore = 0;
3204 bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
3206 return theDebuggerCore->initialize(arguments, errorMessage);
3209 ExtensionSystem::IPlugin::ShutdownFlag DebuggerPlugin::aboutToShutdown()
3211 theDebuggerCore->aboutToShutdown();
3212 return SynchronousShutdown;
3215 void DebuggerPlugin::remoteCommand(const QStringList &options,
3216 const QStringList &list)
3218 theDebuggerCore->remoteCommand(options, list);
3222 DebuggerRunControl *DebuggerPlugin::createDebugger
3223 (const DebuggerStartParameters &sp, RunConfiguration *rc)
3225 return theDebuggerCore->createDebugger(sp, rc);
3228 void DebuggerPlugin::startDebugger(RunControl *runControl)
3230 theDebuggerCore->startDebugger(runControl);
3233 void DebuggerPlugin::extensionsInitialized()
3235 theDebuggerCore->extensionsInitialized();
3238 bool DebuggerPlugin::isActiveDebugLanguage(int language)
3240 return theDebuggerCore->isActiveDebugLanguage(language);
3243 DebuggerMainWindow *DebuggerPlugin::mainWindow()
3245 return theDebuggerCore->m_mainWindow;
3248 QWidget *DebugMode::widget()
3251 //qDebug() << "CREATING DEBUG MODE WIDGET";
3252 m_widget = theDebuggerCore->m_mainWindow->createContents(this);
3253 m_widget->setFocusProxy(EditorManager::instance());
3258 //////////////////////////////////////////////////////////////////////
3262 //////////////////////////////////////////////////////////////////////
3265 void DebuggerPlugin::runTest(const QString &fileName)
3267 DebuggerStartParameters sp;
3268 sp.executable = fileName;
3269 sp.processArgs = QStringList() << "--run-debuggee";
3270 sp.workingDirectory.clear();
3271 startDebugger(m_debuggerRunControlFactory->create(sp));
3275 } // namespace Debugger
3277 #include "debuggerplugin.moc"
3279 Q_EXPORT_PLUGIN(Debugger::DebuggerPlugin)