debuggermanager.cpp 66.4 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 "debuggeractions.h"
33
#include "debuggeragents.h"
con's avatar
con committed
34
#include "debuggerconstants.h"
35
36
37
#include "debuggermainwindow.h"
#include "debuggerplugin.h"
#include "debuggerrunner.h"
38
#include "debuggerstringutils.h"
39
#include "debuggertooltip.h"
40
#include "debuggeruiswitcher.h"
41
42
#include "idebuggerengine.h"
#include "watchutils.h"
con's avatar
con committed
43
44
45
46
47

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

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

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

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

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

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

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

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

156
157
namespace Debugger {
namespace Internal {
158

159
160
IDebuggerEngine *createGdbEngine(DebuggerManager *parent);
IDebuggerEngine *createScriptEngine(DebuggerManager *parent);
hjk's avatar
hjk committed
161
IDebuggerEngine *createPdbEngine(DebuggerManager *parent);
hjk's avatar
hjk committed
162
IDebuggerEngine *createTcfEngine(DebuggerManager *parent);
163
IDebuggerEngine *createQmlEngine(DebuggerManager *parent);
164

hjk's avatar
hjk committed
165
// The createCdbEngine function takes a list of options pages it can add to.
166
167
168
// 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.
169

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

177
} // namespace Internal
178

179
DEBUGGER_EXPORT QDebug operator<<(QDebug str, const DebuggerStartParameters &p)
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>"
186
            << " workingDir=" << p.workingDirectory << " buildDir=" << p.buildDirectory
187
188
189
            << " attachPID=" << p.attachPID << " useTerminal=" << p.useTerminal
            << " remoteChannel=" << p.remoteChannel
            << " remoteArchitecture=" << p.remoteArchitecture
190
            << " symbolFileName=" << p.symbolFileName
191
192
            << " serverStartScript=" << p.serverStartScript
            << " toolchain=" << p.toolChainType << '\n';
193
194
195
    return str;
}

196
using namespace Constants;
197
using namespace Debugger::Internal;
198
using namespace TextEditor;
con's avatar
con committed
199

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

con's avatar
con committed
228
229
230

///////////////////////////////////////////////////////////////////////
//
231
// DebuggerStartParameters
con's avatar
con committed
232
233
234
//
///////////////////////////////////////////////////////////////////////

235
236
DebuggerStartParameters::DebuggerStartParameters()
  : attachPID(-1),
237
    useTerminal(false),
hjk's avatar
hjk committed
238
239
    toolChainType(ProjectExplorer::ToolChain::UNKNOWN),
    startMode(NoStartMode)
240
{}
241
242
243

void DebuggerStartParameters::clear()
{
244
    *this = DebuggerStartParameters();
245
246
}

247
248
249
250
251
252
253

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

254
255
static Debugger::Internal::IDebuggerEngine *gdbEngine = 0;
static Debugger::Internal::IDebuggerEngine *scriptEngine = 0;
hjk's avatar
hjk committed
256
257
static Debugger::Internal::IDebuggerEngine *cdbEngine = 0;
static Debugger::Internal::IDebuggerEngine *pdbEngine = 0;
258
static Debugger::Internal::IDebuggerEngine *qmlEngine = 0;
hjk's avatar
hjk committed
259
static Debugger::Internal::IDebuggerEngine *tcfEngine = 0;
260

261
262
struct DebuggerManagerPrivate
{
263
    explicit DebuggerManagerPrivate(DebuggerManager *manager);
264

265
266
    static DebuggerManager *instance;

con's avatar
con committed
267
268
    QIcon m_stopIcon;
    QIcon m_interruptIcon;
269
270
    const QIcon m_locationMarkIcon;

271
272
273
    // FIXME: Remove engine-specific state
    DebuggerStartParametersPtr m_startParameters;
    qint64 m_inferiorPid;
274

275
    /// Views
276
    DebuggerMainWindow *m_mainWindow;
277

278
    QLabel *m_statusLabel;
279

280
281
282
283
    QDockWidget *m_breakDock;
    QDockWidget *m_modulesDock;
    QDockWidget *m_outputDock;
    QDockWidget *m_registerDock;
284
    QDockWidget *m_snapshotDock;
285
    QDockWidget *m_sourceFilesDock;
286
    QDockWidget *m_stackDock;
287
288
    QDockWidget *m_threadsDock;
    QDockWidget *m_watchDock;
289
    QList<QDockWidget *> m_dockWidgets;
290
291
292
293

    BreakHandler *m_breakHandler;
    ModulesHandler *m_modulesHandler;
    RegisterHandler *m_registerHandler;
294
    SnapshotHandler *m_snapshotHandler;
295
296
297
298
299
300
301
    StackHandler *m_stackHandler;
    ThreadsHandler *m_threadsHandler;
    WatchHandler *m_watchHandler;

    DebuggerManagerActions m_actions;

    QWidget *m_breakWindow;
302
    QWidget *m_returnWindow;
303
    QWidget *m_localsWindow;
304
    QWidget *m_watchersWindow;
305
306
    QWidget *m_registerWindow;
    QWidget *m_modulesWindow;
307
308
    QWidget *m_snapshotWindow;
    SourceFilesWindow *m_sourceFilesWindow;
309
310
311
312
313
314
315
    QWidget *m_stackWindow;
    QWidget *m_threadsWindow;
    DebuggerOutputWindow *m_outputWindow;

    bool m_busy;
    QTimer *m_statusTimer;
    QString m_lastPermanentStatusMessage;
316
    DisassemblerViewAgent m_disassemblerViewAgent;
317
318
319

    IDebuggerEngine *m_engine;
    DebuggerState m_state;
320
321

    CPlusPlus::Snapshot m_codeModelSnapshot;
322
    DebuggerPlugin *m_plugin;
323
324
};

325
326
DebuggerManager *DebuggerManagerPrivate::instance = 0;

327
DebuggerManagerPrivate::DebuggerManagerPrivate(DebuggerManager *manager) :
con's avatar
con committed
328
329
   m_stopIcon(QLatin1String(":/debugger/images/debugger_stop_small.png")),
   m_interruptIcon(QLatin1String(":/debugger/images/debugger_interrupt_small.png")),
con's avatar
con committed
330
   m_locationMarkIcon(QLatin1String(":/debugger/images/location_16.png")),
331
332
333
334
   m_startParameters(new DebuggerStartParameters),
   m_inferiorPid(0),
   m_disassemblerViewAgent(manager),
   m_engine(0)
335
{
con's avatar
con committed
336
337
    m_interruptIcon.addFile(":/debugger/images/debugger_interrupt.png");
    m_stopIcon.addFile(":/debugger/images/debugger_stop.png");
338
339
}

340
DebuggerManager::DebuggerManager(DebuggerPlugin *plugin)
341
  : d(new DebuggerManagerPrivate(this))
con's avatar
con committed
342
{
343
    DebuggerManagerPrivate::instance = this;
344
    d->m_plugin = plugin;
345
    init();
con's avatar
con committed
346
347
348
349
}

DebuggerManager::~DebuggerManager()
{
Tobias Hunger's avatar
Tobias Hunger committed
350
#    define doDelete(ptr) delete ptr; ptr = 0
351
352
353
354
    doDelete(scriptEngine);
    doDelete(pdbEngine);
    doDelete(gdbEngine);
    doDelete(cdbEngine);
hjk's avatar
hjk committed
355
    doDelete(tcfEngine);
356
    doDelete(qmlEngine);
357
358
359
360
361
362
363
364

    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);
Tobias Hunger's avatar
Tobias Hunger committed
365
#    undef doDelete
366
    DebuggerManagerPrivate::instance = 0;
367
    delete d;
con's avatar
con committed
368
369
}

370
371
372
373
374
DebuggerManager *DebuggerManager::instance()
{
    return DebuggerManagerPrivate::instance;
}

375
void DebuggerManager::init()
con's avatar
con committed
376
{
377
378
    d->m_state = DebuggerState(-1);
    d->m_busy = false;
con's avatar
con committed
379

380
381
    d->m_modulesHandler = 0;
    d->m_registerHandler = 0;
con's avatar
con committed
382

383
384
    d->m_statusLabel = new QLabel;
    d->m_statusLabel->setMinimumSize(QSize(30, 10));
385

386
    d->m_breakWindow = new BreakWindow(this);
387
    d->m_breakWindow->setObjectName(QLatin1String("CppDebugBreakpoints"));
388
    d->m_modulesWindow = new ModulesWindow(this);
389
    d->m_modulesWindow->setObjectName(QLatin1String("CppDebugModules"));
390
    d->m_outputWindow = new DebuggerOutputWindow;
391
392
    d->m_outputWindow->setObjectName(QLatin1String("CppDebugOutput"));

393
    d->m_registerWindow = new RegisterWindow(this);
394
    d->m_registerWindow->setObjectName(QLatin1String("CppDebugRegisters"));
395
    d->m_snapshotWindow = new SnapshotWindow(this);
396
    d->m_snapshotWindow->setObjectName(QLatin1String("CppDebugSnapshots"));
397
    d->m_stackWindow = new StackWindow(this);
398
    d->m_stackWindow->setObjectName(QLatin1String("CppDebugStack"));
399
    d->m_sourceFilesWindow = new SourceFilesWindow;
400
    d->m_sourceFilesWindow->setObjectName(QLatin1String("CppDebugSources"));
401
    d->m_threadsWindow = new ThreadsWindow;
402
    d->m_threadsWindow->setObjectName(QLatin1String("CppDebugThreads"));
403
404
    d->m_returnWindow = new WatchWindow(WatchWindow::ReturnType, this);
    d->m_returnWindow->setObjectName(QLatin1String("CppDebugReturn"));
405
    d->m_localsWindow = new WatchWindow(WatchWindow::LocalsType, this);
406
    d->m_localsWindow->setObjectName(QLatin1String("CppDebugLocals"));
407
    d->m_watchersWindow = new WatchWindow(WatchWindow::WatchersType, this);
408
    d->m_watchersWindow->setObjectName(QLatin1String("CppDebugWatchers"));
409
    d->m_statusTimer = new QTimer(this);
con's avatar
con committed
410

411
412
    d->m_mainWindow =
        qobject_cast<DebuggerMainWindow*>(DebuggerUISwitcher::instance()->mainWindow());
413
    QTC_ASSERT(d->m_mainWindow, return)
con's avatar
con committed
414

415
416
417
418
419
420
    // Snapshots
    d->m_snapshotHandler = new SnapshotHandler;
    QAbstractItemView *snapshotView =
        qobject_cast<QAbstractItemView *>(d->m_snapshotWindow);
    snapshotView->setModel(d->m_snapshotHandler);

con's avatar
con committed
421
    // Stack
422
    d->m_stackHandler = new StackHandler;
423
424
    StackWindow *stackView =
        qobject_cast<StackWindow *>(d->m_stackWindow);
425
    stackView->setModel(d->m_stackHandler->stackModel());
426
427
428
    stackView->header()->resizeSection(0, 60);
    stackView->header()->resizeSection(3, 60);

429
430
431
432
    connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
        this, SLOT(reloadFullStack()));
    connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()),
        this, SLOT(reloadFullStack()));
con's avatar
con committed
433
434

    // Threads
435
    d->m_threadsHandler = new ThreadsHandler;
con's avatar
con committed
436
    QAbstractItemView *threadsView =
437
438
        qobject_cast<QAbstractItemView *>(d->m_threadsWindow);
    threadsView->setModel(d->m_threadsHandler->threadsModel());
con's avatar
con committed
439
440
441
442
    connect(threadsView, SIGNAL(threadSelected(int)),
        this, SLOT(selectThread(int)));

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

    // Modules
    QAbstractItemView *modulesView =
460
461
462
        qobject_cast<QAbstractItemView *>(d->m_modulesWindow);
    d->m_modulesHandler = new ModulesHandler;
    modulesView->setModel(d->m_modulesHandler->model());
con's avatar
con committed
463
464
465
466
467
468
    connect(modulesView, SIGNAL(reloadModulesRequested()),
        this, SLOT(reloadModules()));
    connect(modulesView, SIGNAL(loadSymbolsRequested(QString)),
        this, SLOT(loadSymbols(QString)));
    connect(modulesView, SIGNAL(loadAllSymbolsRequested()),
        this, SLOT(loadAllSymbols()));
469
470
    connect(modulesView, SIGNAL(fileOpenRequested(QString)),
        this, SLOT(fileOpen(QString)));
con's avatar
con committed
471

472
    // Source Files
473
    //d->m_sourceFilesHandler = new SourceFilesHandler;
474
    QAbstractItemView *sourceFilesView =
475
476
        qobject_cast<QAbstractItemView *>(d->m_sourceFilesWindow);
    //sourceFileView->setModel(d->m_stackHandler->stackModel());
477
478
    connect(sourceFilesView, SIGNAL(reloadSourceFilesRequested()),
        this, SLOT(reloadSourceFiles()));
479
480
    connect(sourceFilesView, SIGNAL(fileOpenRequested(QString)),
        this, SLOT(fileOpen(QString)));
con's avatar
con committed
481

482
    // Registers
con's avatar
con committed
483
    QAbstractItemView *registerView =
484
485
486
        qobject_cast<QAbstractItemView *>(d->m_registerWindow);
    d->m_registerHandler = new RegisterHandler;
    registerView->setModel(d->m_registerHandler->model());
con's avatar
con committed
487

488
489

    // Return Value
490
    d->m_watchHandler = new WatchHandler(this);
491
492
493
494
    QTreeView *returnView = qobject_cast<QTreeView *>(d->m_returnWindow);
    returnView->setModel(d->m_watchHandler->model(ReturnWatch));

    // Locals
495
496
    QTreeView *localsView = qobject_cast<QTreeView *>(d->m_localsWindow);
    localsView->setModel(d->m_watchHandler->model(LocalsWatch));
497
498

    // Watchers
499
500
    QTreeView *watchersView = qobject_cast<QTreeView *>(d->m_watchersWindow);
    watchersView->setModel(d->m_watchHandler->model(WatchersWatch));
501
    connect(theDebuggerAction(AssignValue), SIGNAL(triggered()),
502
        this, SLOT(assignValueInDebugger()), Qt::QueuedConnection);
503
504
    connect(theDebuggerAction(RemoveWatchExpression), SIGNAL(triggered()),
        this, SLOT(updateWatchersWindow()), Qt::QueuedConnection);
505
506
    connect(localsView->header(), SIGNAL(sectionResized(int,int,int)),
        this, SLOT(updateWatchersHeader(int,int,int)), Qt::QueuedConnection);
con's avatar
con committed
507

508
509
510
511
512
513
    // 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
514
    // Tooltip
515
    qRegisterMetaType<WatchData>("WatchData");
hjk's avatar
hjk committed
516
    qRegisterMetaType<StackCookie>("StackCookie");
517

518
    d->m_actions.continueAction = new QAction(tr("Continue"), this);
con's avatar
con committed
519
520
521
    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
522

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

526
527
528
    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
529

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

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

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

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

545
546
547
548
549
    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
550

551
552
    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
553

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

556
557
    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
558

559
    d->m_actions.snapshotAction = new QAction(tr("Snapshot"), this);
hjk's avatar
hjk committed
560
561
    d->m_actions.snapshotAction->setIcon(
        QIcon(":/debugger/images/debugger_snapshot_small.png"));
562

hjk's avatar
hjk committed
563
564
    d->m_actions.reverseDirectionAction =
        new QAction(tr("Reverse Direction"), this);
565
566
    d->m_actions.reverseDirectionAction->setCheckable(true);
    d->m_actions.reverseDirectionAction->setChecked(false);
hjk's avatar
hjk committed
567
    d->m_actions.reverseDirectionAction->setIcon(
hjk's avatar
hjk committed
568
        QIcon(":/debugger/images/debugger_reversemode_16.png"));
569

570
571
572
573
574
575
    d->m_actions.frameDownAction =
        new QAction(tr("Move to Called Frame"), this);
    d->m_actions.frameUpAction =
        new QAction(tr("Move to Calling Frame"), this);

    d->m_actions.reverseDirectionAction->setCheckable(false);
576
    connect(d->m_actions.continueAction, SIGNAL(triggered()),
hjk's avatar
hjk committed
577
        this, SLOT(executeContinue()));
578
    connect(d->m_actions.stopAction, SIGNAL(triggered()),
con's avatar
con committed
579
        this, SLOT(interruptDebuggingRequest()));
580
    connect(d->m_actions.resetAction, SIGNAL(triggered()),
581
        this, SLOT(abortDebugger()));
582
    connect(d->m_actions.nextAction, SIGNAL(triggered()),
hjk's avatar
hjk committed
583
        this, SLOT(executeStepNext()));
584
    connect(d->m_actions.stepAction, SIGNAL(triggered()),
hjk's avatar
hjk committed
585
        this, SLOT(executeStep()));
586
    connect(d->m_actions.stepOutAction, SIGNAL(triggered()),
hjk's avatar
hjk committed
587
        this, SLOT(executeStepOut()));
588
    connect(d->m_actions.runToLineAction1, SIGNAL(triggered()),
hjk's avatar
hjk committed
589
        this, SLOT(executeRunToLine()));
590
    connect(d->m_actions.runToLineAction2, SIGNAL(triggered()),
hjk's avatar
hjk committed
591
        this, SLOT(executeRunToLine()));
592
    connect(d->m_actions.runToFunctionAction, SIGNAL(triggered()),
hjk's avatar
hjk committed
593
        this, SLOT(executeRunToFunction()));
594
    connect(d->m_actions.jumpToLineAction1, SIGNAL(triggered()),
hjk's avatar
hjk committed
595
        this, SLOT(executeJumpToLine()));
596
    connect(d->m_actions.jumpToLineAction2, SIGNAL(triggered()),
hjk's avatar
hjk committed
597
        this, SLOT(executeJumpToLine()));
598
    connect(d->m_actions.returnFromFunctionAction, SIGNAL(triggered()),
hjk's avatar
hjk committed
599
        this, SLOT(executeReturn()));
600
601
602
    connect(d->m_actions.watchAction1, SIGNAL(triggered()),
        this, SLOT(addToWatchWindow()));
    connect(d->m_actions.watchAction2, SIGNAL(triggered()),
con's avatar
con committed
603
        this, SLOT(addToWatchWindow()));
604
605
    connect(d->m_actions.snapshotAction, SIGNAL(triggered()),
        this, SLOT(makeSnapshot()));
606
607
608
609
    connect(d->m_actions.frameDownAction, SIGNAL(triggered()),
        this, SLOT(frameDown()));
    connect(d->m_actions.frameUpAction, SIGNAL(triggered()),
        this, SLOT(frameUp()));
con's avatar
con committed
610

611
    connect(d->m_statusTimer, SIGNAL(timeout()),
612
        this, SLOT(clearStatusMessage()));
con's avatar
con committed
613

614
615
    connect(theDebuggerAction(ExecuteCommand), SIGNAL(triggered()),
        this, SLOT(executeDebuggerCommand()));
616

617
618
    connect(theDebuggerAction(WatchPoint), SIGNAL(triggered()),
        this, SLOT(watchPoint()));
con's avatar
con committed
619

620
621
    connect(theDebuggerAction(OperateByInstruction), SIGNAL(triggered()),
        this, SLOT(operateByInstructionTriggered()));
622

623
624
625
    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
626
                                                    Qt::TopDockWidgetArea, false);
627

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

631
    d->m_registerDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_registerWindow,
632
        Qt::TopDockWidgetArea, false);
633
    connect(d->m_registerDock->toggleViewAction(), SIGNAL(toggled(bool)),
con's avatar
con committed
634
635
        this, SLOT(reloadRegisters()), Qt::QueuedConnection);

636
    d->m_outputDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_outputWindow,
637
        Qt::TopDockWidgetArea, false);
638

639
640
    d->m_snapshotDock =  uiSwitcher->createDockWidget(LANG_CPP, d->m_snapshotWindow);
    d->m_stackDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_stackWindow);
641
642
    d->m_sourceFilesDock = uiSwitcher->createDockWidget(LANG_CPP,
        d->m_sourceFilesWindow, Qt::TopDockWidgetArea, false);
643
    connect(d->m_sourceFilesDock->toggleViewAction(), SIGNAL(toggled(bool)),
644
645
        this, SLOT(reloadSourceFiles()), Qt::QueuedConnection);

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

648
    QSplitter *localsAndWatchers = new Core::MiniSplitter(Qt::Vertical);
649
    localsAndWatchers->setObjectName(QLatin1String("CppDebugLocalsAndWatchers"));
650
651
    localsAndWatchers->setWindowTitle(d->m_localsWindow->windowTitle());
    localsAndWatchers->addWidget(d->m_localsWindow);
652
    localsAndWatchers->addWidget(d->m_returnWindow);
653
654
    localsAndWatchers->addWidget(d->m_watchersWindow);
    //localsAndWatchers->addWidget(d->m_tooltipWindow);
655
656
    localsAndWatchers->setStretchFactor(0, 3);
    localsAndWatchers->setStretchFactor(1, 1);
657
    localsAndWatchers->setStretchFactor(2, 1);
658
659
    d->m_watchDock = DebuggerUISwitcher::instance()->createDockWidget(LANG_CPP,
        localsAndWatchers);
660
661
662
    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;
663

hjk's avatar
hjk committed
664
    setState(DebuggerNotReady);
665
666
}

667
QList<Core::IOptionsPage*> DebuggerManager::initializeEngines(unsigned enabledTypeFlags)
668
669
{
    QList<Core::IOptionsPage*> rc;
670

671
672
673
674
    if (enabledTypeFlags & GdbEngineType) {
        gdbEngine = createGdbEngine(this);
        gdbEngine->addOptionPages(&rc);
    }
675

hjk's avatar
hjk committed
676
    cdbEngine = createCdbEngine(this, (enabledTypeFlags & CdbEngineType), &rc);
677
678
679
680
681
682

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

hjk's avatar
hjk committed
683
684
685
    if (enabledTypeFlags & PdbEngineType) {
        pdbEngine = createPdbEngine(this);
        //pdbEngine->addOptionPages(&rc);
hjk's avatar
hjk committed
686
687
    }

hjk's avatar
hjk committed
688
689
690
691
692
    if (enabledTypeFlags & TcfEngineType) {
        tcfEngine = createTcfEngine(this);
        tcfEngine->addOptionPages(&rc);
    }

693
694
695
696
697
    if (enabledTypeFlags & QmlEngineType) {
        qmlEngine = createQmlEngine(this);
        //qmlEngine->addOptionPages(&rc);
    }

698
    d->m_engine = 0;
hjk's avatar
hjk committed
699
700
    STATE_DEBUG(gdbEngine << cdbEngine << scriptEngine
        << pdbEngine << rc.size());
701
    return rc;
con's avatar
con committed
702
703
}

704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
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;
}

749
750
751
752
753
SnapshotHandler *DebuggerManager::snapshotHandler() const
{
    return d->m_snapshotHandler;
}

754
755
756
757
758
759
760
761
762
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()
{
763
    d->m_codeModelSnapshot = CPlusPlus::Snapshot();
764
765
}

766
767
768
769
770
771
SourceFilesWindow *DebuggerManager::sourceFileWindow() const
{
    return d->m_sourceFilesWindow;
}

QWidget *DebuggerManager::threadsWindow() const
con's avatar
con committed
772
{
773
    return d->m_threadsWindow;
con's avatar
con committed
774
775
}

hjk's avatar
hjk committed
776
777
void DebuggerManager::createNewDock(QWidget *widget)
{
778
779
    QDockWidget *dockWidget =
        DebuggerUISwitcher::instance()->createDockWidget(LANG_CPP, widget);
780
    dockWidget->setWindowTitle(widget->windowTitle());
hjk's avatar
hjk committed
781
782
    dockWidget->setObjectName(widget->windowTitle());
    dockWidget->setFeatures(QDockWidget::DockWidgetClosable);
783
784
    //dockWidget->setWidget(widget);
    //d->m_mainWindow->addDockWidget(Qt::TopDockWidgetArea, dockWidget);
hjk's avatar
hjk committed
785
786
787
    dockWidget->show();
}

788
void DebuggerManager::setSimpleDockWidgetArrangement(const QString &activeLanguage)
con's avatar
con committed
789
{
hjk's avatar
hjk committed
790
    if (activeLanguage == LANG_CPP || activeLanguage.isEmpty()) {
791
792
793
794
795
796
797
798
        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
799

800
801
802
803
804
805
806
807
808
        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
809

810
811
812
813
814
815
816
817
818
819
820
821
822
823
        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
824
825
826
827
}

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

831
832
void DebuggerManager::clearStatusMessage()
{
833
    d->m_statusLabel->setText(d->m_lastPermanentStatusMessage);
834
835
}

836
void DebuggerManager::showStatusMessage(const QString &msg0, int timeout)
con's avatar
con committed
837
838
{
    Q_UNUSED(timeout)
839
840
841
    showDebuggerOutput(LogStatus, msg0);
    QString msg = msg0;
    msg.replace(QLatin1Char('\n'), QString());
842
    d->m_statusLabel->setText(msg);
843
    if (timeout > 0) {
844
845
        d->m_statusTimer->setSingleShot(true);
        d->m_statusTimer->start(timeout);
846
    } else {
847
848
        d->m_lastPermanentStatusMessage = msg;
        d->m_statusTimer->stop();
849
    }
con's avatar
con committed
850
851
852
853
}

void DebuggerManager::notifyInferiorStopped()
{
hjk's avatar
hjk committed
854
    setState(InferiorStopped);
855
    showStatusMessage(tr("Stopped"), 5000);
con's avatar
con committed
856
857
858
859
}

void DebuggerManager::notifyInferiorRunning()
{
hjk's avatar
hjk committed
860
    setState(InferiorRunning);
con's avatar
con committed
861
862
863
864
865
    showStatusMessage(tr("Running..."), 5000);
}

void DebuggerManager::notifyInferiorExited()
{
hjk's avatar
hjk committed
866
    setState(DebuggerNotReady);
867
    showStatusMessage(tr("Exited"), 5000);
con's avatar
con committed
868
869
}

870
void DebuggerManager::notifyInferiorPidChanged(qint64 pid)