debuggerengine.cpp 57.4 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 130
            << " environment=<" << sp.environment.size() << " variables>"
            << " workingDir=" << sp.workingDirectory
            << " attachPID=" << sp.attachPID
            << " useTerminal=" << sp.useTerminal
            << " remoteChannel=" << sp.remoteChannel
            << " symbolFileName=" << sp.symbolFileName
            << " 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
    }
185 186

    ~DebuggerEnginePrivate() {}
187

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

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

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

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

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

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

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

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

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

270 271
    TaskHub *taskHub();

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

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

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

    // The current state.
288 289
    DebuggerState m_state;

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

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

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

299 300 301 302 303 304 305 306
    qint64 m_inferiorPid;

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

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

    bool m_isStateDebugging;
316

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

583 584 585 586
    d->m_runControl = runControl;

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

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

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

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

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

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

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


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

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

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

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

665 666
// Called from RunControl.
void DebuggerEngine::handleFinished()
667
{
668
    showMessage(QLatin1String("HANDLE RUNCONTROL FINISHED"));
669
    d->m_runControl = 0;
670 671
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692
    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
693
DebuggerState DebuggerEngine::lastGoodState() const
694
{
hjk's avatar
hjk committed
695 696 697 698 699 700 701
    return d->m_lastGoodState;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hjk's avatar
hjk committed
864 865
void DebuggerEnginePrivate::doRunEngine()
{
hjk's avatar
hjk committed
866
    m_engine->showMessage(_("CALL: RUN ENGINE"));
867
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << m_engine << state());