debuggermanager.cpp 65.5 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
101
#include <QtGui/QStatusBar>
#include <QtGui/QTextBlock>
#include <QtGui/QTextCursor>
#include <QtGui/QToolButton>
#include <QtGui/QToolTip>

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

112
113
// 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
114
115
// whereas the debugged process is referred to as 'Inferior'.
//
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
116
//              0 == DebuggerNotReady
hjk's avatar
hjk committed
117
//                          |
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
118
//                    EngineStarting
hjk's avatar
hjk committed
119
//                          |
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
120
//                    AdapterStarting --> AdapterStartFailed --> 0
hjk's avatar
hjk committed
121
//                          |
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//                    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
145
146
//                          |
//                          0
hjk's avatar
hjk committed
147
148
149
150
151
152
//
// Allowed actions:
//    [R] :  Run
//    [C] :  Continue
//    [N] :  Step, Next

153
154
namespace Debugger {
namespace Internal {
155

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

hjk's avatar
hjk committed
160
// The createCdbEngine function takes a list of options pages it can add to.
161
162
163
// 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.
164

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

172
} // namespace Internal
173

174
DEBUGGER_EXPORT QDebug operator<<(QDebug str, const DebuggerStartParameters &p)
175
176
177
178
179
180
181
182
183
184
{
    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
185
            << " symbolFileName=" << p.symbolFileName
186
187
            << " serverStartScript=" << p.serverStartScript
            << " toolchain=" << p.toolChainType << '\n';
188
189
190
    return str;
}

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

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

con's avatar
con committed
223
224
225

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

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

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

242
243
244
245
246
247
248

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

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

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

258
259
    static DebuggerManager *instance;

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

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

268
    /// Views
269
    DebuggerMainWindow *m_mainWindow;
270

271
    QLabel *m_statusLabel;
272

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

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

    DebuggerManagerActions m_actions;

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

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

    IDebuggerEngine *m_engine;
    DebuggerState m_state;
312
313

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

317
318
DebuggerManager *DebuggerManagerPrivate::instance = 0;

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

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

DebuggerManager::~DebuggerManager()
{
342
    #define doDelete(ptr) delete ptr; ptr = 0
343
344
345
346
347
348
349
350
351
352
353
354
355
    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);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

497
498
499
500
501
502
    // 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
503
    // Tooltip
504
505
    //QTreeView *tooltipView = qobject_cast<QTreeView *>(d->m_tooltipWindow);
    //tooltipView->setModel(d->m_watchHandler->model(TooltipsWatch));
506
    qRegisterMetaType<WatchData>("WatchData");
hjk's avatar
hjk committed
507
    qRegisterMetaType<StackCookie>("StackCookie");
508

509
    d->m_actions.continueAction = new QAction(tr("Continue"), this);
con's avatar
con committed
510
511
512
    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
513

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

517
518
519
    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
520

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

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

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

533
534
    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
535

536
537
538
539
540
    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
541

542
543
    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
544

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

547
548
    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
549

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

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

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

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

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

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

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

604
605
606
    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
607
                                                    Qt::TopDockWidgetArea, false);
608

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

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

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

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

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

629
    QSplitter *localsAndWatchers = new Core::MiniSplitter(Qt::Vertical);
630
    localsAndWatchers->setObjectName(QLatin1String("CppDebugLocalsAndWatchers"));
631
632
633
634
    localsAndWatchers->setWindowTitle(d->m_localsWindow->windowTitle());
    localsAndWatchers->addWidget(d->m_localsWindow);
    localsAndWatchers->addWidget(d->m_watchersWindow);
    //localsAndWatchers->addWidget(d->m_tooltipWindow);
635
636
    localsAndWatchers->setStretchFactor(0, 3);
    localsAndWatchers->setStretchFactor(1, 1);
637
    localsAndWatchers->setStretchFactor(2, 1);
638
639
    d->m_watchDock = DebuggerUISwitcher::instance()->createDockWidget(LANG_CPP,
        localsAndWatchers);
640
641
642
    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;
643

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

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

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

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

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

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

668
    d->m_engine = 0;
hjk's avatar
hjk committed
669
670
    STATE_DEBUG(gdbEngine << cdbEngine << scriptEngine
        << pdbEngine << rc.size());
671
    return rc;
con's avatar
con committed
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
718
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;
}

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

724
725
726
727
728
729
730
731
732
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()
{
733
    d->m_codeModelSnapshot = CPlusPlus::Snapshot();
734
735
}

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

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

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

758
void DebuggerManager::setSimpleDockWidgetArrangement(const QString &activeLanguage)
con's avatar
con committed
759
{
hjk's avatar
hjk committed
760
    if (activeLanguage == LANG_CPP || activeLanguage.isEmpty()) {
761
762
763
764
765
766
767
768
        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
769

770
771
772
773
774
775
776
777
778
        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
779

780
781
782
783
784
785
786
787
788
789
790
791
792
793
        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
794
795
796
797
}

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

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

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

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

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

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

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

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

850
void DebuggerManager::showApplicationOutput(const QString &str, bool onStdErr)
con's avatar
con committed
851
{
852
     emit applicationOutputAvailable(str, onStdErr);
con's avatar
con committed
853
854
}

855
void DebuggerManager::aboutToShutdown()
con's avatar
con committed
856
{
857
858
859
860
    STATE_DEBUG(d->m_engine);
    if (d->m_engine)
        d->m_engine->shutdown();
    d->m_engine = 0;
con's avatar
con committed
861
862
}

863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
void DebuggerManager::makeSnapshot()
{
    QTC_ASSERT(d->m_engine, return);
    d->m_engine->makeSnapshot();
}

void DebuggerManager::activateSnapshot(int index)
{
    QTC_ASSERT(d->m_engine, return);
    d->m_engine->activateSnapshot(index);
}

void DebuggerManager::removeSnapshot(int index)
{
    QTC_ASSERT(d->m_engine, return);
    d->m_snapshotHandler->removeSnapshot(index);
}

881
882
BreakpointData *DebuggerManager::findBreakpoint(const QString &fileName, int lineNumber)
{
883
    if (!d->m_breakHandler)
884
        return 0;
885
886