debuggerengine.cpp 56.8 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

64 65 66
#include <projectexplorer/taskhub.h>
#include <extensionsystem/pluginmanager.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 180
        m_testsPossible(true),
        m_taskHub(0)
181
    {
182
        connect(&m_locationTimer, SIGNAL(timeout()), SLOT(resetLocation()));
183
        if (sp.toolChainAbi.os() == Abi::MacOS)
con's avatar
con committed
184
            m_disassemblerAgent.setTryMixed(false);
185
    }
186 187

    ~DebuggerEnginePrivate() {}
188

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

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

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

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

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

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

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

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

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

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

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

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

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

    // The current state.
287 288
    DebuggerState m_state;

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

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

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

298 299 300 301 302 303 304 305
    qint64 m_inferiorPid;

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

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

    bool m_isStateDebugging;
315

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


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

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

DebuggerEngine::~DebuggerEngine()
{
346 347
    disconnect();
    delete d;
348 349
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

584 585 586 587
    d->m_runControl = runControl;

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

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

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

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

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

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

615 616 617 618
    if (debuggerCore()->boolSetting(OperateByInstruction) || !loc.hasDebugInfo()) {
        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 627
    EditorManager *editorManager = EditorManager::instance();
    QList<IEditor *> editors = editorManager->editorsForFileName(file);
628
    IEditor *editor = 0;
hjk's avatar
hjk committed
629
    if (editors.isEmpty()) {
hjk's avatar
hjk committed
630
        editor = editorManager->openEditor(file, Core::Id(),
631 632 633 634 635 636 637
            EditorManager::IgnoreNavigationHistory);
        if (editor) {
            editors.append(editor);
            editor->setProperty(Constants::OPENED_BY_DEBUGGER, true);
        }
    } else {
        editor = editors.back();
hjk's avatar
hjk committed
638
    }
639
    ITextEditor *texteditor = qobject_cast<ITextEditor *>(editor);
hjk's avatar
hjk committed
640 641 642
    if (texteditor)
        texteditor->gotoLine(line, 0);

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

    // FIXME: Breaks with split views.
650
    if (!d->m_memoryAgent.hasVisibleEditor() || loc.needsRaise())
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 693 694 695 696 697 698 699
    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
700
    return debuggerCore()->boolSetting(UseDebuggingHelpers);
701 702 703 704 705 706 707 708 709
}

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

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

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

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

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

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

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

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

hjk's avatar
hjk committed
748
    case InferiorSetupRequested:
749
        return to == InferiorSetupOk || to == InferiorSetupFailed;
hjk's avatar
hjk committed
750
    case InferiorSetupFailed:
hjk's avatar
hjk committed
751
        return to == EngineShutdownRequested;
752 753
    case InferiorSetupOk:
        return to == EngineRunRequested;
hjk's avatar
hjk committed
754 755

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

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

    case InferiorStopRequested:
        return to == InferiorStopOk || to == InferiorStopFailed;
    case InferiorStopOk:
        return to == InferiorRunRequested || to == InferiorShutdownRequested
776
            || to == InferiorStopOk || InferiorExitOk;
777
    case InferiorStopFailed:
hjk's avatar
hjk committed
778
        return to == EngineShutdownRequested;
779

780 781 782
    case InferiorExitOk:
        return to == InferiorShutdownOk;

783
    case InferiorUnrunnable:
hjk's avatar
hjk committed
784 785 786 787 788
        return to == InferiorShutdownRequested;
    case InferiorShutdownRequested:
        return to == InferiorShutdownOk || to == InferiorShutdownFailed;
    case InferiorShutdownOk:
        return to == EngineShutdownRequested;
789
    case InferiorShutdownFailed:
hjk's avatar
hjk committed
790
        return to == EngineShutdownRequested;
791

hjk's avatar
hjk committed
792
    case EngineShutdownRequested:
793
        return to == EngineShutdownOk || to == EngineShutdownFailed;
hjk's avatar
hjk committed
794 795 796 797 798 799
    case EngineShutdownOk:
        return to == DebuggerFinished;
    case EngineShutdownFailed:
        return to == DebuggerFinished;

    case DebuggerFinished:
800
        return to == EngineSetupRequested; // Happens on restart.
801 802
    }

803
    qDebug() << "UNKNOWN DEBUGGER STATE:" << from;
804 805 806
    return false;
}

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

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

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

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

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

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

void DebuggerEngine::setupSlaveInferior()
{
853
    QTC_CHECK(state() == EngineSetupOk);
854
    d->queueSetupInferior();
855 856
}

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

void DebuggerEngine::notifyInferiorSetupFailed()
{
hjk's avatar
hjk committed
867
    showMessage(_("NOTE: INFERIOR SETUP FAILED"));
868
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << this << state());
hjk's avatar
hjk committed
869
    setState(InferiorSetupFailed);
870 871
    if (isMasterEngine())
        d->queueShutdownEngine();
hjk's avatar
hjk committed
872 873 874 875
}

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

883 884 885
void DebuggerEngine::runSlaveEngine()
{
    QTC_ASSERT(isSlaveEngine(), return);
886
    QTC_CHECK(state() == InferiorSetupOk);