debuggermanager.cpp 65.9 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2
3
4
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11
12
13
14
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
15
**
16
** GNU Lesser General Public License Usage
17
**
18
19
20
21
22
23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
**
25
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
con's avatar
con committed
29
30
31

#include "debuggermanager.h"

32
#include "debuggerplugin.h"
33
#include "debuggeractions.h"
34
#include "debuggeragents.h"
35
#include "debuggerrunner.h"
con's avatar
con committed
36
37
#include "debuggerconstants.h"
#include "idebuggerengine.h"
38
#include "debuggerstringutils.h"
39
#include "watchutils.h"
40
41
#include "debuggeruiswitcher.h"
#include "debuggermainwindow.h"
con's avatar
con committed
42
43
44
45
46

#include "breakwindow.h"
#include "debuggeroutputwindow.h"
#include "moduleswindow.h"
#include "registerwindow.h"
47
#include "snapshotwindow.h"
con's avatar
con committed
48
#include "stackwindow.h"
49
#include "sourcefileswindow.h"
con's avatar
con committed
50
51
52
53
54
55
#include "threadswindow.h"
#include "watchwindow.h"

#include "breakhandler.h"
#include "moduleshandler.h"
#include "registerhandler.h"
56
#include "snapshothandler.h"
con's avatar
con committed
57
#include "stackhandler.h"
58
#include "stackframe.h"
con's avatar
con committed
59
60
#include "watchhandler.h"

61
#include "debuggerdialogs.h"
Friedemann Kleint's avatar
m.txt  
Friedemann Kleint committed
62
#ifdef Q_OS_WIN
63
#  include "shared/peutils.h"
Friedemann Kleint's avatar
m.txt  
Friedemann Kleint committed
64
#endif
65

66
#include <coreplugin/icore.h>
67
#include <coreplugin/minisplitter.h>
68
#include <coreplugin/editormanager/editormanager.h>
69
#include <utils/qtcassert.h>
70
#include <utils/savedaction.h>
71
#include <projectexplorer/toolchain.h>
72
73
#include <cplusplus/CppDocument.h>
#include <cpptools/cppmodelmanagerinterface.h>
74
#include <qt4projectmanager/qt4projectmanagerconstants.h>
75
#include <texteditor/fontsettings.h>
76
#include <texteditor/itexteditor.h>
77

con's avatar
con committed
78
79
80
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
81
#include <QtCore/QTextStream>
con's avatar
con committed
82
#include <QtCore/QTime>
83
#include <QtCore/QTimer>
con's avatar
con committed
84

85
#include <QtGui/QApplication>
con's avatar
con committed
86
87
88
89
90
#include <QtGui/QAction>
#include <QtGui/QComboBox>
#include <QtGui/QDockWidget>
#include <QtGui/QErrorMessage>
#include <QtGui/QFileDialog>
91
#include <QtGui/QHeaderView>
con's avatar
con committed
92
93
94
#include <QtGui/QLabel>
#include <QtGui/QMessageBox>
#include <QtGui/QPlainTextEdit>
95
#include <QtGui/QPushButton>
con's avatar
con committed
96
97
98
99
100
#include <QtGui/QStatusBar>
#include <QtGui/QTextBlock>
#include <QtGui/QTextCursor>
#include <QtGui/QToolButton>
#include <QtGui/QToolTip>
hjk's avatar
hjk committed
101
#include <QtGui/QTreeWidget>
con's avatar
con committed
102

103
104
105
106
#define DEBUG_STATE 1
#ifdef DEBUG_STATE
// use  Q_FUNC_INFO?
#   define STATE_DEBUG(s) \
hjk's avatar
hjk committed
107
108
    do { QString msg; QTextStream ts(&msg); ts << s; \
      showDebuggerOutput(LogDebug, msg); } while (0)
109
110
111
112
#else
#   define STATE_DEBUG(s)
#endif

113
114
// Note: the Debugger process itself and any helper processes like
// gdbserver, the trk client etc are referred to as 'Adapter',
hjk's avatar
hjk committed
115
116
// whereas the debugged process is referred to as 'Inferior'.
//
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
117
//              0 == DebuggerNotReady
hjk's avatar
hjk committed
118
//                          |
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
119
//                    EngineStarting
hjk's avatar
hjk committed
120
//                          |
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
121
//                    AdapterStarting --> AdapterStartFailed --> 0
hjk's avatar
hjk committed
122
//                          |
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//                    AdapterStarted ------------------------------------.
//                          |                                            v
//                   InferiorStarting ----> InferiorStartFailed -------->|
//                          |                                            |
//         (core)           |     (attach) (term) (remote)               |
//      .-----------------<-|->------------------.                       |
//      |                   v                    |                       |
//  InferiorUnrunnable      | (plain)            |                       |
//      |                   | (trk)              |                       |
//      |                   |                    |                       |
//      |    .--> InferiorRunningRequested       |                       |
//      |    |              |                    |                       |
//      |    |       InferiorRunning             |                       |
//      |    |              |                    |                       |
//      |    |       InferiorStopping            |                       |
//      |    |              |                    |                       |
//      |    '------ InferiorStopped <-----------'                       |
//      |                   |                                            v
//      |          InferiorShuttingDown  ->  InferiorShutdownFailed ---->|
//      |                   |                                            |
//      |            InferiorShutDown                                    |
//      |                   |                                            |
//      '-------->  EngineShuttingDown  <--------------------------------'
hjk's avatar
hjk committed
146
147
//                          |
//                          0
hjk's avatar
hjk committed
148
149
150
151
152
153
//
// Allowed actions:
//    [R] :  Run
//    [C] :  Continue
//    [N] :  Step, Next

154
155
namespace Debugger {
namespace Internal {
156

157
158
IDebuggerEngine *createGdbEngine(DebuggerManager *parent);
IDebuggerEngine *createScriptEngine(DebuggerManager *parent);
hjk's avatar
hjk committed
159
IDebuggerEngine *createPdbEngine(DebuggerManager *parent);
160

hjk's avatar
hjk committed
161
// The createCdbEngine function takes a list of options pages it can add to.
162
163
164
// This allows for having a "enabled" toggle on the page independently
// of the engine. That's good for not enabling the related ActiveX control
// unnecessarily.
165

hjk's avatar
hjk committed
166
IDebuggerEngine *createCdbEngine(DebuggerManager *, bool /* cmdLineEnabled */, QList<Core::IOptionsPage*> *)
167
168
169
170
171
#ifdef CDB_ENABLED
;
#else
{ return 0; }
#endif
172

173
} // namespace Internal
174

175
DEBUGGER_EXPORT QDebug operator<<(QDebug str, const DebuggerStartParameters &p)
176
177
178
179
180
181
182
183
184
185
{
    QDebug nospace = str.nospace();
    const QString sep = QString(QLatin1Char(','));
    nospace << "executable=" << p.executable << " coreFile=" << p.coreFile
            << " processArgs=" << p.processArgs.join(sep)
            << " environment=<" << p.environment.size() << " variables>"
            << " workingDir=" << p.workingDir << " buildDir=" << p.buildDir
            << " attachPID=" << p.attachPID << " useTerminal=" << p.useTerminal
            << " remoteChannel=" << p.remoteChannel
            << " remoteArchitecture=" << p.remoteArchitecture
186
            << " symbolFileName=" << p.symbolFileName
187
188
            << " serverStartScript=" << p.serverStartScript
            << " toolchain=" << p.toolChainType << '\n';
189
190
191
    return str;
}

192
using namespace Constants;
193
using namespace Debugger::Internal;
194
using namespace TextEditor;
con's avatar
con committed
195

196
const char *DebuggerManager::stateName(int s)
197
{
hjk's avatar
hjk committed
198
    #define SN(x) case x: return #x;
199
    switch (s) {
hjk's avatar
hjk committed
200
201
202
203
204
205
206
207
        SN(DebuggerNotReady)
        SN(EngineStarting)
        SN(AdapterStarting)
        SN(AdapterStarted)
        SN(AdapterStartFailed)
        SN(InferiorStarting)
        SN(InferiorStartFailed)
        SN(InferiorRunningRequested)
208
        SN(InferiorRunningRequested_Kill)
hjk's avatar
hjk committed
209
        SN(InferiorRunning)
210
        SN(InferiorUnrunnable)
hjk's avatar
hjk committed
211
        SN(InferiorStopping)
212
        SN(InferiorStopping_Kill)
hjk's avatar
hjk committed
213
214
215
216
217
        SN(InferiorStopped)
        SN(InferiorStopFailed)
        SN(InferiorShuttingDown)
        SN(InferiorShutDown)
        SN(InferiorShutdownFailed)
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
218
        SN(EngineShuttingDown)
219
220
    }
    return "<unknown>";
hjk's avatar
hjk committed
221
    #undef SN
222
223
}

con's avatar
con committed
224
225
226

///////////////////////////////////////////////////////////////////////
//
227
// DebuggerStartParameters
con's avatar
con committed
228
229
230
//
///////////////////////////////////////////////////////////////////////

231
232
DebuggerStartParameters::DebuggerStartParameters()
  : attachPID(-1),
233
    useTerminal(false),
hjk's avatar
hjk committed
234
235
    toolChainType(ProjectExplorer::ToolChain::UNKNOWN),
    startMode(NoStartMode)
236
{}
237
238
239

void DebuggerStartParameters::clear()
{
240
    *this = DebuggerStartParameters();
241
242
}

243
244
245
246
247
248
249

///////////////////////////////////////////////////////////////////////
//
// DebuggerManager
//
///////////////////////////////////////////////////////////////////////

250
251
static Debugger::Internal::IDebuggerEngine *gdbEngine = 0;
static Debugger::Internal::IDebuggerEngine *scriptEngine = 0;
hjk's avatar
hjk committed
252
253
static Debugger::Internal::IDebuggerEngine *cdbEngine = 0;
static Debugger::Internal::IDebuggerEngine *pdbEngine = 0;
254

255
256
struct DebuggerManagerPrivate
{
257
    explicit DebuggerManagerPrivate(DebuggerManager *manager);
258

259
260
    static DebuggerManager *instance;

con's avatar
con committed
261
262
    QIcon m_stopIcon;
    QIcon m_interruptIcon;
263
264
    const QIcon m_locationMarkIcon;

265
266
267
    // FIXME: Remove engine-specific state
    DebuggerStartParametersPtr m_startParameters;
    qint64 m_inferiorPid;
268

269
    /// Views
270
    DebuggerMainWindow *m_mainWindow;
271

272
    QLabel *m_statusLabel;
273

274
275
276
277
    QDockWidget *m_breakDock;
    QDockWidget *m_modulesDock;
    QDockWidget *m_outputDock;
    QDockWidget *m_registerDock;
278
    QDockWidget *m_snapshotDock;
279
    QDockWidget *m_sourceFilesDock;
280
    QDockWidget *m_stackDock;
281
282
    QDockWidget *m_threadsDock;
    QDockWidget *m_watchDock;
283
    QList<QDockWidget *> m_dockWidgets;
284
285
286
287

    BreakHandler *m_breakHandler;
    ModulesHandler *m_modulesHandler;
    RegisterHandler *m_registerHandler;
288
    SnapshotHandler *m_snapshotHandler;
289
290
291
292
293
294
295
296
297
298
    StackHandler *m_stackHandler;
    ThreadsHandler *m_threadsHandler;
    WatchHandler *m_watchHandler;

    DebuggerManagerActions m_actions;

    QWidget *m_breakWindow;
    QWidget *m_localsWindow;
    QWidget *m_registerWindow;
    QWidget *m_modulesWindow;
299
300
    QWidget *m_snapshotWindow;
    SourceFilesWindow *m_sourceFilesWindow;
301
302
303
304
305
306
307
308
    QWidget *m_stackWindow;
    QWidget *m_threadsWindow;
    QWidget *m_watchersWindow;
    DebuggerOutputWindow *m_outputWindow;

    bool m_busy;
    QTimer *m_statusTimer;
    QString m_lastPermanentStatusMessage;
309
    DisassemblerViewAgent m_disassemblerViewAgent;
310
311
312

    IDebuggerEngine *m_engine;
    DebuggerState m_state;
313
314

    CPlusPlus::Snapshot m_codeModelSnapshot;
315
    DebuggerPlugin *m_plugin;
316
317
};

318
319
DebuggerManager *DebuggerManagerPrivate::instance = 0;

320
DebuggerManagerPrivate::DebuggerManagerPrivate(DebuggerManager *manager) :
con's avatar
con committed
321
322
   m_stopIcon(QLatin1String(":/debugger/images/debugger_stop_small.png")),
   m_interruptIcon(QLatin1String(":/debugger/images/debugger_interrupt_small.png")),
con's avatar
con committed
323
   m_locationMarkIcon(QLatin1String(":/debugger/images/location_16.png")),
324
325
326
327
   m_startParameters(new DebuggerStartParameters),
   m_inferiorPid(0),
   m_disassemblerViewAgent(manager),
   m_engine(0)
328
{
con's avatar
con committed
329
330
    m_interruptIcon.addFile(":/debugger/images/debugger_interrupt.png");
    m_stopIcon.addFile(":/debugger/images/debugger_stop.png");
331
332
}

333
DebuggerManager::DebuggerManager(DebuggerPlugin *plugin)
334
  : d(new DebuggerManagerPrivate(this))
con's avatar
con committed
335
{
336
    DebuggerManagerPrivate::instance = this;
337
    d->m_plugin = plugin;
338
    init();
con's avatar
con committed
339
340
341
342
}

DebuggerManager::~DebuggerManager()
{
343
    #define doDelete(ptr) delete ptr; ptr = 0
344
345
346
347
348
349
350
351
352
353
354
355
356
    doDelete(scriptEngine);
    doDelete(pdbEngine);
    doDelete(gdbEngine);
    doDelete(cdbEngine);

    doDelete(d->m_breakHandler);
    doDelete(d->m_threadsHandler);
    doDelete(d->m_modulesHandler);
    doDelete(d->m_registerHandler);
    doDelete(d->m_snapshotHandler);
    doDelete(d->m_stackHandler);
    doDelete(d->m_watchHandler);

357
358
    doDelete(gdbEngine);
    doDelete(scriptEngine);
hjk's avatar
hjk committed
359
    doDelete(cdbEngine);
360
    #undef doDelete
361
    DebuggerManagerPrivate::instance = 0;
362
    delete d;
con's avatar
con committed
363
364
}

365
366
367
368
369
DebuggerManager *DebuggerManager::instance()
{
    return DebuggerManagerPrivate::instance;
}

370
void DebuggerManager::init()
con's avatar
con committed
371
{
372
373
    d->m_state = DebuggerState(-1);
    d->m_busy = false;
con's avatar
con committed
374

375
376
    d->m_modulesHandler = 0;
    d->m_registerHandler = 0;
con's avatar
con committed
377

378
379
    d->m_statusLabel = new QLabel;
    d->m_statusLabel->setMinimumSize(QSize(30, 10));
380

381
    d->m_breakWindow = new BreakWindow(this);
382
    d->m_breakWindow->setObjectName(QLatin1String("CppDebugBreakpoints"));
383
    d->m_modulesWindow = new ModulesWindow(this);
384
    d->m_modulesWindow->setObjectName(QLatin1String("CppDebugModules"));
385
    d->m_outputWindow = new DebuggerOutputWindow;
386
387
    d->m_outputWindow->setObjectName(QLatin1String("CppDebugOutput"));

388
    d->m_registerWindow = new RegisterWindow(this);
389
    d->m_registerWindow->setObjectName(QLatin1String("CppDebugRegisters"));
390
    d->m_snapshotWindow = new SnapshotWindow(this);
391
    d->m_snapshotWindow->setObjectName(QLatin1String("CppDebugSnapshots"));
392
    d->m_stackWindow = new StackWindow(this);
393
    d->m_stackWindow->setObjectName(QLatin1String("CppDebugStack"));
394
    d->m_sourceFilesWindow = new SourceFilesWindow;
395
    d->m_sourceFilesWindow->setObjectName(QLatin1String("CppDebugSources"));
396
    d->m_threadsWindow = new ThreadsWindow;
397
    d->m_threadsWindow->setObjectName(QLatin1String("CppDebugThreads"));
398
    d->m_localsWindow = new WatchWindow(WatchWindow::LocalsType, this);
399
    d->m_localsWindow->setObjectName(QLatin1String("CppDebugLocals"));
400
    d->m_watchersWindow = new WatchWindow(WatchWindow::WatchersType, this);
401
    d->m_watchersWindow->setObjectName(QLatin1String("CppDebugWatchers"));
402
    d->m_statusTimer = new QTimer(this);
con's avatar
con committed
403

404
405
    d->m_mainWindow =
        qobject_cast<DebuggerMainWindow*>(DebuggerUISwitcher::instance()->mainWindow());
406
    QTC_ASSERT(d->m_mainWindow, return)
con's avatar
con committed
407

408
409
410
411
412
413
    // Snapshots
    d->m_snapshotHandler = new SnapshotHandler;
    QAbstractItemView *snapshotView =
        qobject_cast<QAbstractItemView *>(d->m_snapshotWindow);
    snapshotView->setModel(d->m_snapshotHandler);

con's avatar
con committed
414
    // Stack
415
    d->m_stackHandler = new StackHandler;
416
417
    StackWindow *stackView =
        qobject_cast<StackWindow *>(d->m_stackWindow);
418
    stackView->setModel(d->m_stackHandler->stackModel());
419
420
421
    stackView->header()->resizeSection(0, 60);
    stackView->header()->resizeSection(3, 60);

422
423
424
425
    connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
        this, SLOT(reloadFullStack()));
    connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()),
        this, SLOT(reloadFullStack()));
con's avatar
con committed
426
427

    // Threads
428
    d->m_threadsHandler = new ThreadsHandler;
con's avatar
con committed
429
    QAbstractItemView *threadsView =
430
431
        qobject_cast<QAbstractItemView *>(d->m_threadsWindow);
    threadsView->setModel(d->m_threadsHandler->threadsModel());
con's avatar
con committed
432
433
434
435
    connect(threadsView, SIGNAL(threadSelected(int)),
        this, SLOT(selectThread(int)));

    // Breakpoints
436
    d->m_breakHandler = new BreakHandler(this);
con's avatar
con committed
437
    QAbstractItemView *breakView =
438
439
        qobject_cast<QAbstractItemView *>(d->m_breakWindow);
    breakView->setModel(d->m_breakHandler->model());
440
    connect(breakView, SIGNAL(breakpointActivated(int)),
hjk's avatar
hjk committed
441
        this, SLOT(activateBreakpoint(int)));
442
    connect(breakView, SIGNAL(breakpointDeleted(int)),
443
        d->m_breakHandler, SLOT(removeBreakpoint(int)));
444
445
    connect(breakView, SIGNAL(breakpointSynchronizationRequested()),
        this, SLOT(attemptBreakpointSynchronization()));
446
447
    connect(breakView, SIGNAL(breakByFunctionRequested(QString)),
        this, SLOT(breakByFunction(QString)), Qt::QueuedConnection);
448
449
    connect(breakView, SIGNAL(breakByFunctionMainRequested()),
        this, SLOT(breakByFunctionMain()), Qt::QueuedConnection);
con's avatar
con committed
450
451
452

    // Modules
    QAbstractItemView *modulesView =
453
454
455
        qobject_cast<QAbstractItemView *>(d->m_modulesWindow);
    d->m_modulesHandler = new ModulesHandler;
    modulesView->setModel(d->m_modulesHandler->model());
con's avatar
con committed
456
457
458
459
460
461
    connect(modulesView, SIGNAL(reloadModulesRequested()),
        this, SLOT(reloadModules()));
    connect(modulesView, SIGNAL(loadSymbolsRequested(QString)),
        this, SLOT(loadSymbols(QString)));
    connect(modulesView, SIGNAL(loadAllSymbolsRequested()),
        this, SLOT(loadAllSymbols()));
462
463
    connect(modulesView, SIGNAL(fileOpenRequested(QString)),
        this, SLOT(fileOpen(QString)));
con's avatar
con committed
464

465
    // Source Files
466
    //d->m_sourceFilesHandler = new SourceFilesHandler;
467
    QAbstractItemView *sourceFilesView =
468
469
        qobject_cast<QAbstractItemView *>(d->m_sourceFilesWindow);
    //sourceFileView->setModel(d->m_stackHandler->stackModel());
470
471
    connect(sourceFilesView, SIGNAL(reloadSourceFilesRequested()),
        this, SLOT(reloadSourceFiles()));
472
473
    connect(sourceFilesView, SIGNAL(fileOpenRequested(QString)),
        this, SLOT(fileOpen(QString)));
con's avatar
con committed
474

475
    // Registers
con's avatar
con committed
476
    QAbstractItemView *registerView =
477
478
479
        qobject_cast<QAbstractItemView *>(d->m_registerWindow);
    d->m_registerHandler = new RegisterHandler;
    registerView->setModel(d->m_registerHandler->model());
con's avatar
con committed
480

481
    // Locals
482
    d->m_watchHandler = new WatchHandler(this);
483
484
    QTreeView *localsView = qobject_cast<QTreeView *>(d->m_localsWindow);
    localsView->setModel(d->m_watchHandler->model(LocalsWatch));
485
486

    // Watchers
487
488
    QTreeView *watchersView = qobject_cast<QTreeView *>(d->m_watchersWindow);
    watchersView->setModel(d->m_watchHandler->model(WatchersWatch));
489
    connect(theDebuggerAction(AssignValue), SIGNAL(triggered()),
490
        this, SLOT(assignValueInDebugger()), Qt::QueuedConnection);
491
492
    connect(theDebuggerAction(RemoveWatchExpression), SIGNAL(triggered()),
        this, SLOT(updateWatchersWindow()), Qt::QueuedConnection);
493
494
    connect(localsView->header(), SIGNAL(sectionResized(int,int,int)),
        this, SLOT(updateWatchersHeader(int,int,int)), Qt::QueuedConnection);
con's avatar
con committed
495

496
497
498
499
500
501
    // Log
    connect(this, SIGNAL(emitShowInput(int, QString)),
            d->m_outputWindow, SLOT(showInput(int, QString)), Qt::QueuedConnection);
    connect(this, SIGNAL(emitShowOutput(int, QString)),
            d->m_outputWindow, SLOT(showOutput(int, QString)), Qt::QueuedConnection);

con's avatar
con committed
502
    // Tooltip
503
504
    //QTreeView *tooltipView = qobject_cast<QTreeView *>(d->m_tooltipWindow);
    //tooltipView->setModel(d->m_watchHandler->model(TooltipsWatch));
505
    qRegisterMetaType<WatchData>("WatchData");
hjk's avatar
hjk committed
506
    qRegisterMetaType<StackCookie>("StackCookie");
507

508
    d->m_actions.continueAction = new QAction(tr("Continue"), this);
con's avatar
con committed
509
510
511
    QIcon continueIcon = QIcon(":/debugger/images/debugger_continue_small.png");
    continueIcon.addFile(":/debugger/images/debugger_continue.png");
    d->m_actions.continueAction->setIcon(continueIcon);
con's avatar
con committed
512

513
    d->m_actions.stopAction = new QAction(tr("Interrupt"), this);
con's avatar
con committed
514
    d->m_actions.stopAction->setIcon(d->m_interruptIcon);
con's avatar
con committed
515

516
517
518
    d->m_actions.resetAction = new QAction(tr("Abort Debugging"), this);
    d->m_actions.resetAction->setToolTip(tr("Aborts debugging and "
        "resets the debugger to the initial state."));
con's avatar
con committed
519

520
    d->m_actions.nextAction = new QAction(tr("Step Over"), this);
hjk's avatar
hjk committed
521
522
    d->m_actions.nextAction->setIcon(
        QIcon(":/debugger/images/debugger_stepover_small.png"));
con's avatar
con committed
523

524
    d->m_actions.stepAction = new QAction(tr("Step Into"), this);
hjk's avatar
hjk committed
525
526
    d->m_actions.stepAction->setIcon(
        QIcon(":/debugger/images/debugger_stepinto_small.png"));
con's avatar
con committed
527

528
    d->m_actions.stepOutAction = new QAction(tr("Step Out"), this);
hjk's avatar
hjk committed
529
530
    d->m_actions.stepOutAction->setIcon(
        QIcon(":/debugger/images/debugger_stepout_small.png"));
con's avatar
con committed
531

532
533
    d->m_actions.runToLineAction1 = new QAction(tr("Run to Line"), this);
    d->m_actions.runToLineAction2 = new QAction(tr("Run to Line"), this);
con's avatar
con committed
534

535
536
537
538
539
    d->m_actions.runToFunctionAction =
        new QAction(tr("Run to Outermost Function"), this);

    d->m_actions.returnFromFunctionAction =
        new QAction(tr("Immediately Return From Inner Function"), this);
con's avatar
con committed
540

541
542
    d->m_actions.jumpToLineAction1 = new QAction(tr("Jump to Line"), this);
    d->m_actions.jumpToLineAction2 = new QAction(tr("Jump to Line"), this);
con's avatar
con committed
543

544
    d->m_actions.breakAction = new QAction(tr("Toggle Breakpoint"), this);
con's avatar
con committed
545

546
547
    d->m_actions.watchAction1 = new QAction(tr("Add to Watch Window"), this);
    d->m_actions.watchAction2 = new QAction(tr("Add to Watch Window"), this);
con's avatar
con committed
548

549
    d->m_actions.snapshotAction = new QAction(tr("Snapshot"), this);
hjk's avatar
hjk committed
550
551
    d->m_actions.snapshotAction->setIcon(
        QIcon(":/debugger/images/debugger_snapshot_small.png"));
552

hjk's avatar
hjk committed
553
554
    d->m_actions.reverseDirectionAction =
        new QAction(tr("Reverse Direction"), this);
555
556
    d->m_actions.reverseDirectionAction->setCheckable(true);
    d->m_actions.reverseDirectionAction->setChecked(false);
hjk's avatar
hjk committed
557
    d->m_actions.reverseDirectionAction->setIcon(
hjk's avatar
hjk committed
558
        QIcon(":/debugger/images/debugger_reversemode_16.png"));
559

560
    connect(d->m_actions.continueAction, SIGNAL(triggered()),
hjk's avatar
hjk committed
561
        this, SLOT(executeContinue()));
562
    connect(d->m_actions.stopAction, SIGNAL(triggered()),
con's avatar
con committed
563
        this, SLOT(interruptDebuggingRequest()));
564
    connect(d->m_actions.resetAction, SIGNAL(triggered()),
565
        this, SLOT(abortDebugger()));
566
    connect(d->m_actions.nextAction, SIGNAL(triggered()),
hjk's avatar
hjk committed
567
        this, SLOT(executeStepNext()));
568
    connect(d->m_actions.stepAction, SIGNAL(triggered()),
hjk's avatar
hjk committed
569
        this, SLOT(executeStep()));
570
    connect(d->m_actions.stepOutAction, SIGNAL(triggered()),
hjk's avatar
hjk committed
571
        this, SLOT(executeStepOut()));
572
    connect(d->m_actions.runToLineAction1, SIGNAL(triggered()),
hjk's avatar
hjk committed
573
        this, SLOT(executeRunToLine()));
574
    connect(d->m_actions.runToLineAction2, SIGNAL(triggered()),
hjk's avatar
hjk committed
575
        this, SLOT(executeRunToLine()));
576
    connect(d->m_actions.runToFunctionAction, SIGNAL(triggered()),
hjk's avatar
hjk committed
577
        this, SLOT(executeRunToFunction()));
578
    connect(d->m_actions.jumpToLineAction1, SIGNAL(triggered()),
hjk's avatar
hjk committed
579
        this, SLOT(executeJumpToLine()));
580
    connect(d->m_actions.jumpToLineAction2, SIGNAL(triggered()),
hjk's avatar
hjk committed
581
        this, SLOT(executeJumpToLine()));
582
    connect(d->m_actions.returnFromFunctionAction, SIGNAL(triggered()),
hjk's avatar
hjk committed
583
        this, SLOT(executeReturn()));
584
585
586
    connect(d->m_actions.watchAction1, SIGNAL(triggered()),
        this, SLOT(addToWatchWindow()));
    connect(d->m_actions.watchAction2, SIGNAL(triggered()),
con's avatar
con committed
587
        this, SLOT(addToWatchWindow()));
588
589
    connect(d->m_actions.snapshotAction, SIGNAL(triggered()),
        this, SLOT(makeSnapshot()));
con's avatar
con committed
590

591
    connect(d->m_statusTimer, SIGNAL(timeout()),
592
        this, SLOT(clearStatusMessage()));
con's avatar
con committed
593

594
595
    connect(theDebuggerAction(ExecuteCommand), SIGNAL(triggered()),
        this, SLOT(executeDebuggerCommand()));
596

597
598
    connect(theDebuggerAction(WatchPoint), SIGNAL(triggered()),
        this, SLOT(watchPoint()));
con's avatar
con committed
599

600
601
    connect(theDebuggerAction(OperateByInstruction), SIGNAL(triggered()),
        this, SLOT(operateByInstructionTriggered()));
602

603
604
605
    DebuggerUISwitcher *uiSwitcher = DebuggerUISwitcher::instance();
    d->m_breakDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_breakWindow);
    d->m_modulesDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_modulesWindow,
hjk's avatar
hjk committed
606
                                                    Qt::TopDockWidgetArea, false);
607

608
    connect(d->m_modulesDock->toggleViewAction(), SIGNAL(toggled(bool)),
con's avatar
con committed
609
610
        this, SLOT(reloadModules()), Qt::QueuedConnection);

611
    d->m_registerDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_registerWindow,
612
        Qt::TopDockWidgetArea, false);
613
    connect(d->m_registerDock->toggleViewAction(), SIGNAL(toggled(bool)),
con's avatar
con committed
614
615
        this, SLOT(reloadRegisters()), Qt::QueuedConnection);

616
    d->m_outputDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_outputWindow,
617
        Qt::TopDockWidgetArea, false);
618

619
620
    d->m_snapshotDock =  uiSwitcher->createDockWidget(LANG_CPP, d->m_snapshotWindow);
    d->m_stackDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_stackWindow);
621
622
    d->m_sourceFilesDock = uiSwitcher->createDockWidget(LANG_CPP,
        d->m_sourceFilesWindow, Qt::TopDockWidgetArea, false);
623
    connect(d->m_sourceFilesDock->toggleViewAction(), SIGNAL(toggled(bool)),
624
625
        this, SLOT(reloadSourceFiles()), Qt::QueuedConnection);

626
    d->m_threadsDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_threadsWindow);
con's avatar
con committed
627

628
    QSplitter *localsAndWatchers = new Core::MiniSplitter(Qt::Vertical);
629
    localsAndWatchers->setObjectName(QLatin1String("CppDebugLocalsAndWatchers"));
630
631
632
633
    localsAndWatchers->setWindowTitle(d->m_localsWindow->windowTitle());
    localsAndWatchers->addWidget(d->m_localsWindow);
    localsAndWatchers->addWidget(d->m_watchersWindow);
    //localsAndWatchers->addWidget(d->m_tooltipWindow);
634
635
    localsAndWatchers->setStretchFactor(0, 3);
    localsAndWatchers->setStretchFactor(1, 1);
636
    localsAndWatchers->setStretchFactor(2, 1);
637
638
    d->m_watchDock = DebuggerUISwitcher::instance()->createDockWidget(LANG_CPP,
        localsAndWatchers);
639
640
641
    d->m_dockWidgets << d->m_breakDock << d->m_modulesDock << d->m_registerDock
                     << d->m_outputDock << d->m_stackDock << d->m_sourceFilesDock
                     << d->m_threadsDock << d->m_watchDock;
642

hjk's avatar
hjk committed
643
    setState(DebuggerNotReady);
644
645
}

646
QList<Core::IOptionsPage*> DebuggerManager::initializeEngines(unsigned enabledTypeFlags)
647
648
{
    QList<Core::IOptionsPage*> rc;
649

650
651
652
653
    if (enabledTypeFlags & GdbEngineType) {
        gdbEngine = createGdbEngine(this);
        gdbEngine->addOptionPages(&rc);
    }
654

hjk's avatar
hjk committed
655
    cdbEngine = createCdbEngine(this, (enabledTypeFlags & CdbEngineType), &rc);
656
657
658
659
660
661

    if (enabledTypeFlags & ScriptEngineType) {
        scriptEngine = createScriptEngine(this);
        scriptEngine->addOptionPages(&rc);
    }

hjk's avatar
hjk committed
662
663
664
    if (enabledTypeFlags & PdbEngineType) {
        pdbEngine = createPdbEngine(this);
        //pdbEngine->addOptionPages(&rc);
hjk's avatar
hjk committed
665
666
    }

667
    d->m_engine = 0;
hjk's avatar
hjk committed
668
669
    STATE_DEBUG(gdbEngine << cdbEngine << scriptEngine
        << pdbEngine << rc.size());
670
    return rc;
con's avatar
con committed
671
672
}

673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
DebuggerManagerActions DebuggerManager::debuggerManagerActions() const
{
    return d->m_actions;
}

QLabel *DebuggerManager::statusLabel() const
{
    return d->m_statusLabel;
}

IDebuggerEngine *DebuggerManager::currentEngine() const
{
    return d->m_engine;
}

ModulesHandler *DebuggerManager::modulesHandler() const
{
    return d->m_modulesHandler;
}

BreakHandler *DebuggerManager::breakHandler() const
{
    return d->m_breakHandler;
}

RegisterHandler *DebuggerManager::registerHandler() const
{
    return d->m_registerHandler;
}

StackHandler *DebuggerManager::stackHandler() const
{
    return d->m_stackHandler;
}

ThreadsHandler *DebuggerManager::threadsHandler() const
{
    return d->m_threadsHandler;
}

WatchHandler *DebuggerManager::watchHandler() const
{
    return d->m_watchHandler;
}

718
719
720
721
722
SnapshotHandler *DebuggerManager::snapshotHandler() const
{
    return d->m_snapshotHandler;
}

723
724
725
726
727
728
729
730
731
const CPlusPlus::Snapshot &DebuggerManager::cppCodeModelSnapshot() const
{
    if (d->m_codeModelSnapshot.isEmpty() && theDebuggerAction(UseCodeModel)->isChecked())
        d->m_codeModelSnapshot = CppTools::CppModelManagerInterface::instance()->snapshot();
    return d->m_codeModelSnapshot;
}

void DebuggerManager::clearCppCodeModelSnapshot()
{
732
    d->m_codeModelSnapshot = CPlusPlus::Snapshot();
733
734
}

735
736
737
738
739
740
SourceFilesWindow *DebuggerManager::sourceFileWindow() const
{
    return d->m_sourceFilesWindow;
}

QWidget *DebuggerManager::threadsWindow() const
con's avatar
con committed
741
{
742
    return d->m_threadsWindow;
con's avatar
con committed
743
744
}

hjk's avatar
hjk committed
745
746
void DebuggerManager::createNewDock(QWidget *widget)
{
747
748
    QDockWidget *dockWidget =
        DebuggerUISwitcher::instance()->createDockWidget(LANG_CPP, widget);
749
    dockWidget->setWindowTitle(widget->windowTitle());
hjk's avatar
hjk committed
750
751
    dockWidget->setObjectName(widget->windowTitle());
    dockWidget->setFeatures(QDockWidget::DockWidgetClosable);
752
753
    //dockWidget->setWidget(widget);
    //d->m_mainWindow->addDockWidget(Qt::TopDockWidgetArea, dockWidget);
hjk's avatar
hjk committed
754
755
756
    dockWidget->show();
}

757
void DebuggerManager::setSimpleDockWidgetArrangement(const QString &activeLanguage)
con's avatar
con committed
758
{
hjk's avatar
hjk committed
759
    if (activeLanguage == LANG_CPP || activeLanguage.isEmpty()) {
760
761
762
763
764
765
766
767
        d->m_mainWindow->setTrackingEnabled(false);
        QList<QDockWidget *> dockWidgets = d->m_mainWindow->dockWidgets();
        foreach (QDockWidget *dockWidget, dockWidgets) {
            if (d->m_dockWidgets.contains(dockWidget)) {
                dockWidget->setFloating(false);
                d->m_mainWindow->removeDockWidget(dockWidget);
            }
        }
con's avatar
con committed
768

769
770
771
772
773
774
775
776
777
        foreach (QDockWidget *dockWidget, dockWidgets) {
            if (d->m_dockWidgets.contains(dockWidget)) {
                if (dockWidget == d->m_outputDock)
                    d->m_mainWindow->addDockWidget(Qt::TopDockWidgetArea, dockWidget);
                else
                    d->m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
                dockWidget->show();
            }
        }
con's avatar
con committed
778

779
780
781
782
783
784
785
786
787
788
789
790
791
792
        d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_breakDock);
        d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_modulesDock);
        d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_registerDock);
        d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_threadsDock);
        d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_sourceFilesDock);
        d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_snapshotDock);
        // They following views are rarely used in ordinary debugging. Hiding them
        // saves cycles since the corresponding information won't be retrieved.
        d->m_sourceFilesDock->hide();
        d->m_registerDock->hide();
        d->m_modulesDock->hide();
        d->m_outputDock->hide();
        d->m_mainWindow->setTrackingEnabled(true);
    }
con's avatar
con committed
793
794
795
796
}

QAbstractItemModel *DebuggerManager::threadsModel()
{
797
    return qobject_cast<ThreadsWindow*>(d->m_threadsWindow)->model();
con's avatar
con committed
798
799
}

800
801
void DebuggerManager::clearStatusMessage()
{
802
    d->m_statusLabel->setText(d->m_lastPermanentStatusMessage);
803
804
}

805
void DebuggerManager::showStatusMessage(const QString &msg0, int timeout)
con's avatar
con committed
806
807
{
    Q_UNUSED(timeout)
808
809
810
    showDebuggerOutput(LogStatus, msg0);
    QString msg = msg0;
    msg.replace(QLatin1Char('\n'), QString());
811
    d->m_statusLabel->setText(msg);
812
    if (timeout > 0) {
813
814
        d->m_statusTimer->setSingleShot(true);
        d->m_statusTimer->start(timeout);
815
    } else {
816
817
        d->m_lastPermanentStatusMessage = msg;
        d->m_statusTimer->stop();
818
    }
con's avatar
con committed
819
820
821
822
}

void DebuggerManager::notifyInferiorStopped()
{
hjk's avatar
hjk committed
823
    setState(InferiorStopped);
824
    showStatusMessage(tr("Stopped"), 5000);
con's avatar
con committed
825
826
827
828
}

void DebuggerManager::notifyInferiorRunning()
{
hjk's avatar
hjk committed
829
    setState(InferiorRunning);
con's avatar
con committed
830
831
832
833
834
    showStatusMessage(tr("Running..."), 5000);
}

void DebuggerManager::notifyInferiorExited()
{
hjk's avatar
hjk committed
835
    setState(DebuggerNotReady);
836
    showStatusMessage(tr("Exited"), 5000);
con's avatar
con committed
837
838
}

839
void DebuggerManager::notifyInferiorPidChanged(qint64 pid)
con's avatar
con committed
840
{
841
    STATE_DEBUG(d->m_inferiorPid << pid);
842

843
844
    if (d->m_inferiorPid != pid) {
        d->m_inferiorPid = pid;
845
846
        emit inferiorPidChanged(pid);
    }
con's avatar
con committed
847
848
}

849
void DebuggerManager::showApplicationOutput(const QString &str, bool onStdErr)
con's avatar
con committed
850
{