debuggerengine.cpp 59.1 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
2
**
Eike Ziller's avatar
Eike Ziller committed
3 4
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
7
**
hjk's avatar
hjk committed
8 9 10 11
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
Eike Ziller's avatar
Eike Ziller committed
12 13
** a written agreement between you and The Qt Company.  For licensing terms and
** conditions see http://www.qt.io/terms-conditions.  For further information
Eike Ziller's avatar
Eike Ziller committed
14
** use the contact form at http://www.qt.io/contact-us.
15 16
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17
** Alternatively, this file may be used under the terms of the GNU Lesser
Eike Ziller's avatar
Eike Ziller committed
18 19 20 21 22 23
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
hjk's avatar
hjk committed
24
**
Eike Ziller's avatar
Eike Ziller committed
25 26
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
con's avatar
con committed
27 28
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
29
****************************************************************************/
30 31 32

#include "debuggerengine.h"

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

#include "breakhandler.h"
David Schulz's avatar
David Schulz committed
42
#include "disassembleragent.h"
43
#include "logwindow.h"
David Schulz's avatar
David Schulz committed
44
#include "memoryagent.h"
45
#include "moduleshandler.h"
46
#include "gdb/gdbengine.h" // REMOVE
47 48 49
#include "registerhandler.h"
#include "sourcefileshandler.h"
#include "stackhandler.h"
50
#include "terminal.h"
51 52
#include "threadshandler.h"
#include "watchhandler.h"
53
#include <debugger/shared/peutils.h>
54

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

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

66
#include <texteditor/texteditor.h>
67

68
#include <utils/fileinprojectfinder.h>
hjk's avatar
hjk committed
69 70 71
#include <utils/macroexpander.h>
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
72

73
#include <qmljs/consolemanagerinterface.h>
74

75 76 77
#include <QDebug>
#include <QTimer>
#include <QFileInfo>
78
#include <QDir>
79

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

85 86 87 88
enum { debug = 0 };

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

90 91 92 93
//#define WITH_BENCHMARK
#ifdef WITH_BENCHMARK
#include <valgrind/callgrind.h>
#endif
94

95 96
///////////////////////////////////////////////////////////////////////
//
97
// DebuggerRunParameters
98 99 100
//
///////////////////////////////////////////////////////////////////////

101
DebuggerRunParameters::DebuggerRunParameters()
102
    : isSnapshot(false),
103 104 105 106 107 108 109 110
      testCase(0)
{}

void DebuggerRunParameters::initialize(const DebuggerStartParameters &sp)
{
    DebuggerStartParameters::operator=(sp);
}

hjk's avatar
hjk committed
111 112 113
// VariableManager Prefix
const char PrefixDebugExecutable[]  = "DebuggedExecutable";

114 115
namespace Debugger {

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

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

hjk's avatar
hjk committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151
namespace 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;
    m_from = frame.from;
}

152

153 154 155 156 157 158
//////////////////////////////////////////////////////////////////////
//
// DebuggerEnginePrivate
//
//////////////////////////////////////////////////////////////////////

159 160 161 162 163 164 165 166 167
// transitions:
//   None->Requested
//   Requested->Succeeded
//   Requested->Failed
//   Requested->Cancelled
enum RemoteSetupState { RemoteSetupNone, RemoteSetupRequested,
                        RemoteSetupSucceeded, RemoteSetupFailed,
                        RemoteSetupCancelled };

168 169 170 171 172 173
struct TypeInfo
{
    TypeInfo(uint s = 0) : size(s) {}
    uint size;
};

174
class DebuggerEnginePrivate : public QObject
175
{
176 177
    Q_OBJECT

178
public:
179
    DebuggerEnginePrivate(DebuggerEngine *engine, const DebuggerRunParameters &sp)
180
      : m_engine(engine),
181
        m_masterEngine(0),
182
        m_runControl(0),
183
        m_runParameters(sp),
184
        m_state(DebuggerNotReady),
hjk's avatar
hjk committed
185
        m_lastGoodState(DebuggerNotReady),
Friedemann Kleint's avatar
Friedemann Kleint committed
186
        m_targetState(DebuggerNotReady),
187
        m_remoteSetupState(RemoteSetupNone),
188
        m_inferiorPid(0),
189
        m_modulesHandler(engine),
190
        m_registerHandler(),
191 192
        m_sourceFilesHandler(),
        m_stackHandler(),
hjk's avatar
hjk committed
193
        m_threadsHandler(),
194
        m_watchHandler(engine),
195
        m_disassemblerAgent(engine),
196
        m_memoryAgent(engine),
197
        m_isStateDebugging(false)
198
    {
hjk's avatar
hjk committed
199 200 201 202
        connect(&m_locationTimer, &QTimer::timeout,
                this, &DebuggerEnginePrivate::resetLocation);
        connect(action(IntelFlavor), &Utils::SavedAction::valueChanged,
                this, &DebuggerEnginePrivate::reloadDisassembly);
203 204 205
        connect(action(OperateNativeMixed), &QAction::triggered,
                engine, &DebuggerEngine::reloadFullStack);

hjk's avatar
hjk committed
206
        Utils::globalMacroExpander()->registerFileVariables(PrefixDebugExecutable,
207
            tr("Debugged executable"),
208
            [this]() { return m_runParameters.executable; });
209
    }
210

211
public slots:
212
    void doSetupEngine();
hjk's avatar
hjk committed
213 214
    void doSetupInferior();
    void doRunEngine();
hjk's avatar
hjk committed
215 216
    void doShutdownEngine();
    void doShutdownInferior();
217
    void doInterruptInferior();
hjk's avatar
hjk committed
218
    void doFinishDebugger();
hjk's avatar
hjk committed
219

220 221 222 223 224
    void reloadDisassembly()
    {
        m_disassemblerAgent.reload();
    }

225 226 227 228 229 230 231 232 233 234 235 236 237 238
    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()));
    }

239 240
    void queueRunEngine()
    {
hjk's avatar
hjk committed
241 242 243 244 245
        m_engine->setState(EngineRunRequested);
        m_engine->showMessage(_("QUEUE: RUN ENGINE"));
        QTimer::singleShot(0, this, SLOT(doRunEngine()));
    }

246 247
    void queueShutdownEngine()
    {
hjk's avatar
hjk committed
248 249 250 251 252
        m_engine->setState(EngineShutdownRequested);
        m_engine->showMessage(_("QUEUE: SHUTDOWN ENGINE"));
        QTimer::singleShot(0, this, SLOT(doShutdownEngine()));
    }

253 254
    void queueShutdownInferior()
    {
hjk's avatar
hjk committed
255 256 257 258 259
        m_engine->setState(InferiorShutdownRequested);
        m_engine->showMessage(_("QUEUE: SHUTDOWN INFERIOR"));
        QTimer::singleShot(0, this, SLOT(doShutdownInferior()));
    }

260 261
    void queueFinishDebugger()
    {
262 263 264
        QTC_ASSERT(state() == EngineShutdownOk
            || state() == EngineShutdownFailed, qDebug() << state());
        m_engine->setState(DebuggerFinished);
265 266 267 268 269
        resetLocation();
        if (isMasterEngine()) {
            m_engine->showMessage(_("QUEUE: FINISH DEBUGGER"));
            QTimer::singleShot(0, this, SLOT(doFinishDebugger()));
        }
hjk's avatar
hjk committed
270 271
    }

272 273
    void raiseApplication()
    {
274 275
        QTC_ASSERT(runControl(), return);
        runControl()->bringApplicationToForeground(m_inferiorPid);
276 277
    }

278
    void scheduleResetLocation()
279
    {
280
        m_stackHandler.scheduleResetLocation();
281
        m_watchHandler.scheduleResetLocation();
282
        m_threadsHandler.scheduleResetLocation();
283
        m_disassemblerAgent.scheduleResetLocation();
284 285 286 287
        m_locationTimer.setSingleShot(true);
        m_locationTimer.start(80);
    }

288
    void resetLocation()
289 290 291
    {
        m_locationTimer.stop();
        m_locationMark.reset();
292
        m_stackHandler.resetLocation();
293
        m_watchHandler.resetLocation();
294
        m_threadsHandler.resetLocation();
295
        m_disassemblerAgent.resetLocation();
hjk's avatar
hjk committed
296
        DebuggerToolTipManager::resetLocation();
297 298
    }

299
public:
hjk's avatar
hjk committed
300
    DebuggerState state() const { return m_state; }
301
    RemoteSetupState remoteSetupState() const { return m_remoteSetupState; }
302 303 304
    bool isMasterEngine() const { return m_engine->isMasterEngine(); }
    DebuggerRunControl *runControl() const
        { return m_masterEngine ? m_masterEngine->runControl() : m_runControl; }
305
    void setRemoteSetupState(RemoteSetupState state);
hjk's avatar
hjk committed
306

307
    DebuggerEngine *m_engine; // Not owned.
308
    DebuggerEngine *m_masterEngine; // Not owned
309 310
    DebuggerRunControl *m_runControl;  // Not owned.

311
    DebuggerRunParameters m_runParameters;
hjk's avatar
hjk committed
312 313

    // The current state.
314 315
    DebuggerState m_state;

hjk's avatar
hjk committed
316 317 318 319 320 321
    // The state we had before something unexpected happend.
    DebuggerState m_lastGoodState;

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

322 323 324
    // State of RemoteSetup signal/slots.
    RemoteSetupState m_remoteSetupState;

325
    Terminal m_terminal;
326 327 328 329 330 331 332 333
    qint64 m_inferiorPid;

    ModulesHandler m_modulesHandler;
    RegisterHandler m_registerHandler;
    SourceFilesHandler m_sourceFilesHandler;
    StackHandler m_stackHandler;
    ThreadsHandler m_threadsHandler;
    WatchHandler m_watchHandler;
334
    QFutureInterface<void> m_progress;
335

336 337
    DisassemblerAgent m_disassemblerAgent;
    MemoryAgent m_memoryAgent;
338
    QScopedPointer<TextMark> m_locationMark;
339
    QTimer m_locationTimer;
340 341

    bool m_isStateDebugging;
342

343
    Utils::FileInProjectFinder m_fileFinder;
344 345
    QHash<QByteArray, TypeInfo> m_typeInfoCache;
    QByteArray m_qtNamespace;
346 347 348 349 350 351 352 353 354
};


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

355
DebuggerEngine::DebuggerEngine(const DebuggerRunParameters &startParameters)
356
  : d(new DebuggerEnginePrivate(this, startParameters))
357
{}
358 359 360

DebuggerEngine::~DebuggerEngine()
{
361 362
    disconnect();
    delete d;
363 364
}

365 366 367 368 369 370 371 372 373 374 375
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)
376
        SN(InferiorSetupOk)
377 378 379 380 381 382 383 384
        SN(EngineRunRequested)
        SN(InferiorRunRequested)
        SN(InferiorRunOk)
        SN(InferiorRunFailed)
        SN(InferiorUnrunnable)
        SN(InferiorStopRequested)
        SN(InferiorStopOk)
        SN(InferiorStopFailed)
385
        SN(InferiorExitOk)
386 387 388 389 390 391 392 393 394 395 396 397
        SN(InferiorShutdownRequested)
        SN(InferiorShutdownOk)
        SN(InferiorShutdownFailed)
        SN(EngineShutdownRequested)
        SN(EngineShutdownOk)
        SN(EngineShutdownFailed)
        SN(DebuggerFinished)
    }
    return "<unknown>";
#    undef SN
}

398
void DebuggerEngine::showStatusMessage(const QString &msg, int timeout) const
399
{
400
    showMessage(msg, StatusBar, timeout);
401
}
402

403 404 405 406 407 408 409 410 411 412 413 414
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));
}

415 416 417 418
void DebuggerEngine::doUpdateLocals(const UpdateParameters &)
{
}

419 420 421 422 423
void DebuggerEngine::setTargetState(DebuggerState state)
{
    d->m_targetState = state;
}

424 425
ModulesHandler *DebuggerEngine::modulesHandler() const
{
426 427 428
    return d->m_masterEngine
        ? d->m_masterEngine->modulesHandler()
        : &d->m_modulesHandler;
429 430 431 432
}

RegisterHandler *DebuggerEngine::registerHandler() const
{
433 434 435
    return d->m_masterEngine
        ? d->m_masterEngine->registerHandler()
        : &d->m_registerHandler;
436 437 438 439
}

StackHandler *DebuggerEngine::stackHandler() const
{
Aurindam Jana's avatar
Aurindam Jana committed
440 441 442
    return d->m_masterEngine
        ? d->m_masterEngine->stackHandler()
        : &d->m_stackHandler;
443 444 445 446
}

ThreadsHandler *DebuggerEngine::threadsHandler() const
{
447 448 449
    return d->m_masterEngine
        ? d->m_masterEngine->threadsHandler()
        : &d->m_threadsHandler;
450 451 452 453
}

WatchHandler *DebuggerEngine::watchHandler() const
{
454 455 456
    return d->m_masterEngine
        ? d->m_masterEngine->watchHandler()
        : &d->m_watchHandler;
457 458 459 460
}

SourceFilesHandler *DebuggerEngine::sourceFilesHandler() const
{
461 462 463
    return d->m_masterEngine
        ? d->m_masterEngine->sourceFilesHandler()
        : &d->m_sourceFilesHandler;
464 465 466 467
}

QAbstractItemModel *DebuggerEngine::modulesModel() const
{
468
   return modulesHandler()->model();
469 470 471 472
}

QAbstractItemModel *DebuggerEngine::registerModel() const
{
473
    return registerHandler()->model();
474 475 476 477
}

QAbstractItemModel *DebuggerEngine::stackModel() const
{
478
    return stackHandler()->model();
479 480 481 482
}

QAbstractItemModel *DebuggerEngine::threadsModel() const
{
483
    return threadsHandler()->model();
484 485
}

hjk's avatar
hjk committed
486 487 488
QAbstractItemModel *DebuggerEngine::watchModel() const
{
    return watchHandler()->model();
489 490
}

491 492
QAbstractItemModel *DebuggerEngine::sourceFilesModel() const
{
493
    return sourceFilesHandler()->model();
494 495
}

496
void DebuggerEngine::fetchMemory(MemoryAgent *, QObject *,
497 498 499 500 501 502
        quint64 addr, quint64 length)
{
    Q_UNUSED(addr);
    Q_UNUSED(length);
}

hjk's avatar
hjk committed
503 504 505 506 507 508 509
void DebuggerEngine::changeMemory(MemoryAgent *, QObject *,
        quint64 addr, const QByteArray &data)
{
    Q_UNUSED(addr);
    Q_UNUSED(data);
}

hjk's avatar
hjk committed
510
void DebuggerEngine::setRegisterValue(const QByteArray &name, const QString &value)
511
{
hjk's avatar
hjk committed
512
    Q_UNUSED(name);
513 514 515 516 517
    Q_UNUSED(value);
}

void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) const
{
518 519 520 521
    if (d->m_masterEngine) {
        d->m_masterEngine->showMessage(msg, channel, timeout);
        return;
    }
522 523
    //if (msg.size() && msg.at(0).isUpper() && msg.at(1).isUpper())
    //    qDebug() << qPrintable(msg) << "IN STATE" << state();
524
    QmlJS::ConsoleManagerInterface *consoleManager = QmlJS::ConsoleManagerInterface::instance();
525
    if (channel == ConsoleOutput && consoleManager)
526
        consoleManager->printToConsolePane(QmlJS::ConsoleItem::UndefinedType, msg);
527

528
    Internal::showMessage(msg, channel, timeout);
529 530 531 532 533 534 535 536 537 538 539 540 541
    if (d->m_runControl) {
        switch (channel) {
            case AppOutput:
                d->m_runControl->appendMessage(msg, Utils::StdOutFormatSameLine);
                break;
            case AppError:
                d->m_runControl->appendMessage(msg, Utils::StdErrFormatSameLine);
                break;
            case AppStuff:
                d->m_runControl->appendMessage(msg, Utils::DebugFormat);
                break;
        }
    } else {
542
        qWarning("Warning: %s (no active run control)", qPrintable(msg));
543
    }
544 545 546 547
}

void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
{
548 549
    QTC_ASSERT(runControl, notifyEngineSetupFailed(); return);
    QTC_ASSERT(!d->m_runControl, notifyEngineSetupFailed(); return);
550

551
    d->m_progress.setProgressRange(0, 1000);
552
    FutureProgress *fp = ProgressManager::addTask(d->m_progress.future(),
553
        tr("Launching Debugger"), "Debugger.Launcher");
hjk's avatar
hjk committed
554
    connect(fp, &FutureProgress::canceled, this, &DebuggerEngine::quitDebugger);
555
    fp->setKeepOnFinish(FutureProgress::HideOnFinish);
556 557
    d->m_progress.reportStarted();

558 559
    d->m_runControl = runControl;

560 561
    d->m_inferiorPid = d->m_runParameters.attachPID > 0
        ? d->m_runParameters.attachPID : 0;
562 563
    if (d->m_inferiorPid)
        d->m_runControl->setApplicationProcessHandle(ProcessHandle(d->m_inferiorPid));
564

565 566
    if (!d->m_runParameters.environment.size())
        d->m_runParameters.environment = Utils::Environment();
567

568 569 570
    if (isNativeMixedActive())
        d->m_runParameters.environment.set(QLatin1String("QV4_FORCE_INTERPRETER"), QLatin1String("1"));

hjk's avatar
hjk committed
571
    action(OperateByInstruction)->setEnabled(hasCapability(DisassemblerCapability));
572

573 574
    QTC_ASSERT(state() == DebuggerNotReady || state() == DebuggerFinished,
         qDebug() << state());
575 576
    d->m_lastGoodState = DebuggerNotReady;
    d->m_targetState = DebuggerNotReady;
577
    d->m_progress.setProgressValue(200);
578 579 580 581 582 583 584 585 586 587 588 589 590 591

    d->m_terminal.setup();
    if (d->m_terminal.isUsable()) {
        connect(&d->m_terminal, &Terminal::stdOutReady, [this, runControl](const QString &msg) {
            runControl->appendMessage(msg, Utils::StdOutFormatSameLine);
        });
        connect(&d->m_terminal, &Terminal::stdErrReady, [this, runControl](const QString &msg) {
            runControl->appendMessage(msg, Utils::StdErrFormatSameLine);
        });
        connect(&d->m_terminal, &Terminal::error, [this, runControl](const QString &msg) {
            runControl->appendMessage(msg, Utils::ErrorMessageFormat);
        });
    }

592
    d->queueSetupEngine();
593 594 595 596
}

void DebuggerEngine::resetLocation()
{
597 598
    // Do it after some delay to avoid flicker.
    d->scheduleResetLocation();
599 600
}

601
void DebuggerEngine::gotoLocation(const Location &loc)
602
{
Aurindam Jana's avatar
Aurindam Jana committed
603 604
     d->resetLocation();

605 606 607 608
    if (loc.canBeDisassembled()
            && ((hasCapability(OperateByInstructionCapability) && boolSetting(OperateByInstruction))
                || !loc.hasDebugInfo()) )
    {
609 610 611
        d->m_disassemblerAgent.setLocation(loc);
        return;
    }
612

613 614 615 616
    if (loc.fileName().isEmpty()) {
        showMessage(QLatin1String("CANNOT GO TO THIS LOCATION"));
        return;
    }
617
    const QString file = QDir::cleanPath(loc.fileName());
618
    const int line = loc.lineNumber();
619
    bool newEditor = false;
620
    IEditor *editor = EditorManager::openEditor(file, Id(),
621 622
                                                EditorManager::IgnoreNavigationHistory, &newEditor);
    QTC_ASSERT(editor, return); // Unreadable file?
623

hjk's avatar
hjk committed
624
    editor->gotoLine(line, 0, !boolSetting(StationaryEditorWhileStepping));
625

626 627
    if (newEditor)
        editor->document()->setProperty(Constants::OPENED_BY_DEBUGGER, true);
hjk's avatar
hjk committed
628

629
    if (loc.needsMarker()) {
630
        d->m_locationMark.reset(new TextMark(file, line, Constants::TEXT_MARK_CATEGORY_LOCATION));
631
        d->m_locationMark->setIcon(Internal::locationMarkIcon());
632
        d->m_locationMark->setPriority(TextMark::HighPriority);
633
    }
634 635

    //qDebug() << "MEMORY: " << d->m_memoryAgent.hasVisibleEditor();
636 637
}

638 639 640
// Called from RunControl.
void DebuggerEngine::handleStartFailed()
{
641
    showMessage(QLatin1String("HANDLE RUNCONTROL START FAILED"));
642
    d->m_runControl = 0;
643
    d->m_progress.setProgressValue(900);
644 645
    d->m_progress.reportCanceled();
    d->m_progress.reportFinished();
646 647
}

648 649
// Called from RunControl.
void DebuggerEngine::handleFinished()
650
{
651
    showMessage(QLatin1String("HANDLE RUNCONTROL FINISHED"));
652
    d->m_runControl = 0;
653 654
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
655 656 657 658 659 660
    modulesHandler()->removeAll();
    stackHandler()->removeAll();
    threadsHandler()->removeAll();
    watchHandler()->cleanup();
}

661
const DebuggerRunParameters &DebuggerEngine::runParameters() const
662
{
663
    return d->m_runParameters;
664 665
}

666
DebuggerRunParameters &DebuggerEngine::runParameters()
667
{
668
    return d->m_runParameters;
669 670 671 672 673 674 675
}

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

hjk's avatar
hjk committed
676
DebuggerState DebuggerEngine::lastGoodState() const
677
{
hjk's avatar
hjk committed
678 679 680 681 682 683 684
    return d->m_lastGoodState;
}

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

hjk's avatar
hjk committed
686 687 688
static bool isAllowedTransition(DebuggerState from, DebuggerState to)
{
    switch (from) {
689
    case DebuggerNotReady:
690
        return to == EngineSetupRequested;
691

hjk's avatar
hjk committed
692
    case EngineSetupRequested:
693 694
        return to == EngineSetupOk || to == EngineSetupFailed;
    case EngineSetupFailed:
695 696 697
        // In is the engine's task to go into a proper "Shutdown"
        // state before calling notifyEngineSetupFailed
        return to == DebuggerFinished;
698
    case EngineSetupOk:
hjk's avatar
hjk committed
699
        return to == InferiorSetupRequested || to == EngineShutdownRequested;
700

hjk's avatar
hjk committed
701
    case InferiorSetupRequested:
702
        return to == InferiorSetupOk || to == InferiorSetupFailed;
hjk's avatar
hjk committed
703
    case InferiorSetupFailed:
hjk's avatar
hjk committed
704
        return to == EngineShutdownRequested;
705 706
    case InferiorSetupOk:
        return to == EngineRunRequested;
hjk's avatar
hjk committed
707 708

    case EngineRunRequested:
hjk's avatar
hjk committed
709
        return to == EngineRunFailed
710
            || to == InferiorRunRequested
hjk's avatar
hjk committed
711 712 713
            || to == InferiorRunOk
            || to == InferiorStopOk
            || to == InferiorUnrunnable;
hjk's avatar
hjk committed
714
    case EngineRunFailed:
715
        return to == EngineShutdownRequested;
hjk's avatar
hjk committed
716 717 718 719 720 721

    case InferiorRunRequested:
        return to == InferiorRunOk || to == InferiorRunFailed;
    case InferiorRunFailed:
        return to == InferiorStopOk;
    case InferiorRunOk:
722 723 724
        return to == InferiorStopRequested
            || to == InferiorStopOk // A spontaneous stop.
            || to == InferiorExitOk;
hjk's avatar
hjk committed
725 726 727 728 729

    case InferiorStopRequested:
        return to == InferiorStopOk || to == InferiorStopFailed;
    case InferiorStopOk:
        return to == InferiorRunRequested || to == InferiorShutdownRequested
Orgad Shaneh's avatar
Orgad Shaneh committed
730
            || to == InferiorStopOk || to == InferiorExitOk;
731
    case InferiorStopFailed:
hjk's avatar
hjk committed
732
        return to == EngineShutdownRequested;
733

734 735 736
    case InferiorExitOk:
        return to == InferiorShutdownOk;

737
    case InferiorUnrunnable:
hjk's avatar
hjk committed
738 739 740 741 742
        return to == InferiorShutdownRequested;
    case InferiorShutdownRequested:
        return to == InferiorShutdownOk || to == InferiorShutdownFailed;
    case InferiorShutdownOk:
        return to == EngineShutdownRequested;
743
    case InferiorShutdownFailed:
hjk's avatar
hjk committed
744
        return to == EngineShutdownRequested;
745

hjk's avatar
hjk committed
746
    case EngineShutdownRequested:
747
        return to == EngineShutdownOk || to == EngineShutdownFailed;
hjk's avatar
hjk committed
748 749 750 751 752 753
    case EngineShutdownOk:
        return to == DebuggerFinished;
    case EngineShutdownFailed:
        return to == DebuggerFinished;

    case DebuggerFinished:
754
        return to == EngineSetupRequested; // Happens on restart.
755 756
    }

757
    qDebug() << "UNKNOWN DEBUGGER STATE:" << from;
758 759 760
    return false;
}

761 762
void DebuggerEngine::setupSlaveEngine()
{
763
    QTC_CHECK(state() == DebuggerNotReady);
764 765 766 767 768 769 770
    d->queueSetupEngine();
}

void DebuggerEnginePrivate::doSetupEngine()
{
    m_engine->showMessage(_("CALL: SETUP ENGINE"));
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << m_engine << state());
771
    m_engine->validateExecutable(&m_runParameters);
772 773 774
    m_engine->setupEngine();
}

775
void DebuggerEngine::notifyEngineSetupFailed()
hjk's avatar
hjk committed
776
{
hjk's avatar
hjk committed
777
    showMessage(_("NOTE: ENGINE SETUP FAILED"));
778 779 780 781 782 783 784
    QTC_ASSERT(d->remoteSetupState() == RemoteSetupNone
               || d->remoteSetupState() == RemoteSetupRequested
               || d->remoteSetupState() == RemoteSetupSucceeded,
               qDebug() << this << "remoteSetupState" << d->remoteSetupState());
    if (d->remoteSetupState() == RemoteSetupRequested)
        d->setRemoteSetupState(RemoteSetupCancelled);

785
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
786
    setState(EngineSetupFailed);
hjk's avatar
hjk committed
787
    if (isMasterEngine() && runControl())
788
        runControl()->startFailed();
hjk's avatar
hjk committed
789
    setState(DebuggerFinished);
hjk's avatar
hjk committed
790 791
}

792
void DebuggerEngine::notifyEngineSetupOk()
793
{
hjk's avatar
hjk committed
794
    showMessage(_("NOTE: ENGINE SETUP OK"));
795 796 797 798
    QTC_ASSERT(d->remoteSetupState() == RemoteSetupNone
               || d->remoteSetupState() == RemoteSetupSucceeded,
               qDebug() << this << "remoteSetupState" << d->remoteSetupState());

799
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
800
    setState(EngineSetupOk);
hjk's avatar
hjk committed
801
    showMessage(_("QUEUE: SETUP INFERIOR"));
802
    if (isMasterEngine())
803 804 805 806 807
        d->queueSetupInferior();
}

void DebuggerEngine::setupSlaveInferior()
{
808
    QTC_CHECK(state() == EngineSetupOk);
809
    d->queueSetupInferior();
810 811
}

hjk's avatar
hjk committed
812
void DebuggerEnginePrivate::doSetupInferior()
813
{
814
    m_engine->showMessage(_("CALL: SETUP INFERIOR"));
815
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << m_engine << state());
816
    m_progress.setProgressValue(250);
hjk's avatar
hjk committed
817 818 819 820 821
    m_engine->setupInferior();
}

void DebuggerEngine::notifyInferiorSetupFailed()
{
hjk's avatar
hjk committed
822
    showMessage(_("NOTE: INFERIOR SETUP FAILED"));
823
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << this << state());
824
    showStatusMessage(tr("Setup failed."));
hjk's avatar
hjk committed
825
    setState(InferiorSetupFailed);
826 827
    if (isMasterEngine())
        d->queueShutdownEngine();
hjk's avatar
hjk committed
828 829 830 831
}

void DebuggerEngine::notifyInferiorSetupOk()
{
832 833 834
#ifdef WITH_BENCHMARK
    CALLGRIND_START_INSTRUMENTATION;
#endif
hjk's avatar
hjk committed
835
    aboutToNotifyInferiorSetupOk();