debuggerengine.cpp 58.7 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
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
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.
**
con's avatar
con committed
28
** If you have questions regarding the use of this file, please contact
29
** Nokia at qt-info@nokia.com.
30
31
32
33
34
**
**************************************************************************/

#include "debuggerengine.h"

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

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

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

#include <texteditor/itexteditor.h>
62
#include <texteditor/basetextmark.h>
hjk's avatar
hjk committed
63

hjk's avatar
hjk committed
64
#include <projectexplorer/projectexplorer.h>
65
66
#include <projectexplorer/taskhub.h>

67
68
#include <utils/savedaction.h>
#include <utils/qtcassert.h>
69
#include <utils/fileinprojectfinder.h>
70

71
72
73
74
75
#include <QDebug>
#include <QTimer>
#include <QFile>
#include <QFileInfo>
#include <QFutureInterface>
76

77
#include <QMessageBox>
78

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

84
85
86
87
enum { debug = 0 };

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

89

90
91
92
93
94
95
///////////////////////////////////////////////////////////////////////
//
// DebuggerStartParameters
//
///////////////////////////////////////////////////////////////////////

96
97
namespace Debugger {

Friedemann Kleint's avatar
Friedemann Kleint committed
98
99
100
101
102
103
104
105
106
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;
107
    m_from = frame.from;
Friedemann Kleint's avatar
Friedemann Kleint committed
108
109
}

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

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

135

136
137
138
139
140
141
//////////////////////////////////////////////////////////////////////
//
// DebuggerEnginePrivate
//
//////////////////////////////////////////////////////////////////////

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

151
class DebuggerEnginePrivate : public QObject
152
{
153
154
    Q_OBJECT

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

    ~DebuggerEnginePrivate() {}
189

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

199
200
201
202
203
204
205
206
207
208
209
210
211
212
    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()));
    }

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

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

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

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

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

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

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

272
273
    TaskHub *taskHub();

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

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

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

    // The current state.
290
291
    DebuggerState m_state;

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

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

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

301
302
303
304
305
306
307
308
    qint64 m_inferiorPid;

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

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

    bool m_isStateDebugging;
318

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


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

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

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

354
355
356
357
358
359
360
361
362
363
364
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)
365
        SN(InferiorSetupOk)
366
367
368
369
370
371
372
373
        SN(EngineRunRequested)
        SN(InferiorRunRequested)
        SN(InferiorRunOk)
        SN(InferiorRunFailed)
        SN(InferiorUnrunnable)
        SN(InferiorStopRequested)
        SN(InferiorStopOk)
        SN(InferiorStopFailed)
374
        SN(InferiorExitOk)
375
376
377
378
379
380
381
382
383
384
385
386
        SN(InferiorShutdownRequested)
        SN(InferiorShutdownOk)
        SN(InferiorShutdownFailed)
        SN(EngineShutdownRequested)
        SN(EngineShutdownOk)
        SN(EngineShutdownFailed)
        SN(DebuggerFinished)
    }
    return "<unknown>";
#    undef SN
}

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

392
393
394
395
396
397
398
399
400
401
402
403
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));
}

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

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

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

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

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

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

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

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

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

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

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

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

QAbstractItemModel *DebuggerEngine::localsModel() const
{
490
    QAbstractItemModel *model = watchHandler()->model(LocalsWatch);
Friedemann Kleint's avatar
Friedemann Kleint committed
491
492
493
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("LocalsModel"));
    return model;
494
495
496
497
}

QAbstractItemModel *DebuggerEngine::watchersModel() const
{
498
    QAbstractItemModel *model = watchHandler()->model(WatchersWatch);
Friedemann Kleint's avatar
Friedemann Kleint committed
499
500
501
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("WatchersModel"));
    return model;
502
503
504
505
}

QAbstractItemModel *DebuggerEngine::returnModel() const
{
506
    QAbstractItemModel *model = watchHandler()->model(ReturnWatch);
Friedemann Kleint's avatar
Friedemann Kleint committed
507
508
509
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("ReturnModel"));
    return model;
510
511
}

512
513
514
515
516
517
518
519
QAbstractItemModel *DebuggerEngine::toolTipsModel() const
{
    QAbstractItemModel *model = watchHandler()->model(TooltipsWatch);
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("TooltipsModel"));
    return model;
}

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

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

536
void DebuggerEngine::fetchMemory(MemoryAgent *, QObject *,
537
538
539
540
541
542
        quint64 addr, quint64 length)
{
    Q_UNUSED(addr);
    Q_UNUSED(length);
}

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

550
551
552
553
554
555
556
557
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
{
558
559
560
561
    if (d->m_masterEngine) {
        d->m_masterEngine->showMessage(msg, channel, timeout);
        return;
    }
562
563
    //if (msg.size() && msg.at(0).isUpper() && msg.at(1).isUpper())
    //    qDebug() << qPrintable(msg) << "IN STATE" << state();
564
565
566
    if (channel == QtMessageLogOutput)
        qtMessageLogHandler()->appendMessage(QtMessageLogHandler::UndefinedType, msg);

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

void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
{
577
578
    QTC_ASSERT(runControl, notifyEngineSetupFailed(); return);
    QTC_ASSERT(!d->m_runControl, notifyEngineSetupFailed(); return);
579

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

587
588
589
590
    d->m_runControl = runControl;

    d->m_inferiorPid = d->m_startParameters.attachPID > 0
        ? d->m_startParameters.attachPID : 0;
591
592
    if (d->m_inferiorPid)
        d->m_runControl->setApplicationProcessHandle(ProcessHandle(d->m_inferiorPid));
593

594
595
    if (!d->m_startParameters.environment.size())
        d->m_startParameters.environment = Utils::Environment();
596

hjk's avatar
hjk committed
597
    debuggerCore()->action(OperateByInstruction)
598
        ->setEnabled(hasCapability(DisassemblerCapability));
599

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

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

614
void DebuggerEngine::gotoLocation(const Location &loc)
615
{
Aurindam Jana's avatar
Aurindam Jana committed
616
617
     d->resetLocation();

618
619
620
621
    if (debuggerCore()->boolSetting(OperateByInstruction) || !loc.hasDebugInfo()) {
        d->m_disassemblerAgent.setLocation(loc);
        return;
    }
622
623
624
625
626
    // CDB might hit on breakpoints while shutting down.
    //if (m_shuttingDown)
    //    return;


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

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

    // FIXME: Breaks with split views.
653
    if (!d->m_memoryAgent.hasVisibleEditor() || loc.needsRaise())
654
        editorManager->activateEditor(editor);
655
    //qDebug() << "MEMORY: " << d->m_memoryAgent.hasVisibleEditor();
656
657
}

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

668
669
// Called from RunControl.
void DebuggerEngine::handleFinished()
670
{
671
    showMessage(QLatin1String("HANDLE RUNCONTROL FINISHED"));
672
    d->m_runControl = 0;
673
674
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
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
    modulesHandler()->removeAll();
    stackHandler()->removeAll();
    threadsHandler()->removeAll();
    watchHandler()->cleanup();
}

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

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


//////////////////////////////////////////////////////////////////////
//
// Dumpers. "Custom dumpers" are a library compiled against the current
// Qt containing functions to evaluate values of Qt classes
// (such as QString, taking pointers to their addresses).
// The library must be loaded into the debuggee.
//
//////////////////////////////////////////////////////////////////////

bool DebuggerEngine::qtDumperLibraryEnabled() const
{
hjk's avatar
hjk committed
703
    return debuggerCore()->boolSetting(UseDebuggingHelpers);
704
705
706
707
708
709
710
711
712
}

QStringList DebuggerEngine::qtDumperLibraryLocations() const
{
    return d->m_startParameters.dumperLibraryLocations;
}

void DebuggerEngine::showQtDumperLibraryWarning(const QString &details)
{
713
    debuggerCore()->showQtDumperLibraryWarning(details);
714
715
716
717
718
719
720
721
722
723
724
725
}

QString DebuggerEngine::qtDumperLibraryName() const
{
    return startParameters().dumperLibrary;
}

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

hjk's avatar
hjk committed
726
DebuggerState DebuggerEngine::lastGoodState() const
727
{
hjk's avatar
hjk committed
728
729
730
731
732
733
734
    return d->m_lastGoodState;
}

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

hjk's avatar
hjk committed
736
737
738
static bool isAllowedTransition(DebuggerState from, DebuggerState to)
{
    switch (from) {
739
    case DebuggerNotReady:
740
        return to == EngineSetupRequested;
741

hjk's avatar
hjk committed
742
    case EngineSetupRequested:
743
744
        return to == EngineSetupOk || to == EngineSetupFailed;
    case EngineSetupFailed:
745
746
747
        // In is the engine's task to go into a proper "Shutdown"
        // state before calling notifyEngineSetupFailed
        return to == DebuggerFinished;
748
    case EngineSetupOk:
hjk's avatar
hjk committed
749
        return to == InferiorSetupRequested || to == EngineShutdownRequested;
750

hjk's avatar
hjk committed
751
    case InferiorSetupRequested:
752
        return to == InferiorSetupOk || to == InferiorSetupFailed;
hjk's avatar
hjk committed
753
    case InferiorSetupFailed:
hjk's avatar
hjk committed
754
        return to == EngineShutdownRequested;
755
756
    case InferiorSetupOk:
        return to == EngineRunRequested;
hjk's avatar
hjk committed
757
758

    case EngineRunRequested:
hjk's avatar
hjk committed
759
760
761
762
        return to == EngineRunFailed
            || to == InferiorRunOk
            || to == InferiorStopOk
            || to == InferiorUnrunnable;
hjk's avatar
hjk committed
763
    case EngineRunFailed:
764
        return to == EngineShutdownRequested;
hjk's avatar
hjk committed
765
766
767
768
769
770

    case InferiorRunRequested:
        return to == InferiorRunOk || to == InferiorRunFailed;
    case InferiorRunFailed:
        return to == InferiorStopOk;
    case InferiorRunOk:
771
772
773
        return to == InferiorStopRequested
            || to == InferiorStopOk // A spontaneous stop.
            || to == InferiorExitOk;
hjk's avatar
hjk committed
774
775
776
777
778

    case InferiorStopRequested:
        return to == InferiorStopOk || to == InferiorStopFailed;
    case InferiorStopOk:
        return to == InferiorRunRequested || to == InferiorShutdownRequested
779
            || to == InferiorStopOk || InferiorExitOk;
780
    case InferiorStopFailed:
hjk's avatar
hjk committed
781
        return to == EngineShutdownRequested;
782

783
784
785
    case InferiorExitOk:
        return to == InferiorShutdownOk;

786
    case InferiorUnrunnable:
hjk's avatar
hjk committed
787
788
789
790
791
        return to == InferiorShutdownRequested;
    case InferiorShutdownRequested:
        return to == InferiorShutdownOk || to == InferiorShutdownFailed;
    case InferiorShutdownOk:
        return to == EngineShutdownRequested;
792
    case InferiorShutdownFailed:
hjk's avatar
hjk committed
793
        return to == EngineShutdownRequested;
794

hjk's avatar
hjk committed
795
    case EngineShutdownRequested:
796
        return to == EngineShutdownOk || to == EngineShutdownFailed;
hjk's avatar
hjk committed
797
798
799
800
801
802
    case EngineShutdownOk:
        return to == DebuggerFinished;
    case EngineShutdownFailed:
        return to == DebuggerFinished;

    case DebuggerFinished:
803
        return to == EngineSetupRequested; // Happens on restart.
804
805
    }

806
    qDebug() << "UNKNOWN DEBUGGER STATE:" << from;
807
808
809
    return false;
}

810
811
void DebuggerEngine::setupSlaveEngine()
{
812
    QTC_CHECK(state() == DebuggerNotReady);
813
814
815
816
817
818
819
820
821
822
    d->queueSetupEngine();
}

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

823
void DebuggerEngine::notifyEngineSetupFailed()
hjk's avatar
hjk committed
824
{
hjk's avatar
hjk committed
825
    showMessage(_("NOTE: ENGINE SETUP FAILED"));
826
827
828
829
830
831
832
    QTC_ASSERT(d->remoteSetupState() == RemoteSetupNone
               || d->remoteSetupState() == RemoteSetupRequested
               || d->remoteSetupState() == RemoteSetupSucceeded,
               qDebug() << this << "remoteSetupState" << d->remoteSetupState());
    if (d->remoteSetupState() == RemoteSetupRequested)
        d->setRemoteSetupState(RemoteSetupCancelled);

833
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
834
    setState(EngineSetupFailed);
hjk's avatar
hjk committed
835
    if (isMasterEngine() && runControl())
836
        runControl()->startFailed();
hjk's avatar
hjk committed
837
    setState(DebuggerFinished);
hjk's avatar
hjk committed
838
839
}

840
void DebuggerEngine::notifyEngineSetupOk()
841
{
hjk's avatar
hjk committed
842
    showMessage(_("NOTE: ENGINE SETUP OK"));
843
844
845
846
    QTC_ASSERT(d->remoteSetupState() == RemoteSetupNone
               || d->remoteSetupState() == RemoteSetupSucceeded,
               qDebug() << this << "remoteSetupState" << d->remoteSetupState());

847
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
848
    setState(EngineSetupOk);
hjk's avatar
hjk committed
849
    showMessage(_("QUEUE: SETUP INFERIOR"));
850
    if (isMasterEngine())
851
852
853
854
855
        d->queueSetupInferior();
}

void DebuggerEngine::setupSlaveInferior()
{
856
    QTC_CHECK(state() == EngineSetupOk);
857
    d->queueSetupInferior();
858
859
}

hjk's avatar
hjk committed
860
void DebuggerEnginePrivate::doSetupInferior()
861
{
862
    m_engine->showMessage(_("CALL: SETUP INFERIOR"));
863
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << m_engine << state());
864
    m_progress.setProgressValue(250);
hjk's avatar
hjk committed
865
866
867
868
869
    m_engine->setupInferior();
}

void DebuggerEngine::notifyInferiorSetupFailed()
{
hjk's avatar
hjk committed
870
    showMessage(_("NOTE: INFERIOR SETUP FAILED"));
871
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << this << state());
872
    showStatusMessage(tr("Setup failed."));
hjk's avatar
hjk committed
873
    setState(InferiorSetupFailed);
874
875
    if (isMasterEngine())
        d->queueShutdownEngine();
hjk's avatar
hjk committed
876
877
878
879
}

void DebuggerEngine::notifyInferiorSetupOk()
{
hjk's avatar
hjk committed
880
    showMessage(_("NOTE: INFERIOR SETUP OK"));
881
882
883
884
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << this << state());
    setState(InferiorSetupOk);
    if (isMasterEngine())
        d->queueRunEngine();
hjk's avatar
hjk committed
885
886
}

887
888
889
void DebuggerEngine::runSlaveEngine()
{
    QTC_ASSERT(isSlaveEngine(), return);
890
    QTC_CHECK(state() == InferiorSetupOk);
891
892
893
    d->queueRunEngine();
}

hjk's avatar
hjk committed
894
895
void DebuggerEnginePrivate::doRunEngine()
{
hjk's avatar
hjk committed
896
    m_engine->showMessage(_("CALL: RUN ENGINE"));
897
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << m_engine << state());
898
    m_progress.setProgressValue(300);
hjk's avatar
hjk committed
899
900
901
    m_engine->runEngine();
}

hjk's avatar
hjk committed
902
903
void DebuggerEngine::notifyInferiorUnrunnable()
{
hjk's avatar
hjk committed
904
    showMessage(_("NOTE: INFERIOR UNRUNNABLE"));
905
906
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
907
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state());
908
    showStatusMessage(tr("Loading finished."));
hjk's avatar
hjk committed
909
910
911
912
913
    setState(InferiorUnrunnable);
}

void DebuggerEngine::notifyEngineRunFailed()
{
hjk's avatar
hjk committed
914
    showMessage(_("NOTE: ENGINE RUN FAILED"));
915
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state());
916
917
918
    d->m_progress.setProgressValue(900);
    d->m_progress.reportCanceled();
    d->m_progress.reportFinished();
919
    showStatusMessage(tr("Run failed."));
hjk's avatar
hjk committed
920
    setState(EngineRunFailed);
921
922
    if (isMasterEngine())
        d->queueShutdownEngine();
hjk's avatar
hjk committed
923
924
}

925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
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();
}

void DebuggerEngine::notifyEngineRemoteSetupDone()
{
    showMessage(_("NOTE: REMOTE SETUP DONE"));
    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);
}

void DebuggerEngine::notifyEngineRemoteSetupFailed()
{
    showMessage(_("NOTE: REMOTE SETUP FAILED"));
    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
965
966
void DebuggerEngine::notifyEngineRunAndInferiorRunOk()
{
hjk's avatar
hjk committed
967
    showMessage(_("NOTE: ENGINE RUN AND INFERIOR RUN OK"));
968
969
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
970
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state());
971
    showStatusMessage(tr("Running."));
hjk's avatar
hjk committed
972
    setState(InferiorRunOk);
hjk's avatar
hjk committed
973
974
975
976
}

void DebuggerEngine::notifyEngineRunAndInferiorStopOk()
{
hjk's avatar
hjk committed
977
    showMessage(_("NOTE: ENGINE RUN AND INFERIOR STOP OK"));
978
979
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
980
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state());
981
    showStatusMessage(tr("Stopped."));
hjk's avatar
hjk committed
982
    setState(InferiorStopOk);
hjk's avatar
hjk committed
983
984
985
986
}

void DebuggerEngine::notifyInferiorRunRequested()
{
hjk's avatar
hjk committed
987
    showMessage(_("NOTE: INFERIOR RUN REQUESTED"));
988
    QTC_ASSERT(state() == InferiorStopOk, qDebug() << this << state());
989
    showStatusMessage(tr("Run requested..."));
hjk's avatar
hjk committed
990
991
992
993
994
    setState(InferiorRunRequested);
}

void DebuggerEngine::notifyInferiorRunOk()
{
hjk's avatar
hjk committed
995
    showMessage(_("NOTE: INFERIOR RUN OK"));
996
    showStatusMessage(tr("Running."));
997
998
999
    // Transition from StopRequested can happen sin remotegdbadapter.
    QTC_ASSERT(state() == InferiorRunRequested
        || state() == InferiorStopRequested, qDebug() << this << state());
hjk's avatar
hjk committed
1000
1001
1002
1003
1004
    setState(InferiorRunOk);
}

void DebuggerEngine::notifyInferiorRunFailed()
{
hjk's avatar
hjk committed
1005
    showMessage(_("NOTE: INFERIOR RUN FAILED"));
1006
    QTC_ASSERT(state() == InferiorRunRequested, qDebug() << this << state());
hjk's avatar
hjk committed
1007
1008
    setState(InferiorRunFailed);
    setState(InferiorStopOk);
hjk's avatar
hjk committed
1009
1010
    if (isDying())
        d->queueShutdownInferior();
hjk's avatar
hjk committed
1011
1012
1013
1014
}

void DebuggerEngine::notifyInferiorStopOk()
{
hjk's avatar
hjk committed
1015
1016
    showMessage(_("NOTE: INFERIOR STOP OK"));
    // Ignore spurious notifications after we are set to die.
hjk's avatar
hjk committed
1017
    if (isDying()) {
hjk's avatar
hjk committed
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
        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();
        }
        showMessage(_("NOTE: ... IGNORING STOP MESSAGE"));
        return;
hjk's avatar
hjk committed
1031
    }
1032
    QTC_ASSERT(state() == InferiorStopRequested, qDebug() << this << state());
1033
    showStatusMessage(tr("Stopped."));
hjk's avatar
hjk committed
1034
    setState(InferiorStopOk);
<