debuggerengine.cpp 57.5 KB
Newer Older
1
2
3
4
/**************************************************************************
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
6
**
Eike Ziller's avatar
Eike Ziller committed
7
** Contact: http://www.qt-project.org/
8
9
10
11
**
**
** GNU Lesser General Public License Usage
**
hjk's avatar
hjk committed
12
13
14
15
16
17
** 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.
18
**
con's avatar
con committed
19
** In addition, as a special exception, Nokia gives you certain additional
hjk's avatar
hjk committed
20
** rights. These rights are described in the Nokia Qt LGPL Exception
con's avatar
con committed
21
22
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
23
24
25
26
27
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
28
29
30
31
32
**
**************************************************************************/

#include "debuggerengine.h"

33
#include "debuggerinternalconstants.h"
34
#include "debuggeractions.h"
35
#include "debuggercore.h"
36
#include "debuggerplugin.h"
37
#include "debuggerrunner.h"
38
#include "debuggerstringutils.h"
Friedemann Kleint's avatar
Friedemann Kleint committed
39
#include "debuggerstartparameters.h"
40

41
42
#include "memoryagent.h"
#include "disassembleragent.h"
43
44
45
46
47
48
49
50
#include "breakhandler.h"
#include "moduleshandler.h"
#include "registerhandler.h"
#include "snapshothandler.h"
#include "sourcefileshandler.h"
#include "stackhandler.h"
#include "threadshandler.h"
#include "watchhandler.h"
51
#include "qtmessageloghandler.h"
52

hjk's avatar
hjk committed
53
#include <coreplugin/icore.h>
54
#include <coreplugin/idocument.h>
hjk's avatar
hjk committed
55
#include <coreplugin/editormanager/editormanager.h>
56
57
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
hjk's avatar
hjk committed
58
59

#include <texteditor/itexteditor.h>
60
#include <texteditor/basetextmark.h>
hjk's avatar
hjk committed
61

hjk's avatar
hjk committed
62
#include <projectexplorer/projectexplorer.h>
63
64
#include <projectexplorer/taskhub.h>

65
66
#include <utils/savedaction.h>
#include <utils/qtcassert.h>
67
#include <utils/fileinprojectfinder.h>
68

69
70
71
72
73
#include <QDebug>
#include <QTimer>
#include <QFile>
#include <QFileInfo>
#include <QFutureInterface>
74

75
#include <QMessageBox>
76

hjk's avatar
hjk committed
77
using namespace Core;
78
using namespace Debugger::Internal;
hjk's avatar
hjk committed
79
80
using namespace ProjectExplorer;
using namespace TextEditor;
81

82
83
84
85
enum { debug = 0 };

#define SDEBUG(s) if (!debug) {} else qDebug() << s;
#define XSDEBUG(s) qDebug() << s
86

87
88
89
90
//#define WITH_BENCHMARK
#ifdef WITH_BENCHMARK
#include <valgrind/callgrind.h>
#endif
91

92
93
94
95
96
97
///////////////////////////////////////////////////////////////////////
//
// DebuggerStartParameters
//
///////////////////////////////////////////////////////////////////////

98
99
namespace Debugger {

Friedemann Kleint's avatar
Friedemann Kleint committed
100
101
102
103
104
105
106
107
108
Internal::Location::Location(const StackFrame &frame, bool marker)
{
    init();
    m_fileName = frame.file;
    m_lineNumber = frame.line;
    m_needsMarker = marker;
    m_functionName = frame.function;
    m_hasDebugInfo = frame.isUsable();
    m_address = frame.address;
109
    m_from = frame.from;
Friedemann Kleint's avatar
Friedemann Kleint committed
110
111
}

112
113
QDebug operator<<(QDebug d, DebuggerState state)
{
hjk's avatar
hjk committed
114
115
    //return d << DebuggerEngine::stateName(state) << '(' << int(state) << ')';
    return d << DebuggerEngine::stateName(state);
116
117
118
119
120
121
122
}

QDebug operator<<(QDebug str, const DebuggerStartParameters &sp)
{
    QDebug nospace = str.nospace();
    nospace << "executable=" << sp.executable
            << " coreFile=" << sp.coreFile
123
            << " processArgs=" << sp.processArgs
124
125
126
127
128
129
            << " environment=<" << sp.environment.size() << " variables>"
            << " workingDir=" << sp.workingDirectory
            << " attachPID=" << sp.attachPID
            << " useTerminal=" << sp.useTerminal
            << " remoteChannel=" << sp.remoteChannel
            << " symbolFileName=" << sp.symbolFileName
hjk's avatar
hjk committed
130
            << " useServerStartScript=" << sp.useServerStartScript
131
            << " serverStartScript=" << sp.serverStartScript
132
            << " abi=" << sp.toolChainAbi.toString() << '\n';
133
134
135
    return str;
}

136

137
138
139
140
141
142
//////////////////////////////////////////////////////////////////////
//
// DebuggerEnginePrivate
//
//////////////////////////////////////////////////////////////////////

143
144
145
146
147
148
149
150
151
// transitions:
//   None->Requested
//   Requested->Succeeded
//   Requested->Failed
//   Requested->Cancelled
enum RemoteSetupState { RemoteSetupNone, RemoteSetupRequested,
                        RemoteSetupSucceeded, RemoteSetupFailed,
                        RemoteSetupCancelled };

152
class DebuggerEnginePrivate : public QObject
153
{
154
155
    Q_OBJECT

156
public:
157
158
    DebuggerEnginePrivate(DebuggerEngine *engine,
            DebuggerEngine *masterEngine,
159
            DebuggerLanguages languages,
160
            const DebuggerStartParameters &sp)
161
      : m_engine(engine),
162
        m_masterEngine(masterEngine),
163
164
        m_runControl(0),
        m_startParameters(sp),
165
        m_languages(languages),
166
        m_state(DebuggerNotReady),
hjk's avatar
hjk committed
167
        m_lastGoodState(DebuggerNotReady),
Friedemann Kleint's avatar
Friedemann Kleint committed
168
        m_targetState(DebuggerNotReady),
169
        m_remoteSetupState(RemoteSetupNone),
170
        m_inferiorPid(0),
171
        m_modulesHandler(),
172
        m_registerHandler(),
173
174
        m_sourceFilesHandler(),
        m_stackHandler(),
hjk's avatar
hjk committed
175
        m_threadsHandler(),
176
        m_watchHandler(engine),
177
        m_disassemblerAgent(engine),
178
        m_memoryAgent(engine),
179
        m_isStateDebugging(false),
180
        m_testsPossible(true),
181
        m_testsRunning(false),
182
        m_taskHub(0)
183
    {
184
        connect(&m_locationTimer, SIGNAL(timeout()), SLOT(resetLocation()));
185
    }
186
187

    ~DebuggerEnginePrivate() {}
188

189
public slots:
190
    void doSetupEngine();
hjk's avatar
hjk committed
191
192
    void doSetupInferior();
    void doRunEngine();
hjk's avatar
hjk committed
193
194
    void doShutdownEngine();
    void doShutdownInferior();
195
    void doInterruptInferior();
hjk's avatar
hjk committed
196
    void doFinishDebugger();
hjk's avatar
hjk committed
197

198
199
200
201
202
203
204
205
206
207
208
209
210
211
    void queueSetupEngine()
    {
        m_engine->setState(EngineSetupRequested);
        m_engine->showMessage(_("QUEUE: SETUP ENGINE"));
        QTimer::singleShot(0, this, SLOT(doSetupEngine()));
    }

    void queueSetupInferior()
    {
        m_engine->setState(InferiorSetupRequested);
        m_engine->showMessage(_("QUEUE: SETUP INFERIOR"));
        QTimer::singleShot(0, this, SLOT(doSetupInferior()));
    }

212
213
    void queueRunEngine()
    {
hjk's avatar
hjk committed
214
215
216
217
218
        m_engine->setState(EngineRunRequested);
        m_engine->showMessage(_("QUEUE: RUN ENGINE"));
        QTimer::singleShot(0, this, SLOT(doRunEngine()));
    }

219
220
    void queueShutdownEngine()
    {
hjk's avatar
hjk committed
221
222
223
224
225
        m_engine->setState(EngineShutdownRequested);
        m_engine->showMessage(_("QUEUE: SHUTDOWN ENGINE"));
        QTimer::singleShot(0, this, SLOT(doShutdownEngine()));
    }

226
227
    void queueShutdownInferior()
    {
hjk's avatar
hjk committed
228
229
230
231
232
        m_engine->setState(InferiorShutdownRequested);
        m_engine->showMessage(_("QUEUE: SHUTDOWN INFERIOR"));
        QTimer::singleShot(0, this, SLOT(doShutdownInferior()));
    }

233
234
    void queueFinishDebugger()
    {
235
236
237
        QTC_ASSERT(state() == EngineShutdownOk
            || state() == EngineShutdownFailed, qDebug() << state());
        m_engine->setState(DebuggerFinished);
238
239
240
241
242
        resetLocation();
        if (isMasterEngine()) {
            m_engine->showMessage(_("QUEUE: FINISH DEBUGGER"));
            QTimer::singleShot(0, this, SLOT(doFinishDebugger()));
        }
hjk's avatar
hjk committed
243
244
    }

245
246
    void raiseApplication()
    {
247
248
        QTC_ASSERT(runControl(), return);
        runControl()->bringApplicationToForeground(m_inferiorPid);
249
250
    }

251
    void scheduleResetLocation()
252
    {
253
        m_stackHandler.scheduleResetLocation();
254
        m_watchHandler.scheduleResetLocation();
255
        m_threadsHandler.scheduleResetLocation();
256
        m_disassemblerAgent.scheduleResetLocation();
257
258
259
260
        m_locationTimer.setSingleShot(true);
        m_locationTimer.start(80);
    }

261
    void resetLocation()
262
263
264
    {
        m_locationTimer.stop();
        m_locationMark.reset();
265
        m_stackHandler.resetLocation();
266
        m_watchHandler.resetLocation();
267
        m_threadsHandler.resetLocation();
268
        m_disassemblerAgent.resetLocation();
269
270
    }

271
272
    TaskHub *taskHub();

273
public:
hjk's avatar
hjk committed
274
    DebuggerState state() const { return m_state; }
275
    RemoteSetupState remoteSetupState() const { return m_remoteSetupState; }
276
277
278
    bool isMasterEngine() const { return m_engine->isMasterEngine(); }
    DebuggerRunControl *runControl() const
        { return m_masterEngine ? m_masterEngine->runControl() : m_runControl; }
279
    void setRemoteSetupState(RemoteSetupState state);
hjk's avatar
hjk committed
280

281
    DebuggerEngine *m_engine; // Not owned.
282
    DebuggerEngine *m_masterEngine; // Not owned
283
284
285
    DebuggerRunControl *m_runControl;  // Not owned.

    DebuggerStartParameters m_startParameters;
286
    DebuggerLanguages m_languages;
hjk's avatar
hjk committed
287
288

    // The current state.
289
290
    DebuggerState m_state;

hjk's avatar
hjk committed
291
292
293
294
295
296
    // The state we had before something unexpected happend.
    DebuggerState m_lastGoodState;

    // The state we are aiming for.
    DebuggerState m_targetState;

297
298
299
    // State of RemoteSetup signal/slots.
    RemoteSetupState m_remoteSetupState;

300
301
302
303
304
305
306
307
    qint64 m_inferiorPid;

    ModulesHandler m_modulesHandler;
    RegisterHandler m_registerHandler;
    SourceFilesHandler m_sourceFilesHandler;
    StackHandler m_stackHandler;
    ThreadsHandler m_threadsHandler;
    WatchHandler m_watchHandler;
308
    QtMessageLogHandler m_qtMessageHandler;
309
    QFutureInterface<void> m_progress;
310

311
312
    DisassemblerAgent m_disassemblerAgent;
    MemoryAgent m_memoryAgent;
313
314
    QScopedPointer<TextEditor::BaseTextMark> m_locationMark;
    QTimer m_locationTimer;
315
316

    bool m_isStateDebugging;
317

318
    Utils::FileInProjectFinder m_fileFinder;
319
320
321
    // Testing
    void handleAutoTests();
    void handleAutoTestLine(int line);
322
    void reportTestError(const QString &msg, int line);
323
    bool m_testsPossible;
324
    bool m_testsRunning;
David Schulz's avatar
David Schulz committed
325
326
    bool m_breakOnError;
    bool m_foundError;
327
    QStringList m_testContents;
328
329
    TaskHub *m_taskHub;
    QString m_testFileName;
330
331
332
333
334
335
336
337
338
};


//////////////////////////////////////////////////////////////////////
//
// DebuggerEngine
//
//////////////////////////////////////////////////////////////////////

339
DebuggerEngine::DebuggerEngine(const DebuggerStartParameters &startParameters,
340
        DebuggerLanguages languages,
341
        DebuggerEngine *parentEngine)
342
  : d(new DebuggerEnginePrivate(this, parentEngine, languages, startParameters))
343
{
344
    d->m_inferiorPid = 0;
345
346
347
348
}

DebuggerEngine::~DebuggerEngine()
{
349
350
    disconnect();
    delete d;
351
352
}

353
354
355
356
357
358
359
360
361
362
363
const char *DebuggerEngine::stateName(int s)
{
#    define SN(x) case x: return #x;
    switch (s) {
        SN(DebuggerNotReady)
        SN(EngineSetupRequested)
        SN(EngineSetupOk)
        SN(EngineSetupFailed)
        SN(EngineRunFailed)
        SN(InferiorSetupRequested)
        SN(InferiorSetupFailed)
364
        SN(InferiorSetupOk)
365
366
367
368
369
370
371
372
        SN(EngineRunRequested)
        SN(InferiorRunRequested)
        SN(InferiorRunOk)
        SN(InferiorRunFailed)
        SN(InferiorUnrunnable)
        SN(InferiorStopRequested)
        SN(InferiorStopOk)
        SN(InferiorStopFailed)
373
        SN(InferiorExitOk)
374
375
376
377
378
379
380
381
382
383
384
385
        SN(InferiorShutdownRequested)
        SN(InferiorShutdownOk)
        SN(InferiorShutdownFailed)
        SN(EngineShutdownRequested)
        SN(EngineShutdownOk)
        SN(EngineShutdownFailed)
        SN(DebuggerFinished)
    }
    return "<unknown>";
#    undef SN
}

386
void DebuggerEngine::showStatusMessage(const QString &msg, int timeout) const
387
{
388
    showMessage(msg, StatusBar, timeout);
389
}
390

391
392
393
394
395
396
397
398
399
400
401
402
void DebuggerEngine::frameUp()
{
    int currentIndex = stackHandler()->currentIndex();
    activateFrame(qMin(currentIndex + 1, stackHandler()->stackSize() - 1));
}

void DebuggerEngine::frameDown()
{
    int currentIndex = stackHandler()->currentIndex();
    activateFrame(qMax(currentIndex - 1, 0));
}

403
404
405
406
407
void DebuggerEngine::setTargetState(DebuggerState state)
{
    d->m_targetState = state;
}

408
409
ModulesHandler *DebuggerEngine::modulesHandler() const
{
410
411
412
    return d->m_masterEngine
        ? d->m_masterEngine->modulesHandler()
        : &d->m_modulesHandler;
413
414
415
416
}

RegisterHandler *DebuggerEngine::registerHandler() const
{
417
418
419
    return d->m_masterEngine
        ? d->m_masterEngine->registerHandler()
        : &d->m_registerHandler;
420
421
422
423
}

StackHandler *DebuggerEngine::stackHandler() const
{
Aurindam Jana's avatar
Aurindam Jana committed
424
425
426
    return d->m_masterEngine
        ? d->m_masterEngine->stackHandler()
        : &d->m_stackHandler;
427
428
429
430
}

ThreadsHandler *DebuggerEngine::threadsHandler() const
{
431
432
433
    return d->m_masterEngine
        ? d->m_masterEngine->threadsHandler()
        : &d->m_threadsHandler;
434
435
436
437
}

WatchHandler *DebuggerEngine::watchHandler() const
{
438
439
440
    return d->m_masterEngine
        ? d->m_masterEngine->watchHandler()
        : &d->m_watchHandler;
441
442
}

443
444
445
446
447
QtMessageLogHandler *DebuggerEngine::qtMessageLogHandler() const
{
    return &d->m_qtMessageHandler;
}

448
449
SourceFilesHandler *DebuggerEngine::sourceFilesHandler() const
{
450
451
452
    return d->m_masterEngine
        ? d->m_masterEngine->sourceFilesHandler()
        : &d->m_sourceFilesHandler;
453
454
455
456
}

QAbstractItemModel *DebuggerEngine::modulesModel() const
{
457
    QAbstractItemModel *model = modulesHandler()->model();
Friedemann Kleint's avatar
Friedemann Kleint committed
458
459
460
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("ModulesModel"));
    return model;
461
462
463
464
}

QAbstractItemModel *DebuggerEngine::registerModel() const
{
465
    QAbstractItemModel *model = registerHandler()->model();
Friedemann Kleint's avatar
Friedemann Kleint committed
466
467
468
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("RegisterModel"));
    return model;
469
470
471
472
}

QAbstractItemModel *DebuggerEngine::stackModel() const
{
473
    QAbstractItemModel *model = stackHandler()->model();
Friedemann Kleint's avatar
Friedemann Kleint committed
474
475
476
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("StackModel"));
    return model;
477
478
479
480
}

QAbstractItemModel *DebuggerEngine::threadsModel() const
{
481
    QAbstractItemModel *model = threadsHandler()->model();
Friedemann Kleint's avatar
Friedemann Kleint committed
482
483
484
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("ThreadsModel"));
    return model;
485
486
487
488
}

QAbstractItemModel *DebuggerEngine::localsModel() const
{
hjk's avatar
hjk committed
489
    return watchHandler()->model();
490
491
492
493
}

QAbstractItemModel *DebuggerEngine::watchersModel() const
{
hjk's avatar
hjk committed
494
    return watchHandler()->model();
495
496
497
498
}

QAbstractItemModel *DebuggerEngine::returnModel() const
{
hjk's avatar
hjk committed
499
    return watchHandler()->model();
500
501
}

502
503
QAbstractItemModel *DebuggerEngine::inspectorModel() const
{
hjk's avatar
hjk committed
504
    return watchHandler()->model();
505
506
}

507
508
QAbstractItemModel *DebuggerEngine::toolTipsModel() const
{
hjk's avatar
hjk committed
509
510
511
512
513
514
    return watchHandler()->model();
}

QAbstractItemModel *DebuggerEngine::watchModel() const
{
    return watchHandler()->model();
515
516
}

517
518
QAbstractItemModel *DebuggerEngine::sourceFilesModel() const
{
519
    QAbstractItemModel *model = sourceFilesHandler()->model();
Friedemann Kleint's avatar
Friedemann Kleint committed
520
521
522
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("SourceFilesModel"));
    return model;
523
524
}

525
526
527
528
529
530
531
532
QAbstractItemModel *DebuggerEngine::qtMessageLogModel() const
{
    QAbstractItemModel *model = qtMessageLogHandler()->model();
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("QtMessageLogModel"));
    return model;
}

533
void DebuggerEngine::fetchMemory(MemoryAgent *, QObject *,
534
535
536
537
538
539
        quint64 addr, quint64 length)
{
    Q_UNUSED(addr);
    Q_UNUSED(length);
}

hjk's avatar
hjk committed
540
541
542
543
544
545
546
void DebuggerEngine::changeMemory(MemoryAgent *, QObject *,
        quint64 addr, const QByteArray &data)
{
    Q_UNUSED(addr);
    Q_UNUSED(data);
}

547
548
549
550
551
552
553
554
void DebuggerEngine::setRegisterValue(int regnr, const QString &value)
{
    Q_UNUSED(regnr);
    Q_UNUSED(value);
}

void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) const
{
555
556
557
558
    if (d->m_masterEngine) {
        d->m_masterEngine->showMessage(msg, channel, timeout);
        return;
    }
559
560
    //if (msg.size() && msg.at(0).isUpper() && msg.at(1).isUpper())
    //    qDebug() << qPrintable(msg) << "IN STATE" << state();
561
562
563
    if (channel == QtMessageLogOutput)
        qtMessageLogHandler()->appendMessage(QtMessageLogHandler::UndefinedType, msg);

564
    debuggerCore()->showMessage(msg, channel, timeout);
565
566
567
568
569
    if (d->m_runControl) {
        d->m_runControl->showMessage(msg, channel);
    } else {
        qWarning("Warning: %s (no active run control)", qPrintable(msg));
    }
570
571
572
573
}

void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
{
574
575
    QTC_ASSERT(runControl, notifyEngineSetupFailed(); return);
    QTC_ASSERT(!d->m_runControl, notifyEngineSetupFailed(); return);
576

577
    d->m_progress.setProgressRange(0, 1000);
hjk's avatar
hjk committed
578
    Core::FutureProgress *fp = Core::ICore::progressManager()
579
580
        ->addTask(d->m_progress.future(),
        tr("Launching"), _("Debugger.Launcher"));
con's avatar
con committed
581
    fp->setKeepOnFinish(Core::FutureProgress::HideOnFinish);
582
583
    d->m_progress.reportStarted();

584
585
586
587
    d->m_runControl = runControl;

    d->m_inferiorPid = d->m_startParameters.attachPID > 0
        ? d->m_startParameters.attachPID : 0;
588
589
    if (d->m_inferiorPid)
        d->m_runControl->setApplicationProcessHandle(ProcessHandle(d->m_inferiorPid));
590

591
592
    if (!d->m_startParameters.environment.size())
        d->m_startParameters.environment = Utils::Environment();
593

hjk's avatar
hjk committed
594
    debuggerCore()->action(OperateByInstruction)
595
        ->setEnabled(hasCapability(DisassemblerCapability));
596

597
598
    QTC_ASSERT(state() == DebuggerNotReady || state() == DebuggerFinished,
         qDebug() << state());
599
600
    d->m_lastGoodState = DebuggerNotReady;
    d->m_targetState = DebuggerNotReady;
601
    d->m_progress.setProgressValue(200);
602
    d->queueSetupEngine();
603
604
605
606
}

void DebuggerEngine::resetLocation()
{
607
608
    // Do it after some delay to avoid flicker.
    d->scheduleResetLocation();
609
610
}

611
void DebuggerEngine::gotoLocation(const Location &loc)
612
{
Aurindam Jana's avatar
Aurindam Jana committed
613
614
     d->resetLocation();

Aurindam Jana's avatar
Aurindam Jana committed
615
616
    if ((hasCapability(OperateByInstructionCapability) &&
            debuggerCore()->boolSetting(OperateByInstruction)) || !loc.hasDebugInfo()) {
617
618
619
        d->m_disassemblerAgent.setLocation(loc);
        return;
    }
620
621
622
623
624
    // CDB might hit on breakpoints while shutting down.
    //if (m_shuttingDown)
    //    return;


625
626
    const QString file = loc.fileName();
    const int line = loc.lineNumber();
hjk's avatar
hjk committed
627
    QList<IEditor *> editors = EditorManager::instance()->editorsForFileName(file);
628
    IEditor *editor = 0;
hjk's avatar
hjk committed
629
    if (editors.isEmpty()) {
hjk's avatar
hjk committed
630
        editor = EditorManager::openEditor(file, Core::Id(),
631
632
633
634
635
636
637
            EditorManager::IgnoreNavigationHistory);
        if (editor) {
            editors.append(editor);
            editor->setProperty(Constants::OPENED_BY_DEBUGGER, true);
        }
    } else {
        editor = editors.back();
hjk's avatar
hjk committed
638
    }
639
    ITextEditor *texteditor = qobject_cast<ITextEditor *>(editor);
hjk's avatar
hjk committed
640
641
642
    if (texteditor)
        texteditor->gotoLine(line, 0);

643
    if (loc.needsMarker()) {
Daniel Teske's avatar
Daniel Teske committed
644
        d->m_locationMark.reset(new TextEditor::BaseTextMark(file, line));
645
646
        d->m_locationMark->setIcon(debuggerCore()->locationMarkIcon());
        d->m_locationMark->setPriority(TextEditor::ITextMark::HighPriority);
647
        d->m_locationMark->init();
648
    }
649
650

    // FIXME: Breaks with split views.
651
    if (!d->m_memoryAgent.hasVisibleEditor() || loc.needsRaise())
hjk's avatar
hjk committed
652
        EditorManager::activateEditor(editor);
653
    //qDebug() << "MEMORY: " << d->m_memoryAgent.hasVisibleEditor();
654
655
}

656
657
658
// Called from RunControl.
void DebuggerEngine::handleStartFailed()
{
659
    showMessage(QLatin1String("HANDLE RUNCONTROL START FAILED"));
660
    d->m_runControl = 0;
661
    d->m_progress.setProgressValue(900);
662
663
    d->m_progress.reportCanceled();
    d->m_progress.reportFinished();
664
665
}

666
667
// Called from RunControl.
void DebuggerEngine::handleFinished()
668
{
669
    showMessage(QLatin1String("HANDLE RUNCONTROL FINISHED"));
670
    d->m_runControl = 0;
671
672
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
    modulesHandler()->removeAll();
    stackHandler()->removeAll();
    threadsHandler()->removeAll();
    watchHandler()->cleanup();
}

const DebuggerStartParameters &DebuggerEngine::startParameters() const
{
    return d->m_startParameters;
}

DebuggerStartParameters &DebuggerEngine::startParameters()
{
    return d->m_startParameters;
}

DebuggerState DebuggerEngine::state() const
{
    return d->m_state;
}

hjk's avatar
hjk committed
694
DebuggerState DebuggerEngine::lastGoodState() const
695
{
hjk's avatar
hjk committed
696
697
698
699
700
701
702
    return d->m_lastGoodState;
}

DebuggerState DebuggerEngine::targetState() const
{
    return d->m_targetState;
}
703

hjk's avatar
hjk committed
704
705
706
static bool isAllowedTransition(DebuggerState from, DebuggerState to)
{
    switch (from) {
707
    case DebuggerNotReady:
708
        return to == EngineSetupRequested;
709

hjk's avatar
hjk committed
710
    case EngineSetupRequested:
711
712
        return to == EngineSetupOk || to == EngineSetupFailed;
    case EngineSetupFailed:
713
714
715
        // In is the engine's task to go into a proper "Shutdown"
        // state before calling notifyEngineSetupFailed
        return to == DebuggerFinished;
716
    case EngineSetupOk:
hjk's avatar
hjk committed
717
        return to == InferiorSetupRequested || to == EngineShutdownRequested;
718

hjk's avatar
hjk committed
719
    case InferiorSetupRequested:
720
        return to == InferiorSetupOk || to == InferiorSetupFailed;
hjk's avatar
hjk committed
721
    case InferiorSetupFailed:
hjk's avatar
hjk committed
722
        return to == EngineShutdownRequested;
723
724
    case InferiorSetupOk:
        return to == EngineRunRequested;
hjk's avatar
hjk committed
725
726

    case EngineRunRequested:
hjk's avatar
hjk committed
727
728
729
730
        return to == EngineRunFailed
            || to == InferiorRunOk
            || to == InferiorStopOk
            || to == InferiorUnrunnable;
hjk's avatar
hjk committed
731
    case EngineRunFailed:
732
        return to == EngineShutdownRequested;
hjk's avatar
hjk committed
733
734
735
736
737
738

    case InferiorRunRequested:
        return to == InferiorRunOk || to == InferiorRunFailed;
    case InferiorRunFailed:
        return to == InferiorStopOk;
    case InferiorRunOk:
739
740
741
        return to == InferiorStopRequested
            || to == InferiorStopOk // A spontaneous stop.
            || to == InferiorExitOk;
hjk's avatar
hjk committed
742
743
744
745
746

    case InferiorStopRequested:
        return to == InferiorStopOk || to == InferiorStopFailed;
    case InferiorStopOk:
        return to == InferiorRunRequested || to == InferiorShutdownRequested
747
            || to == InferiorStopOk || InferiorExitOk;
748
    case InferiorStopFailed:
hjk's avatar
hjk committed
749
        return to == EngineShutdownRequested;
750

751
752
753
    case InferiorExitOk:
        return to == InferiorShutdownOk;

754
    case InferiorUnrunnable:
hjk's avatar
hjk committed
755
756
757
758
759
        return to == InferiorShutdownRequested;
    case InferiorShutdownRequested:
        return to == InferiorShutdownOk || to == InferiorShutdownFailed;
    case InferiorShutdownOk:
        return to == EngineShutdownRequested;
760
    case InferiorShutdownFailed:
hjk's avatar
hjk committed
761
        return to == EngineShutdownRequested;
762

hjk's avatar
hjk committed
763
    case EngineShutdownRequested:
764
        return to == EngineShutdownOk || to == EngineShutdownFailed;
hjk's avatar
hjk committed
765
766
767
768
769
770
    case EngineShutdownOk:
        return to == DebuggerFinished;
    case EngineShutdownFailed:
        return to == DebuggerFinished;

    case DebuggerFinished:
771
        return to == EngineSetupRequested; // Happens on restart.
772
773
    }

774
    qDebug() << "UNKNOWN DEBUGGER STATE:" << from;
775
776
777
    return false;
}

778
779
void DebuggerEngine::setupSlaveEngine()
{
780
    QTC_CHECK(state() == DebuggerNotReady);
781
782
783
784
785
786
787
788
789
790
    d->queueSetupEngine();
}

void DebuggerEnginePrivate::doSetupEngine()
{
    m_engine->showMessage(_("CALL: SETUP ENGINE"));
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << m_engine << state());
    m_engine->setupEngine();
}

791
void DebuggerEngine::notifyEngineSetupFailed()
hjk's avatar
hjk committed
792
{
hjk's avatar
hjk committed
793
    showMessage(_("NOTE: ENGINE SETUP FAILED"));
794
795
796
797
798
799
800
    QTC_ASSERT(d->remoteSetupState() == RemoteSetupNone
               || d->remoteSetupState() == RemoteSetupRequested
               || d->remoteSetupState() == RemoteSetupSucceeded,
               qDebug() << this << "remoteSetupState" << d->remoteSetupState());
    if (d->remoteSetupState() == RemoteSetupRequested)
        d->setRemoteSetupState(RemoteSetupCancelled);

801
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
802
    setState(EngineSetupFailed);
hjk's avatar
hjk committed
803
    if (isMasterEngine() && runControl())
804
        runControl()->startFailed();
hjk's avatar
hjk committed
805
    setState(DebuggerFinished);
hjk's avatar
hjk committed
806
807
}

808
void DebuggerEngine::notifyEngineSetupOk()
809
{
hjk's avatar
hjk committed
810
    showMessage(_("NOTE: ENGINE SETUP OK"));
811
812
813
814
    QTC_ASSERT(d->remoteSetupState() == RemoteSetupNone
               || d->remoteSetupState() == RemoteSetupSucceeded,
               qDebug() << this << "remoteSetupState" << d->remoteSetupState());

815
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
816
    setState(EngineSetupOk);
hjk's avatar
hjk committed
817
    showMessage(_("QUEUE: SETUP INFERIOR"));
818
    if (isMasterEngine())
819
820
821
822
823
        d->queueSetupInferior();
}

void DebuggerEngine::setupSlaveInferior()
{
824
    QTC_CHECK(state() == EngineSetupOk);
825
    d->queueSetupInferior();
826
827
}

hjk's avatar
hjk committed
828
void DebuggerEnginePrivate::doSetupInferior()
829
{
830
    m_engine->showMessage(_("CALL: SETUP INFERIOR"));
831
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << m_engine << state());
832
    m_progress.setProgressValue(250);
hjk's avatar
hjk committed
833
834
835
836
837
    m_engine->setupInferior();
}

void DebuggerEngine::notifyInferiorSetupFailed()
{
hjk's avatar
hjk committed
838
    showMessage(_("NOTE: INFERIOR SETUP FAILED"));
839
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << this << state());
840
    showStatusMessage(tr("Setup failed."));
hjk's avatar
hjk committed
841
    setState(InferiorSetupFailed);
842
843
    if (isMasterEngine())
        d->queueShutdownEngine();
hjk's avatar
hjk committed
844
845
846
847
}

void DebuggerEngine::notifyInferiorSetupOk()
{
848
849
850
#ifdef WITH_BENCHMARK
    CALLGRIND_START_INSTRUMENTATION;
#endif
hjk's avatar
hjk committed
851
    showMessage(_("NOTE: INFERIOR SETUP OK"));
852
853
854
855
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << this << state());
    setState(InferiorSetupOk);
    if (isMasterEngine())
        d->queueRunEngine();
hjk's avatar
hjk committed
856
857
}

858
859
860
void DebuggerEngine::runSlaveEngine()
{
    QTC_ASSERT(isSlaveEngine(), return);
861
    QTC_CHECK(state() == InferiorSetupOk);
862
863
864
    d->queueRunEngine();
}

hjk's avatar
hjk committed
865
866
void DebuggerEnginePrivate::doRunEngine()
{
hjk's avatar
hjk committed
867
    m_engine->showMessage(_("CALL: RUN ENGINE"));
868
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << m_engine << state());
869
    m_progress.setProgressValue(300);
hjk's avatar
hjk committed
870
871
872
    m_engine->runEngine();
}

hjk's avatar
hjk committed
873
874
void DebuggerEngine::notifyInferiorUnrunnable()
{
hjk's avatar
hjk committed
875
    showMessage(_("NOTE: INFERIOR UNRUNNABLE"));
876
877
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
878
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state());
879
    showStatusMessage(tr("Loading finished."));
hjk's avatar
hjk committed
880
881
882
883
884
    setState(InferiorUnrunnable);
}

void DebuggerEngine::notifyEngineRunFailed()
{
hjk's avatar
hjk committed
885
    showMessage(_("NOTE: ENGINE RUN FAILED"));
886
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state());
887
888
889
    d->m_progress.setProgressValue(900);
    d->m_progress.reportCanceled();
    d->m_progress.reportFinished();
890
    showStatusMessage(tr("Run failed."));
hjk's avatar
hjk committed
891
    setState(EngineRunFailed);
892
893
    if (isMasterEngine())
        d->queueShutdownEngine();
hjk's avatar
hjk committed
894
895
}

896
897
898
899
900
901
902
903
904
905
906
void DebuggerEngine::notifyEngineRequestRemoteSetup()
{
    showMessage(_("NOTE: REQUEST REMOTE SETUP"));
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
    QTC_ASSERT(d->remoteSetupState() == RemoteSetupNone, qDebug() << this
               << "remoteSetupState" << d->remoteSetupState());

    d->setRemoteSetupState(RemoteSetupRequested);
    emit requestRemoteSetup();
}

907
void DebuggerEngine::notifyEngineRemoteSetupDone(int gdbServerPort, int qmlPort)
908
{
909
910
    showMessage(_("NOTE: REMOTE SETUP DONE: GDB SERVER PORT: %1  QML PORT %2")
                .arg(gdbServerPort).arg(qmlPort));
911
912
913
914
915
916
917
918
919
920
921
922
923
924
    QTC_ASSERT(state() == EngineSetupRequested
               || state() == EngineSetupFailed
               || state() == DebuggerFinished, qDebug() << this << state());

    QTC_ASSERT(d->remoteSetupState() == RemoteSetupRequested
               || d->remoteSetupState() == RemoteSetupCancelled,
               qDebug() << this << "remoteSetupState" << d->remoteSetupState());

    if (d->remoteSetupState() == RemoteSetupCancelled)
        return;

    d->setRemoteSetupState(RemoteSetupSucceeded);
}

925
void DebuggerEngine::notifyEngineRemoteSetupFailed(const QString &message)
926
{
927
    showMessage(_("NOTE: REMOTE SETUP FAILED: ") + message);
928
929
930
931
932
933
934
935
936
    QTC_ASSERT(state() == EngineSetupRequested
               || state() == EngineSetupFailed
               || state() == DebuggerFinished, qDebug() << this << state());

    QTC_ASSERT(d->remoteSetupState() == RemoteSetupRequested
               || d->remoteSetupState() == RemoteSetupCancelled,
               qDebug() << this << "remoteSetupState" << d->remoteSetupState());
}

hjk's avatar
hjk committed
937
938
void DebuggerEngine::notifyEngineRunAndInferiorRunOk()
{
hjk's avatar
hjk committed
939
    showMessage(_("NOTE: ENGINE RUN AND INFERIOR RUN OK"));
940
941
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
942
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state());
943
    showStatusMessage(tr("Running."));
hjk's avatar
hjk committed
944
    setState(InferiorRunOk);
hjk's avatar
hjk committed
945
946
947
948
}

void DebuggerEngine::notifyEngineRunAndInferiorStopOk()
{
hjk's avatar
hjk committed
949
    showMessage(_("NOTE: ENGINE RUN AND INFERIOR STOP OK"));
950
951
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
952
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state());
953
    showStatusMessage(tr("Stopped."));
hjk's avatar
hjk committed
954
    setState(InferiorStopOk);
hjk's avatar
hjk committed
955
956
957
958
}

void DebuggerEngine::notifyInferiorRunRequested()
{
hjk's avatar
hjk committed
959
    showMessage(_("NOTE: INFERIOR RUN REQUESTED"));
960
    QTC_ASSERT(state() == InferiorStopOk, qDebug() << this << state());
961
    showStatusMessage(tr("Run requested..."));
hjk's avatar
hjk committed
962
963
964
965
966
    setState(InferiorRunRequested);
}

void DebuggerEngine::notifyInferiorRunOk()
{
hjk's avatar
hjk committed
967
    showMessage(_("NOTE: INFERIOR RUN OK"));
968
    showStatusMessage(tr("Running."));
969
970
971
    // Transition from StopRequested can happen sin remotegdbadapter.
    QTC_ASSERT(state() == InferiorRunRequested
        || state() == InferiorStopRequested, qDebug() << this << state());
hjk's avatar
hjk committed
972
973
974
975
976
    setState(InferiorRunOk);
}

void DebuggerEngine::notifyInferiorRunFailed()
{
hjk's avatar
hjk committed
977
    showMessage(_("NOTE: INFERIOR RUN FAILED"));
978
    QTC_ASSERT(state() == InferiorRunRequested, qDebug() << this << state());
hjk's avatar
hjk committed
979
980
    setState(InferiorRunFailed);
    setState(InferiorStopOk);
hjk's avatar
hjk committed
981
982
    if (isDying())
        d->queueShutdownInferior();
hjk's avatar
hjk committed
983
984
985
986
}

void DebuggerEngine::notifyInferiorStopOk()
{
hjk's avatar
hjk committed
987
988
    showMessage(_("NOTE: INFERIOR STOP OK"));
    // Ignore spurious notifications after we are set to die.
hjk's avatar
hjk committed
989
    if (isDying()) {
hjk's avatar
hjk committed
990
991
992
993
994
995
996
997
998
999
1000
        showMessage(_("NOTE: ... WHILE DYING. "));
        // Forward state to "StopOk" if needed.
        if (state() == InferiorStopRequested
                || state() == InferiorRunRequested
                || state() == InferiorRunOk) {
            showMessage(_("NOTE: ... FORWARDING TO 'STOP OK'. "));
            setState(InferiorStopOk);
        }
        if (state() == InferiorStopOk || state() == InferiorStopFailed) {
            d->queueShutdownInferior();
        }