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"));
hjk's avatar