debuggerengine.cpp 50.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "debuggerengine.h"

#include "debuggeractions.h"
#include "debuggeragents.h"
#include "debuggerrunner.h"
#include "debuggerplugin.h"
#include "debuggerstringutils.h"
37
#include "debuggertooltip.h"
38
#include "logwindow.h"
39
40
41
42
43
44
45
46
47

#include "breakhandler.h"
#include "moduleshandler.h"
#include "registerhandler.h"
#include "snapshothandler.h"
#include "sourcefileshandler.h"
#include "stackhandler.h"
#include "threadshandler.h"
#include "watchhandler.h"
hjk's avatar
hjk committed
48
#include "watchutils.h"
49
#include "breakwindow.h"
50

hjk's avatar
hjk committed
51
#include <coreplugin/icore.h>
52
#include <coreplugin/ifile.h>
hjk's avatar
hjk committed
53
#include <coreplugin/editormanager/editormanager.h>
54
55
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
hjk's avatar
hjk committed
56

57
#include <projectexplorer/toolchaintype.h>
58
59
60

#include <qt4projectmanager/qt4projectmanagerconstants.h>

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

63
#include <utils/environment.h>
64
65
66
67
68
#include <utils/savedaction.h>
#include <utils/qtcassert.h>

#include <QtCore/QDebug>
#include <QtCore/QTimer>
69
#include <QtCore/QFutureInterface>
70
71
72
73

#include <QtGui/QAbstractItemView>
#include <QtGui/QStandardItemModel>
#include <QtGui/QAction>
74
#include <QtGui/QMenu>
75
#include <QtGui/QMessageBox>
hjk's avatar
hjk committed
76
#include <QtGui/QPlainTextEdit>
77
#include <QtGui/QPushButton>
hjk's avatar
hjk committed
78
79
#include <QtGui/QTextBlock>
#include <QtGui/QTextCursor>
80
#include <QtGui/QTreeWidget>
81
#include <QtGui/QMainWindow>
82

hjk's avatar
hjk committed
83
using namespace Core;
84
85
using namespace Debugger;
using namespace Debugger::Internal;
hjk's avatar
hjk committed
86
87
using namespace ProjectExplorer;
using namespace TextEditor;
88

hjk's avatar
hjk committed
89
90
91
92
93
94
95
//#define DEBUG_STATE 1
#if DEBUG_STATE
#   define SDEBUG(s) qDebug() << s
#else
#   define SDEBUG(s)
#endif
# define XSDEBUG(s) qDebug() << s
96
97
98
99
100
101
102

///////////////////////////////////////////////////////////////////////
//
// DebuggerStartParameters
//
///////////////////////////////////////////////////////////////////////

103
DebuggerStartParameters::DebuggerStartParameters() :
104
    isSnapshot(false),
105
106
    attachPID(-1),
    useTerminal(false),
107
108
    breakAtMain(false),
    qmlServerAddress("127.0.0.1"),
109
    qmlServerPort(0),
hjk's avatar
hjk committed
110
    useServerStartScript(false),
111
    connParams(SshConnectionParameters::NoProxy),
112
    toolChainType(ToolChain_UNKNOWN),
113
114
    startMode(NoStartMode),
    executableUid(0)
115
116
117
118
119
120
121
122
123
124
125
126
{}

void DebuggerStartParameters::clear()
{
    *this = DebuggerStartParameters();
}


namespace Debugger {

QDebug operator<<(QDebug d, DebuggerState state)
{
hjk's avatar
hjk committed
127
128
    //return d << DebuggerEngine::stateName(state) << '(' << int(state) << ')';
    return d << DebuggerEngine::stateName(state);
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
}

QDebug operator<<(QDebug str, const DebuggerStartParameters &sp)
{
    QDebug nospace = str.nospace();
    const QString sep = QString(QLatin1Char(','));
    nospace << "executable=" << sp.executable
            << " coreFile=" << sp.coreFile
            << " processArgs=" << sp.processArgs.join(sep)
            << " 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
145
            << " useServerStartScript=" << sp.useServerStartScript
146
147
148
149
150
151
152
153
154
155
            << " serverStartScript=" << sp.serverStartScript
            << " toolchain=" << sp.toolChainType << '\n';
    return str;
}

const char *DebuggerEngine::stateName(int s)
{
#    define SN(x) case x: return #x;
    switch (s) {
        SN(DebuggerNotReady)
hjk's avatar
hjk committed
156
        SN(EngineSetupRequested)
157
158
        SN(EngineSetupOk)
        SN(EngineSetupFailed)
hjk's avatar
hjk committed
159
160
        SN(EngineRunFailed)
        SN(InferiorSetupRequested)
hjk's avatar
hjk committed
161
        SN(InferiorSetupFailed)
hjk's avatar
hjk committed
162
163
164
165
        SN(EngineRunRequested)
        SN(InferiorRunRequested)
        SN(InferiorRunOk)
        SN(InferiorRunFailed)
166
        SN(InferiorUnrunnable)
hjk's avatar
hjk committed
167
168
        SN(InferiorStopRequested)
        SN(InferiorStopOk)
169
        SN(InferiorStopFailed)
hjk's avatar
hjk committed
170
171
        SN(InferiorShutdownRequested)
        SN(InferiorShutdownOk)
172
        SN(InferiorShutdownFailed)
hjk's avatar
hjk committed
173
174
175
176
        SN(EngineShutdownRequested)
        SN(EngineShutdownOk)
        SN(EngineShutdownFailed)
        SN(DebuggerFinished)
177
178
179
180
181
    }
    return "<unknown>";
#    undef SN
}

182

183
184
185
186
187
188
189
190
191
//////////////////////////////////////////////////////////////////////
//
// CommandHandler
//
//////////////////////////////////////////////////////////////////////

class CommandHandler : public QStandardItemModel
{
public:
192
    explicit CommandHandler(DebuggerEngine *engine) : m_engine(engine) {}
193
194
195
196
    bool setData(const QModelIndex &index, const QVariant &value, int role);
    QAbstractItemModel *model() { return this; }

private:
197
    QPointer<DebuggerEngine> m_engine;
198
199
};

200
bool CommandHandler::setData(const QModelIndex &, const QVariant &value, int role)
201
{
202
    QTC_ASSERT(m_engine, qDebug() << value << role; return false);
203
204
    m_engine->handleCommand(role, value);
    return true;
205
206
207
208
209
210
211
212
}

//////////////////////////////////////////////////////////////////////
//
// DebuggerEnginePrivate
//
//////////////////////////////////////////////////////////////////////

213
class DebuggerEnginePrivate : public QObject
214
{
215
216
    Q_OBJECT

217
218
219
220
public:
    DebuggerEnginePrivate(DebuggerEngine *engine, const DebuggerStartParameters &sp)
      : m_engine(engine),
        m_runControl(0),
221
        m_isActive(false),
222
223
        m_startParameters(sp),
        m_state(DebuggerNotReady),
hjk's avatar
hjk committed
224
        m_lastGoodState(DebuggerNotReady),
Friedemann Kleint's avatar
Friedemann Kleint committed
225
        m_targetState(DebuggerNotReady),
226
227
228
229
230
231
232
        m_commandHandler(engine),
        m_modulesHandler(engine),
        m_registerHandler(engine),
        m_sourceFilesHandler(engine),
        m_stackHandler(engine),
        m_threadsHandler(engine),
        m_watchHandler(engine),
233
        m_disassemblerViewAgent(engine),
234
        m_isSlaveEngine(false)
235
    {}
236
237

    ~DebuggerEnginePrivate() {}
238

239
240
241
242
243
public slots:
    void breakpointSetRemoveMarginActionTriggered();
    void breakpointEnableDisableMarginActionTriggered();
    void handleContextMenuRequest(const QVariant &parameters);

hjk's avatar
hjk committed
244
245
    void doSetupInferior();
    void doRunEngine();
hjk's avatar
hjk committed
246
247
    void doShutdownEngine();
    void doShutdownInferior();
248
    void doInterruptInferior();
hjk's avatar
hjk committed
249
    void doFinishDebugger();
hjk's avatar
hjk committed
250

hjk's avatar
hjk committed
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
    void queueRunEngine() {
        m_engine->setState(EngineRunRequested);
        m_engine->showMessage(_("QUEUE: RUN ENGINE"));
        QTimer::singleShot(0, this, SLOT(doRunEngine()));
    }

    void queueShutdownEngine() {
        m_engine->setState(EngineShutdownRequested);
        m_engine->showMessage(_("QUEUE: SHUTDOWN ENGINE"));
        QTimer::singleShot(0, this, SLOT(doShutdownEngine()));
    }

    void queueShutdownInferior() {
        m_engine->setState(InferiorShutdownRequested);
        m_engine->showMessage(_("QUEUE: SHUTDOWN INFERIOR"));
        QTimer::singleShot(0, this, SLOT(doShutdownInferior()));
    }

    void queueFinishDebugger() {
270
271
272
273
        QTC_ASSERT(state() == EngineShutdownOk
            || state() == EngineShutdownFailed, qDebug() << state());
        m_engine->setState(DebuggerFinished);
        m_engine->showMessage(_("QUEUE: FINISH DEBUGGER"));
hjk's avatar
hjk committed
274
275
276
        QTimer::singleShot(0, this, SLOT(doFinishDebugger()));
    }

277
    void raiseApplication() {
hjk's avatar
hjk committed
278
        QTC_ASSERT(m_runControl, return);
279
280
281
        m_runControl->bringApplicationToForeground(m_inferiorPid);
    }

282
283
private slots:
    void slotEditBreakpoint();
284
285
    void slotRunToLine();
    void slotJumpToLine();
286

287
public:
hjk's avatar
hjk committed
288
289
    DebuggerState state() const { return m_state; }

290
291
    DebuggerEngine *m_engine; // Not owned.
    DebuggerRunControl *m_runControl;  // Not owned.
292
    bool m_isActive;
293
294

    DebuggerStartParameters m_startParameters;
hjk's avatar
hjk committed
295
296

    // The current state.
297
298
    DebuggerState m_state;

hjk's avatar
hjk committed
299
300
301
302
303
304
    // The state we had before something unexpected happend.
    DebuggerState m_lastGoodState;

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

305
306
307
308
309
310
311
312
313
314
    qint64 m_inferiorPid;

    CommandHandler m_commandHandler;
    ModulesHandler m_modulesHandler;
    RegisterHandler m_registerHandler;
    SourceFilesHandler m_sourceFilesHandler;
    StackHandler m_stackHandler;
    ThreadsHandler m_threadsHandler;
    WatchHandler m_watchHandler;
    DisassemblerViewAgent m_disassemblerViewAgent;
315
    QFutureInterface<void> m_progress;
316

317
    bool m_isSlaveEngine;
318
319
};

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
// Retrieve file name and line and optionally address
// from the data set on the text editor context menu action.
static bool positionFromContextActionData(const QObject *sender,
                                          QString *fileName,
                                          int *lineNumber,
                                          quint64 *address = 0)
{
    if (const QAction *action = qobject_cast<const QAction *>(sender)) {
        const QVariantList data = action->data().toList();
        if (data.size() >= (address ? 3 : 2)) {
            *fileName = data.front().toString();
            *lineNumber = data.at(1).toInt();
            if (address)
                *address = data.at(2).toULongLong();
            return true;
        }
    }
    return false;
}

340
341
void DebuggerEnginePrivate::breakpointSetRemoveMarginActionTriggered()
{
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
    QString fileName;
    int lineNumber;
    quint64 address;
    if (positionFromContextActionData(sender(), &fileName, &lineNumber, &address))
        m_engine->breakHandler()->toggleBreakpoint(fileName, lineNumber, address);
 }


void DebuggerEnginePrivate::slotRunToLine()
{
    // Run to line, file name and line number set as list.
    QString fileName;
    int lineNumber;
    if (positionFromContextActionData(sender(), &fileName, &lineNumber)) {
        m_engine->resetLocation();
        m_engine->executeRunToLine(fileName, lineNumber);
    }
}

void DebuggerEnginePrivate::slotJumpToLine()
{
    QString fileName;
    int lineNumber;
    if (positionFromContextActionData(sender(), &fileName, &lineNumber))
        m_engine->executeJumpToLine(fileName, lineNumber);
}

 void DebuggerEnginePrivate::breakpointEnableDisableMarginActionTriggered()
{
    QString fileName;
    int lineNumber;
    if (positionFromContextActionData(sender(), &fileName, &lineNumber))
        m_engine->breakHandler()->toggleBreakpointEnabled(fileName, lineNumber);
375
376
}

377
378
379
380
381
382
383
void DebuggerEnginePrivate::slotEditBreakpoint()
{
    const QAction *act = qobject_cast<QAction *>(sender());
    QTC_ASSERT(act, return);
    const QVariant data = act->data();
    QTC_ASSERT(qVariantCanConvert<BreakpointData *>(data), return);
    BreakpointData *breakPointData = qvariant_cast<BreakpointData *>(data);
Arvid Ephraim Picciani's avatar
Arvid Ephraim Picciani committed
384
    BreakWindow::editBreakpoint(breakPointData, ICore::instance()->mainWindow());
385
386
}

387
388
389
void DebuggerEnginePrivate::handleContextMenuRequest(const QVariant &parameters)
{
    const QList<QVariant> list = parameters.toList();
390
    QTC_ASSERT(list.size() == 3, qDebug() << list; return);
391
392
    TextEditor::ITextEditor *editor =
        (TextEditor::ITextEditor *)(list.at(0).value<quint64>());
393
    const int lineNumber = list.at(1).toInt();
394
395
396
397
    QMenu *menu = (QMenu *)(list.at(2).value<quint64>());

    BreakpointData *data = 0;
    QString fileName;
398
    quint64 address = 0;
399

400
401
402
403
404
    if (editor->property("DisassemblerView").toBool()) {
        fileName = editor->file()->fileName();
        QString line = editor->contents()
            .section('\n', lineNumber - 1, lineNumber - 1);
        BreakpointData needle;
405
406
        address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
        needle.address = address;
407
        needle.bpLineNumber = -1;
408
        data = m_engine->breakHandler()->findSimilarBreakpoint(&needle);
409
410
    } else {
        fileName = editor->file()->fileName();
411
        data = m_engine->breakHandler()->findBreakpoint(fileName, lineNumber);
412
413
414
415
416
    }

    QList<QVariant> args;
    args.append(fileName);
    args.append(lineNumber);
417
    args.append(address);
418
419
420

    if (data) {
        // existing breakpoint
421
        const QString number = QString::fromAscii(data->bpNumber);
422
423
424
425
426
        QAction *act;
        if (number.isEmpty())
            act = new QAction(tr("Remove Breakpoint"), menu);
        else
            act = new QAction(tr("Remove Breakpoint %1").arg(number), menu);
427
428
        act->setData(args);
        connect(act, SIGNAL(triggered()),
429
            SLOT(breakpointSetRemoveMarginActionTriggered()));
430
431
432
433
        menu->addAction(act);

        QAction *act2;
        if (data->enabled)
434
435
436
437
            if (number.isEmpty())
                act2 = new QAction(tr("Disable Breakpoint"), menu);
            else
                act2 = new QAction(tr("Disable Breakpoint %1").arg(number), menu);
438
        else
439
440
441
442
            if (number.isEmpty())
                act2 = new QAction(tr("Enable Breakpoint"), menu);
            else
                act2 = new QAction(tr("Enable Breakpoint %1").arg(number), menu);
443
444
445
446
        act2->setData(args);
        connect(act2, SIGNAL(triggered()),
            this, SLOT(breakpointEnableDisableMarginActionTriggered()));
        menu->addAction(act2);
447
448
449
450
451
        QAction *editAction;
        if (number.isEmpty())
            editAction = new QAction(tr("Edit Breakpoint..."), menu);
        else
            editAction = new QAction(tr("Edit Breakpoint %1...").arg(number), menu);
452
        connect(editAction, SIGNAL(triggered()), SLOT(slotEditBreakpoint()));
453
454
        editAction->setData(qVariantFromValue(data));
        menu->addAction(editAction);
455
456
    } else {
        // non-existing
457
458
459
460
        const QString text = address ?
                    tr("Set Breakpoint at 0x%1").arg(address, 0, 16) :
                    tr("Set Breakpoint at line %1").arg(lineNumber);
        QAction *act = new QAction(text, menu);
461
462
        act->setData(args);
        connect(act, SIGNAL(triggered()),
463
            SLOT(breakpointSetRemoveMarginActionTriggered()));
464
465
        menu->addAction(act);
    }
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
    // Run to, jump to line below in stopped state.
    if (state() == InferiorStopOk) {
        menu->addSeparator();
        const QString runText = DebuggerEngine::tr("Run to Line %1").
                                arg(lineNumber);
        QAction *runToLineAction  = new QAction(runText, menu);
        runToLineAction->setData(args);
        connect(runToLineAction, SIGNAL(triggered()), this, SLOT(slotRunToLine()));
        menu->addAction(runToLineAction);
        if (m_engine->debuggerCapabilities() & JumpToLineCapability) {
            const QString jumpText = DebuggerEngine::tr("Jump to Line %1").
                                     arg(lineNumber);
            QAction *jumpToLineAction  = new QAction(jumpText, menu);
            menu->addAction(runToLineAction);
            jumpToLineAction->setData(args);
            connect(jumpToLineAction, SIGNAL(triggered()), this, SLOT(slotJumpToLine()));
            menu->addAction(jumpToLineAction);
        }
    }
485
}
486
487
488
489
490
491
492
493
494
495
496
497
498
499

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

DebuggerEngine::DebuggerEngine(const DebuggerStartParameters &startParameters)
  : d(new DebuggerEnginePrivate(this, startParameters))
{
}

DebuggerEngine::~DebuggerEngine()
{
500
501
    disconnect();
    delete d;
502
503
}

504
void DebuggerEngine::showStatusMessage(const QString &msg, int timeout) const
505
{
506
    showMessage(msg, StatusBar, timeout);
507
}
508

509
510
511
512
513
514
void DebuggerEngine::removeTooltip()
{
    watchHandler()->removeTooltip();
    hideDebuggerToolTip();
}

515
516
void DebuggerEngine::handleCommand(int role, const QVariant &value)
{
517
518
    if (role != RequestToolTipByExpressionRole)
        removeTooltip();
519
520

    switch (role) {
521
522
523
524
525
526
527
528
        case RequestActivateFrameRole:
            activateFrame(value.toInt());
            break;

        case RequestReloadFullStackRole:
            reloadFullStack();
            break;

529
530
531
532
533
534
535
536
        case RequestReloadSourceFilesRole:
            reloadSourceFiles();
            break;

        case RequestReloadModulesRole:
            reloadModules();
            break;

537
538
539
540
        case RequestReloadRegistersRole:
            reloadRegisters();
            break;

541
542
543
544
        case RequestExecDetachRole:
            detachDebugger();
            break;

545
546
547
548
549
        case RequestExecContinueRole:
            continueInferior();
            break;

        case RequestExecInterruptRole:
550
            requestInterruptInferior();
551
552
553
            break;

        case RequestExecResetRole:
554
            notifyEngineIll(); // FIXME: check
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
            break;

        case RequestExecStepRole:
            executeStepX();
            break;

        case RequestExecStepOutRole:
            executeStepOutX();
            break;

        case RequestExecNextRole:
            executeStepNextX();
            break;

        case RequestExecRunToLineRole:
hjk's avatar
hjk committed
570
            executeRunToLine();
571
572
573
            break;

        case RequestExecRunToFunctionRole:
hjk's avatar
hjk committed
574
            executeRunToFunction();
575
576
577
578
579
580
581
            break;

        case RequestExecReturnFromFunctionRole:
            executeReturnX();
            break;

        case RequestExecJumpToLineRole:
hjk's avatar
hjk committed
582
            executeJumpToLine();
583
584
585
            break;

        case RequestExecWatchRole:
hjk's avatar
hjk committed
586
            addToWatchWindow();
587
588
589
            break;

        case RequestExecExitRole:
590
            d->queueShutdownInferior();
591
592
            break;

593
594
        case RequestCreateSnapshotRole:
            createSnapshot();
595
596
            break;

597
598
599
600
        case RequestActivationRole:
            setActive(value.toBool());
            break;

601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
        case RequestExecFrameDownRole:
            frameDown();
            break;

        case RequestExecFrameUpRole:
            frameUp();
            break;

        case RequestOperatedByInstructionTriggeredRole:
            gotoLocation(stackHandler()->currentFrame(), true);
            break;

        case RequestExecuteCommandRole:
            executeDebuggerCommand(value.toString());
            break;
hjk's avatar
hjk committed
616

617
618
619
        case RequestToolTipByExpressionRole: {
            QList<QVariant> list = value.toList();
            QTC_ASSERT(list.size() == 3, break);
620
621
622
            QPoint point = list.at(0).value<QPoint>();
            TextEditor::ITextEditor *editor = // Eeks.
                (TextEditor::ITextEditor *)(list.at(1).value<quint64>());
hjk's avatar
hjk committed
623
            int pos = list.at(2).toInt();
624
            setToolTipExpression(point, editor, pos);
625
626
627
            break;
        }

628
        case RequestContextMenuRole: {
629
            QList<QVariant> list = value.toList();
630
631
            QTC_ASSERT(list.size() == 3, break);
            d->handleContextMenuRequest(list);
hjk's avatar
hjk committed
632
            break;
633
        }
634
635
636
637
638
639

        case RequestShowMemoryRole: {
            qDebug() << "CREATING MEMORY VIEW";
            (void) MemoryViewAgent(this, "0x0");
            break;
        }
640
    }
641
}
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
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

void DebuggerEngine::showModuleSymbols
    (const QString &moduleName, const Symbols &symbols)
{
    QTreeWidget *w = new QTreeWidget;
    w->setColumnCount(3);
    w->setRootIsDecorated(false);
    w->setAlternatingRowColors(true);
    w->setSortingEnabled(true);
    w->setHeaderLabels(QStringList() << tr("Symbol") << tr("Address") << tr("Code"));
    w->setWindowTitle(tr("Symbols in \"%1\"").arg(moduleName));
    foreach (const Symbol &s, symbols) {
        QTreeWidgetItem *it = new QTreeWidgetItem;
        it->setData(0, Qt::DisplayRole, s.name);
        it->setData(1, Qt::DisplayRole, s.address);
        it->setData(2, Qt::DisplayRole, s.state);
        w->addTopLevelItem(it);
    }
    plugin()->createNewDock(w);
}

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));
}

ModulesHandler *DebuggerEngine::modulesHandler() const
{
    return &d->m_modulesHandler;
}

RegisterHandler *DebuggerEngine::registerHandler() const
{
    return &d->m_registerHandler;
}

StackHandler *DebuggerEngine::stackHandler() const
{
    return &d->m_stackHandler;
}

ThreadsHandler *DebuggerEngine::threadsHandler() const
{
    return &d->m_threadsHandler;
}

WatchHandler *DebuggerEngine::watchHandler() const
{
    return &d->m_watchHandler;
}

700
701
702
703
//SnapshotHandler *DebuggerEngine::snapshotHandler() const
//{
//    return &d->m_snapshotHandler;
//}
704
705
706
707
708
709
710
711

SourceFilesHandler *DebuggerEngine::sourceFilesHandler() const
{
    return &d->m_sourceFilesHandler;
}

QAbstractItemModel *DebuggerEngine::modulesModel() const
{
Friedemann Kleint's avatar
Friedemann Kleint committed
712
713
714
715
    QAbstractItemModel *model = d->m_modulesHandler.model();
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("ModulesModel"));
    return model;
716
717
718
719
}

QAbstractItemModel *DebuggerEngine::registerModel() const
{
Friedemann Kleint's avatar
Friedemann Kleint committed
720
721
722
723
    QAbstractItemModel *model = d->m_registerHandler.model();
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("RegisterModel"));
    return model;
724
725
726
727
}

QAbstractItemModel *DebuggerEngine::stackModel() const
{
Friedemann Kleint's avatar
Friedemann Kleint committed
728
729
730
731
    QAbstractItemModel *model = d->m_stackHandler.model();
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("StackModel"));
    return model;
732
733
734
735
}

QAbstractItemModel *DebuggerEngine::threadsModel() const
{
Friedemann Kleint's avatar
Friedemann Kleint committed
736
737
738
739
    QAbstractItemModel *model = d->m_threadsHandler.model();
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("ThreadsModel"));
    return model;
740
741
742
743
}

QAbstractItemModel *DebuggerEngine::localsModel() const
{
Friedemann Kleint's avatar
Friedemann Kleint committed
744
745
746
747
    QAbstractItemModel *model = d->m_watchHandler.model(LocalsWatch);
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("LocalsModel"));
    return model;
748
749
750
751
}

QAbstractItemModel *DebuggerEngine::watchersModel() const
{
Friedemann Kleint's avatar
Friedemann Kleint committed
752
753
754
755
    QAbstractItemModel *model = d->m_watchHandler.model(WatchersWatch);
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("WatchersModel"));
    return model;
756
757
758
759
}

QAbstractItemModel *DebuggerEngine::returnModel() const
{
Friedemann Kleint's avatar
Friedemann Kleint committed
760
761
762
763
    QAbstractItemModel *model = d->m_watchHandler.model(ReturnWatch);
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("ReturnModel"));
    return model;
764
765
766
767
}

QAbstractItemModel *DebuggerEngine::sourceFilesModel() const
{
Friedemann Kleint's avatar
Friedemann Kleint committed
768
769
770
771
    QAbstractItemModel *model = d->m_sourceFilesHandler.model();
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("SourceFilesModel"));
    return model;
772
773
774
775
}

QAbstractItemModel *DebuggerEngine::commandModel() const
{
Friedemann Kleint's avatar
Friedemann Kleint committed
776
777
778
779
    QAbstractItemModel *model = d->m_commandHandler.model();
    if (model->objectName().isEmpty()) // Make debugging easier.
        model->setObjectName(objectName() + QLatin1String("CommandModel"));
    return model;
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
}

void DebuggerEngine::fetchMemory(MemoryViewAgent *, QObject *,
        quint64 addr, quint64 length)
{
    Q_UNUSED(addr);
    Q_UNUSED(length);
}

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
{
797
798
    //if (msg.size() && msg.at(0).isUpper() && msg.at(1).isUpper())
    //    qDebug() << qPrintable(msg) << "IN STATE" << state();
799
    plugin()->showMessage(msg, channel, timeout);
800
801
802
803
804
    if (d->m_runControl) {
        d->m_runControl->showMessage(msg, channel);
    } else {
        qWarning("Warning: %s (no active run control)", qPrintable(msg));
    }
805
806
807
808
}

void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
{
hjk's avatar
hjk committed
809
    if (!isSlaveEngine()) {
810
        d->m_progress.setProgressRange(0, 1000);
811
812
813
        Core::FutureProgress *fp = Core::ICore::instance()->progressManager()
            ->addTask(d->m_progress.future(),
            tr("Launching"), _("Debugger.Launcher"));
814
        fp->setKeepOnFinish(Core::FutureProgress::DontKeepOnFinish);
815
816
        d->m_progress.reportStarted();
    }
817
818
    QTC_ASSERT(runControl, notifyEngineSetupFailed(); return);
    QTC_ASSERT(!d->m_runControl, notifyEngineSetupFailed(); return);
819
820
821
822
823
824
825

    d->m_runControl = runControl;

    d->m_inferiorPid = d->m_startParameters.attachPID > 0
        ? d->m_startParameters.attachPID : 0;

    if (d->m_startParameters.environment.empty())
826
        d->m_startParameters.environment = Utils::Environment().toStringList();
827
828
829
830
831
832
833
834

    if (d->m_startParameters.breakAtMain)
        breakByFunctionMain();

    const unsigned engineCapabilities = debuggerCapabilities();
    theDebuggerAction(OperateByInstruction)
        ->setEnabled(engineCapabilities & DisassemblerCapability);

835
836
    QTC_ASSERT(state() == DebuggerNotReady || state() == DebuggerFinished,
         qDebug() << state());
hjk's avatar
hjk committed
837
    setState(EngineSetupRequested);
838

839
    d->m_progress.setProgressValue(200);
hjk's avatar
hjk committed
840
    setupEngine();
841
842
843
844
845
846
847
848
849
850
851
852
853
854
}

void DebuggerEngine::breakByFunctionMain()
{
#ifdef Q_OS_WIN
    // FIXME: wrong on non-Qt based binaries
    emit breakByFunction("qMain");
#else
    emit breakByFunction("main");
#endif
}

void DebuggerEngine::breakByFunction(const QString &functionName)
{
855
856
    breakHandler()->breakByFunction(functionName);
    breakHandler()->synchronizeBreakpoints();
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
}

void DebuggerEngine::resetLocation()
{
    d->m_disassemblerViewAgent.resetLocation();
    d->m_stackHandler.setCurrentIndex(-1);
    plugin()->resetLocation();
}

void DebuggerEngine::gotoLocation(const QString &fileName, int lineNumber, bool setMarker)
{
    StackFrame frame;
    frame.file = fileName;
    frame.line = lineNumber;
    gotoLocation(frame, setMarker);
}

void DebuggerEngine::gotoLocation(const StackFrame &frame, bool setMarker)
{
    if (theDebuggerBoolSetting(OperateByInstruction) || !frame.isUsable()) {
        if (setMarker)
            plugin()->resetLocation();
        d->m_disassemblerViewAgent.setFrame(frame);
    } else {
        plugin()->gotoLocation(frame.file, frame.line, setMarker);
    }
}

void DebuggerEngine::executeStepX()
{
    resetLocation();
    if (theDebuggerBoolSetting(OperateByInstruction))
        executeStepI();
    else
        executeStep();
}

void DebuggerEngine::executeStepOutX()
{
    resetLocation();
    executeStepOut();
}

void DebuggerEngine::executeStepNextX()
{
    resetLocation();
    if (theDebuggerBoolSetting(OperateByInstruction))
        executeNextI();
    else
        executeNext();
}

void DebuggerEngine::executeReturnX()
{
    resetLocation();
    executeReturn();
}

hjk's avatar
hjk committed
915
void DebuggerEngine::executeRunToLine()
916
{
917
918
919
920
921
922
    QString fileName;
    int lineNumber;
    if (currentTextEditorPosition(&fileName, &lineNumber)) {
        resetLocation();
        executeRunToLine(fileName, lineNumber);
    }
923
924
}

hjk's avatar
hjk committed
925
void DebuggerEngine::executeRunToFunction()
926
{
hjk's avatar
hjk committed
927
    ITextEditor *textEditor = currentTextEditor();
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
    QTC_ASSERT(textEditor, return);
    QPlainTextEdit *ed = qobject_cast<QPlainTextEdit*>(textEditor->widget());
    if (!ed)
        return;
    QTextCursor cursor = ed->textCursor();
    QString functionName = cursor.selectedText();
    if (functionName.isEmpty()) {
        const QTextBlock block = cursor.block();
        const QString line = block.text();
        foreach (const QString &str, line.trimmed().split('(')) {
            QString a;
            for (int i = str.size(); --i >= 0; ) {
                if (!str.at(i).isLetterOrNumber())
                    break;
                a = str.at(i) + a;
            }
            if (!a.isEmpty()) {
                functionName = a;
                break;
            }
        }
    }

hjk's avatar
hjk committed
951
952
953
954
    if (functionName.isEmpty())
        return;
    resetLocation();
    executeRunToFunction(functionName);
955
956
}

hjk's avatar
hjk committed
957
void DebuggerEngine::executeJumpToLine()
958
{
959
960
961
962
    QString fileName;
    int lineNumber;
    if (currentTextEditorPosition(&fileName, &lineNumber))
        executeJumpToLine(fileName, lineNumber);
963
964
}

hjk's avatar
hjk committed
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
void DebuggerEngine::addToWatchWindow()
{
    // Requires a selection, but that's the only case we want anyway.
    EditorManager *editorManager = EditorManager::instance();
    if (!editorManager)
        return;
    IEditor *editor = editorManager->currentEditor();
    if (!editor)
        return;
    ITextEditor *textEditor = qobject_cast<ITextEditor*>(editor);
    if (!textEditor)
        return;
    QTextCursor tc;
    QPlainTextEdit *ptEdit = qobject_cast<QPlainTextEdit*>(editor->widget());
    if (ptEdit)
        tc = ptEdit->textCursor();
    QString exp;
    if (tc.hasSelection()) {
        exp = tc.selectedText();
    } else {
        int line, column;
        exp = cppExpressionAt(textEditor, tc.position(), &line, &column);
    }
988
989
990
    if (exp.isEmpty())
        return;
    watchHandler()->watchExpression(exp);
hjk's avatar
hjk committed
991
992
}

993
994
995
// Called from RunControl.
void DebuggerEngine::handleStartFailed()
{
996
    showMessage("HANDLE RUNCONTROL START FAILED");
997
    d->m_runControl = 0;
998

999
    d->m_progress.setProgressValue(900);
1000
1001
    d->m_progress.reportCanceled();
    d->m_progress.reportFinished();
1002
1003
}

1004
1005
// Called from RunControl.
void DebuggerEngine::handleFinished()
1006
{
1007
    showMessage("HANDLE RUNCONTROL FINISHED");
1008
    d->m_runControl = 0;
1009
1010
1011
1012
    modulesHandler()->removeAll();
    stackHandler()->removeAll();
    threadsHandler()->removeAll();
    watchHandler()->cleanup();
1013

1014
    d->m_progress.setProgressValue(1000);
1015
    d->m_progress.reportFinished();
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
}

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
{
    return theDebuggerBoolSetting(UseDebuggingHelpers);
}

QStringList DebuggerEngine::qtDumperLibraryLocations() const
{
    if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool()) {
        const QString customLocation =
            theDebuggerAction(CustomDebuggingHelperLocation)->value().toString();
        const QString location =
            tr("%1 (explicitly set in the Debugger Options)").arg(customLocation);
        return QStringList(location);
    }
    return d->m_startParameters.dumperLibraryLocations;
}

void DebuggerEngine::showQtDumperLibraryWarning(const QString &details)
{
1057
    QMessageBox dialog(plugin()->mainWindow());
Leena Miettinen's avatar
Leena Miettinen committed
1058
    QPushButton *qtPref = dialog.addButton(tr("Open Qt4 Options"),
1059
        QMessageBox::ActionRole);
Leena Miettinen's avatar
Leena Miettinen committed
1060
    QPushButton *helperOff = dialog.addButton(tr("Turn off Helper Usage"),
1061
        QMessageBox::ActionRole);
Leena Miettinen's avatar
Leena Miettinen committed
1062
    QPushButton *justContinue = dialog.addButton(tr("Continue Anyway"),
1063
1064
        QMessageBox::AcceptRole);
    dialog.setDefaultButton(justContinue);
Leena Miettinen's avatar
Leena Miettinen committed
1065
    dialog.setWindowTitle(tr("Debugging Helper Missing"));
1066
1067
1068
1069
1070
    dialog.setText(tr("The debugger could not load the debugging helper library."));
    dialog.setInformativeText(tr(
        "The debugging helper is used to nicely format the values of some Qt "
        "and Standard Library data types. "
        "It must be compiled for each used Qt version separately. "
Leena Miettinen's avatar
Leena Miettinen committed
1071
1072
        "On the Qt4 options page, select a Qt installation "
        "and click Rebuild."));
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
    if (!details.isEmpty())
        dialog.setDetailedText(details);
    dialog.exec();
    if (dialog.clickedButton() == qtPref) {
        Core::ICore::instance()->showOptionsDialog(
            _(Qt4ProjectManager::Constants::QT_SETTINGS_CATEGORY),
            _(Qt4ProjectManager::Constants::QTVERSION_SETTINGS_PAGE_ID));
    } else if (dialog.clickedButton() == helperOff) {
        theDebuggerAction(UseDebuggingHelpers)
            ->setValue(qVariantFromValue(false), false);
    }
}

QString DebuggerEngine::qtDumperLibraryName() const
{
    if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool())
        return theDebuggerAction(CustomDebuggingHelperLocation)->value().toString();
    return startParameters().dumperLibrary;
}

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

hjk's avatar
hjk committed
1098
DebuggerState DebuggerEngine::lastGoodState() const
1099
{
hjk's avatar
hjk committed
1100
1101
1102
1103
1104
1105
1106
    return d->m_lastGoodState;
}

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

hjk's avatar
hjk committed
1108
1109
1110
static bool isAllowedTransition(DebuggerState from, DebuggerState to)
{
    switch (from) {
1111
    case DebuggerNotReady:
1112
        return to == EngineSetupRequested;
1113

hjk's avatar
hjk committed
1114
    case EngineSetupRequested:
1115
1116
        return to == EngineSetupOk || to == EngineSetupFailed;
    case EngineSetupFailed:
1117
        // FIXME: In therory it's the engine's task to go into a
1118
1119
1120
        // proper "Shutdown" state before calling notifyEngineSetupFailed
        //return to == DebuggerFinished;
        return to == EngineShutdownRequested;
1121
    case EngineSetupOk:
hjk's avatar
hjk committed
1122
        return to == InferiorSetupRequested || to == EngineShutdownRequested;
1123

hjk's avatar
hjk committed
1124
1125
    case InferiorSetupRequested:
        return to == EngineRunRequested || to == InferiorSetupFailed;
hjk's avatar
hjk committed
1126
    case InferiorSetupFailed:
hjk's avatar
hjk committed
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
        return to == EngineShutdownRequested;

    case EngineRunRequested:
        return to == InferiorRunRequested || to == InferiorStopRequested
            || to == InferiorUnrunnable || to == EngineRunFailed;

    case EngineRunFailed:
        return to == InferiorShutdownRequested;

    case InferiorRunRequested:
        return to == InferiorRunOk || to == InferiorRunFailed;
    case InferiorRunFailed:
        return to == InferiorStopOk;
    case InferiorRunOk:
        return to == InferiorStopRequested || to == InferiorStopOk;

    case InferiorStopRequested:
        return to == InferiorStopOk || to == InferiorStopFailed;
    case InferiorStopOk:
        return to == InferiorRunRequested || to == InferiorShutdownRequested
            || to == InferiorStopOk;
1148
    case InferiorStopFailed:
hjk's avatar
hjk committed
1149
        return to == EngineShutdownRequested;
1150
1151

    case InferiorUnrunnable:
hjk's avatar
hjk committed
1152
1153
1154
1155
1156
        return to == InferiorShutdownRequested;
    case InferiorShutdownRequested:
        return to == InferiorShutdownOk || to == InferiorShutdownFailed;
    case InferiorShutdownOk:
        return to == EngineShutdownRequested;
1157
    case InferiorShutdownFailed:
hjk's avatar
hjk committed
1158
        return to == EngineShutdownRequested;
1159

hjk's avatar
hjk committed
1160
    case EngineShutdownRequested:
1161
        return to == EngineShutdownOk || to == EngineShutdownFailed;
hjk's avatar
hjk committed
1162
1163
1164
1165
1166
1167
    case EngineShutdownOk:
        return to == DebuggerFinished;
    case EngineShutdownFailed:
        return to == DebuggerFinished;

    case DebuggerFinished:
1168
        return to == EngineSetupRequested; // Happens on restart.
1169
1170
1171
1172
1173
1174
    }

    qDebug() << "UNKNOWN STATE:" << from;
    return false;
}

1175
void DebuggerEngine::notifyEngineSetupFailed()
hjk's avatar
hjk committed
1176
{
hjk's avatar
hjk committed
1177
    showMessage(_("NOTE: ENGINE SETUP FAILED"));
hjk's avatar
hjk committed
1178
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
1179
    setState(EngineSetupFailed);
hjk's avatar
hjk committed
1180
1181
    QTC_ASSERT(d->m_runControl, return);
    d->m_runControl->startFailed();
hjk's avatar
hjk committed
1182
    setState(DebuggerFinished);
hjk's avatar
hjk committed
1183
1184
}

1185
void DebuggerEngine::notifyEngineSetupOk()
1186
{
hjk's avatar
hjk committed
1187
    showMessage(_("NOTE: ENGINE SETUP OK"));
hjk's avatar
hjk committed
1188
    QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
1189
    setState(EngineSetupOk);
hjk's avatar
hjk committed
1190
    QTC_ASSERT(d->m_runControl, return);
hjk's avatar
hjk committed
1191
    showMessage(_("QUEUE: SETUP INFERIOR"));
hjk's avatar
hjk committed
1192
    QTimer::singleShot(0, d, SLOT(doSetupInferior()));
1193
1194
}

hjk's avatar
hjk committed
1195
void DebuggerEnginePrivate::doSetupInferior()
1196
{
1197
    m_engine->showMessage(_("CALL: SETUP INFERIOR"));
hjk's avatar
hjk committed
1198
    QTC_ASSERT(state() == EngineSetupOk, qDebug() << state());
1199
    m_progress.setProgressValue(250);
hjk's avatar
hjk committed
1200
    m_engine->setState(InferiorSetupRequested);
hjk's avatar
hjk committed
1201
1202
1203
1204
1205
    m_engine->setupInferior();
}

void DebuggerEngine::notifyInferiorSetupFailed()
{
hjk's avatar
hjk committed
1206
    showMessage(_("NOTE: INFERIOR SETUP FAILED"));
hjk's avatar
hjk committed
1207
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
hjk's avatar
hjk committed
1208
    setState(InferiorSetupFailed);
hjk's avatar
hjk committed
1209
    d->queueShutdownEngine();
hjk's avatar
hjk committed
1210
1211
1212
1213
}

void DebuggerEngine::notifyInferiorSetupOk()
{
hjk's avatar
hjk committed
1214
    showMessage(_("NOTE: INFERIOR SETUP OK"));
hjk's avatar
hjk committed
1215
    QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
hjk's avatar
hjk committed
1216
    d->queueRunEngine();
hjk's avatar
hjk committed
1217
1218
1219
1220
}

void DebuggerEnginePrivate::doRunEngine()
{
hjk's avatar
hjk committed
1221
    m_engine->showMessage(_("CALL: RUN ENGINE"));
hjk's avatar
hjk committed
1222
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
1223
    m_progress.setProgressValue(300);
hjk's avatar
hjk committed
1224
1225
1226
    m_engine->runEngine();
}

hjk's avatar
hjk committed
1227
1228
void DebuggerEngine::notifyInferiorUnrunnable()
{
hjk's avatar
hjk committed
1229
    showMessage(_("NOTE: INFERIOR UNRUNNABLE"));
1230
1231
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
hjk's avatar
hjk committed
1232
1233
1234
1235
1236
1237
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
    setState(InferiorUnrunnable);
}

void DebuggerEngine::notifyEngineRunFailed()
{
hjk's avatar
hjk committed
1238
    showMessage(_("NOTE: ENGINE RUN FAILED"));
hjk's avatar
hjk committed
1239
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
1240
1241
1242
    d->m_progress.setProgressValue(900);
    d->m_progress.reportCanceled();
    d->m_progress.reportFinished();
hjk's avatar
hjk committed
1243
    setState(EngineRunFailed);
1244
    d->queueShutdownEngine();
hjk's avatar
hjk committed
1245
1246
1247
1248
}

void DebuggerEngine::notifyEngineRunAndInferiorRunOk()
{
hjk's avatar
hjk committed
1249
    showMessage(_("NOTE: ENGINE RUN AND INFERIOR RUN OK"));
1250
1251
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
hjk's avatar
hjk committed
1252
1253
1254
1255
1256
1257
1258
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
    setState(InferiorRunRequested);
    notifyInferiorRunOk();
}

void DebuggerEngine::notifyEngineRunAndInferiorStopOk()
{
hjk's avatar
hjk committed
1259
    showMessage(_("NOTE: ENGINE RUN AND INFERIOR STOP OK"));
1260
1261
    d->m_progress.setProgressValue(1000);
    d->m_progress.reportFinished();
hjk's avatar
hjk committed
1262
1263
1264
1265
1266
1267
1268
    QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
    setState(InferiorStopRequested);
    notifyInferiorStopOk();
}

void DebuggerEngine::notifyInferiorRunRequested()
{
hjk's avatar
hjk committed
1269
    showMessage(_("NOTE: INFERIOR RUN REQUESTED"));
hjk's avatar
hjk committed
1270
1271
1272
1273
1274
1275
    QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
    setState(InferiorRunRequested);
}

void DebuggerEngine::notifyInferiorRunOk()
{
hjk's avatar
hjk committed
1276
    showMessage(_("NOTE: INFERIOR RUN OK"));
hjk's avatar
hjk committed
1277
1278
1279
1280
1281
1282
    QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
    setState(InferiorRunOk);
}

void DebuggerEngine::notifyInferiorRunFailed()
{
hjk's avatar
hjk committed
1283
    showMessage(_("NOTE: INFERIOR RUN FAILED"));