debuggerengine.h 13.8 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 33 34 35

#ifndef DEBUGGER_DEBUGGERENGINE_H
#define DEBUGGER_DEBUGGERENGINE_H

#include "debugger_global.h"
#include "debuggerconstants.h"
36

37
#include <QObject>
38
#include <QProcess>
39 40 41 42

QT_BEGIN_NAMESPACE
class QDebug;
class QPoint;
Friedemann Kleint's avatar
Friedemann Kleint committed
43
class QAbstractItemModel;
44 45
QT_END_NAMESPACE

46
namespace TextEditor { class TextEditorWidget; }
47
namespace Core { class IOptionsPage; }
48 49 50

namespace Debugger {

hjk's avatar
hjk committed
51
class DebuggerRunControl;
Friedemann Kleint's avatar
Friedemann Kleint committed
52
class DebuggerStartParameters;
53
class RemoteSetupResult;
54 55 56 57 58 59

DEBUGGER_EXPORT QDebug operator<<(QDebug str, const DebuggerStartParameters &);
DEBUGGER_EXPORT QDebug operator<<(QDebug str, DebuggerState state);

namespace Internal {

hjk's avatar
hjk committed
60
class DebuggerEnginePrivate;
61
class DebuggerPluginPrivate;
62 63
class DisassemblerAgent;
class MemoryAgent;
64
class WatchData;
65
class WatchItem;
66 67 68 69 70 71 72 73
class BreakHandler;
class ModulesHandler;
class RegisterHandler;
class StackHandler;
class StackFrame;
class SourceFilesHandler;
class ThreadsHandler;
class WatchHandler;
74
class Breakpoint;
75
class QmlAdapter;
76
class QmlCppEngine;
77
class DebuggerToolTipContext;
hjk's avatar
hjk committed
78
class MemoryViewSetupData;
79
class Terminal;
80
class ThreadId;
81

82 83 84 85 86 87 88 89
class Location
{
public:
    Location() { init(); }
    Location(quint64 address) { init(); m_address = address; }
    Location(const QString &file) { init(); m_fileName = file; }
    Location(const QString &file, int line, bool marker = true)
        { init(); m_lineNumber = line; m_fileName = file; m_needsMarker = marker; }
Friedemann Kleint's avatar
Friedemann Kleint committed
90
    Location(const StackFrame &frame, bool marker = true);
91 92
    QString fileName() const { return m_fileName; }
    QString functionName() const { return m_functionName; }
93
    QString from() const { return m_from; }
94 95 96 97
    int lineNumber() const { return m_lineNumber; }
    void setNeedsRaise(bool on) { m_needsRaise = on; }
    void setNeedsMarker(bool on) { m_needsMarker = on; }
    void setFileName(const QString &fileName) { m_fileName = fileName; }
hjk's avatar
hjk committed
98
    void setUseAssembler(bool on) { m_hasDebugInfo = !on; }
99 100 101
    bool needsRaise() const { return m_needsRaise; }
    bool needsMarker() const { return m_needsMarker; }
    bool hasDebugInfo() const { return m_hasDebugInfo; }
102 103
    bool canBeDisassembled() const
        { return m_address != quint64(-1) || !m_functionName.isEmpty(); }
104 105 106 107 108 109 110 111 112 113 114
    quint64 address() const { return m_address; }

private:
    void init() { m_needsMarker = false; m_needsRaise = true; m_lineNumber = -1;
        m_address = 0; m_hasDebugInfo = true; }
    bool m_needsMarker;
    bool m_needsRaise;
    bool m_hasDebugInfo;
    int m_lineNumber;
    QString m_fileName;
    QString m_functionName;
115
    QString m_from;
116 117 118
    quint64 m_address;
};

119 120 121 122 123 124 125 126 127 128 129
class ContextData
{
public:
    ContextData() : lineNumber(0), address(0) {}

public:
    QString fileName;
    int lineNumber;
    quint64 address;
};

hjk's avatar
hjk committed
130
class DebuggerEngine : public QObject
131 132 133 134
{
    Q_OBJECT

public:
135
    explicit DebuggerEngine(const DebuggerStartParameters &sp);
136 137
    virtual ~DebuggerEngine();

hjk's avatar
hjk committed
138 139 140
    const DebuggerStartParameters &startParameters() const;
    DebuggerStartParameters &startParameters();

141
    virtual bool setToolTipExpression(const Internal::DebuggerToolTipContext &);
hjk's avatar
hjk committed
142

143
    virtual void updateWatchItem(WatchItem *) {}
144 145
    virtual void watchDataSelected(const QByteArray &iname);

146
    virtual void startDebugger(DebuggerRunControl *runControl);
147 148

    virtual void watchPoint(const QPoint &);
149 150 151 152 153 154 155 156

    enum MemoryViewFlags
    {
        MemoryReadOnly = 0x1,      //!< Read-only.
        MemoryTrackRegister = 0x2, //!< Address parameter is register number to track
        MemoryView = 0x4           //!< Open a separate view (using the pos-parameter).
    };

hjk's avatar
hjk committed
157
    virtual void openMemoryView(const MemoryViewSetupData &data);
158
    virtual void fetchMemory(Internal::MemoryAgent *, QObject *,
159
                             quint64 addr, quint64 length);
hjk's avatar
hjk committed
160 161
    virtual void changeMemory(Internal::MemoryAgent *, QObject *,
                              quint64 addr, const QByteArray &data);
162
    virtual void updateMemoryViews();
163
    virtual void openDisassemblerView(const Internal::Location &location);
164
    virtual void fetchDisassembler(Internal::DisassemblerAgent *);
165 166 167 168 169
    virtual void activateFrame(int index);

    virtual void reloadModules();
    virtual void examineModules();
    virtual void loadSymbols(const QString &moduleName);
170
    virtual void loadSymbolsForStack();
171 172
    virtual void loadAllSymbols();
    virtual void requestModuleSymbols(const QString &moduleName);
173
    virtual void requestModuleSections(const QString &moduleName);
174 175 176 177

    virtual void reloadRegisters();
    virtual void reloadSourceFiles();
    virtual void reloadFullStack();
178
    virtual void loadAdditionalQmlStack();
179
    virtual void reloadDebuggingHelpers();
hjk's avatar
hjk committed
180

hjk's avatar
hjk committed
181
    virtual void setRegisterValue(const QByteArray &name, const QString &value);
182
    virtual void addOptionPages(QList<Core::IOptionsPage*> *) const;
183
    virtual bool hasCapability(unsigned cap) const = 0;
hjk's avatar
hjk committed
184
    virtual void debugLastCommand() {}
hjk's avatar
hjk committed
185

186 187
    virtual bool isSynchronous() const;
    virtual QByteArray qtNamespace() const;
hjk's avatar
hjk committed
188

189 190
    virtual void createSnapshot();
    virtual void updateAll();
hjk's avatar
hjk committed
191

hjk's avatar
hjk committed
192 193
    virtual bool stateAcceptsBreakpointChanges() const { return true; }
    virtual void attemptBreakpointSynchronization();
194 195 196 197
    virtual bool acceptsBreakpoint(Breakpoint bp) const = 0;
    virtual void insertBreakpoint(Breakpoint bp);  // FIXME: make pure
    virtual void removeBreakpoint(Breakpoint bp);  // FIXME: make pure
    virtual void changeBreakpoint(Breakpoint bp);  // FIXME: make pure
hjk's avatar
hjk committed
198

199
    virtual bool acceptsDebuggerCommands() const { return true; }
hjk's avatar
hjk committed
200 201
    virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages);

202
    virtual void assignValueInDebugger(WatchItem *item,
hjk's avatar
hjk committed
203
        const QString &expr, const QVariant &value);
hjk's avatar
hjk committed
204
    virtual void selectThread(Internal::ThreadId threadId) = 0;
205

206 207 208 209 210 211 212
    virtual Internal::ModulesHandler *modulesHandler() const;
    virtual Internal::RegisterHandler *registerHandler() const;
    virtual Internal::StackHandler *stackHandler() const;
    virtual Internal::ThreadsHandler *threadsHandler() const;
    virtual Internal::WatchHandler *watchHandler() const;
    virtual Internal::SourceFilesHandler *sourceFilesHandler() const;
    virtual Internal::BreakHandler *breakHandler() const;
213

214 215 216 217
    virtual QAbstractItemModel *modulesModel() const;
    virtual QAbstractItemModel *registerModel() const;
    virtual QAbstractItemModel *stackModel() const;
    virtual QAbstractItemModel *threadsModel() const;
hjk's avatar
hjk committed
218
    virtual QAbstractItemModel *watchModel() const;
219
    virtual QAbstractItemModel *sourceFilesModel() const;
220

221
    void progressPing();
222
    void handleFinished();
223
    void handleStartFailed();
224 225 226 227
    bool debuggerActionsEnabled() const;
    static bool debuggerActionsEnabled(DebuggerState state);

    DebuggerState state() const;
hjk's avatar
hjk committed
228 229
    DebuggerState lastGoodState() const;
    DebuggerState targetState() const;
230
    bool isDying() const;
231 232 233 234 235 236

    static const char *stateName(int s);

    void notifyInferiorPid(qint64 pid);
    qint64 inferiorPid() const;
    bool isReverseDebugging() const;
237
    void handleCommand(int role, const QVariant &value);
238

239
    // Convenience
240
    Q_SLOT virtual void showMessage(const QString &msg, int channel = LogDebug,
241
        int timeout = -1) const;
Friedemann Kleint's avatar
Friedemann Kleint committed
242
    Q_SLOT void showStatusMessage(const QString &msg, int timeout = -1) const;
243

244
    virtual void resetLocation();
245
    virtual void gotoLocation(const Internal::Location &location);
246
    Q_SLOT virtual void quitDebugger(); // called by DebuggerRunControl
hjk's avatar
hjk committed
247
    virtual void abortDebugger(); // called by DebuggerPlugin
248

249
    virtual void updateViews();
hjk's avatar
x  
hjk committed
250
    bool isSlaveEngine() const;
251
    bool isMasterEngine() const;
hjk's avatar
hjk committed
252
    DebuggerEngine *masterEngine() const;
253
    virtual DebuggerEngine *cppEngine() { return 0; }
254

255 256
    virtual bool canDisplayTooltip() const { return state() == InferiorStopOk; }

257 258
    virtual void notifyInferiorIll();

259 260
    QString toFileInProject(const QUrl &fileUrl);

261
signals:
262
    void stateChanged(Debugger::DebuggerState state);
263 264
    // A new stack frame is on display including locals.
    void stackFrameCompleted();
265
    /*
266
     * For "external" clients of a debugger run control that needs to do
267
     * further setup before the debugger is started (e.g. RemoteLinux).
268 269
     * Afterwards, notifyEngineRemoteSetupFinished
     * must be called to continue or abort debugging.
270 271 272 273
     * This signal is only emitted if the start parameters indicate that
     * a server start script should be used, but none is given.
     */
    void requestRemoteSetup();
hjk's avatar
hjk committed
274
    void aboutToNotifyInferiorSetupOk();
275

276
protected:
277 278 279 280 281 282
    // The base notify*() function implementation should be sufficient
    // in most cases, but engines are free to override them to do some
    // engine specific cleanup like stopping timers etc.
    virtual void notifyEngineSetupOk();
    virtual void notifyEngineSetupFailed();
    virtual void notifyEngineRunFailed();
283

284
    virtual void notifyEngineRequestRemoteSetup();
285
    public:
hjk's avatar
hjk committed
286
    virtual void notifyEngineRemoteServerRunning(const QByteArray &, int pid);
287
    virtual void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
288

289
    protected:
290 291
    virtual void notifyInferiorSetupOk();
    virtual void notifyInferiorSetupFailed();
hjk's avatar
hjk committed
292

293 294
    virtual void notifyEngineRunAndInferiorRunOk();
    virtual void notifyEngineRunAndInferiorStopOk();
hjk's avatar
hjk committed
295
    virtual void notifyEngineRunOkAndInferiorUnrunnable(); // Called by CoreAdapter.
hjk's avatar
hjk committed
296 297

    // Use notifyInferiorRunRequested() plus notifyInferiorRunOk() instead.
298
    //virtual void notifyInferiorSpontaneousRun();
hjk's avatar
hjk committed
299

300 301 302
    virtual void notifyInferiorRunRequested();
    virtual void notifyInferiorRunOk();
    virtual void notifyInferiorRunFailed();
hjk's avatar
hjk committed
303

304 305 306
    virtual void notifyInferiorStopOk();
    virtual void notifyInferiorSpontaneousStop();
    virtual void notifyInferiorStopFailed();
hjk's avatar
hjk committed
307 308 309

    public:
    virtual void notifyInferiorExited();
310 311
    void notifyDebuggerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus,
                                       const QString &backendName);
hjk's avatar
hjk committed
312

313
protected:
314 315
    virtual void notifyInferiorShutdownOk();
    virtual void notifyInferiorShutdownFailed();
hjk's avatar
hjk committed
316

317 318 319
    virtual void notifyEngineSpontaneousShutdown();
    virtual void notifyEngineShutdownOk();
    virtual void notifyEngineShutdownFailed();
320

321
    virtual void notifyEngineIll();
322

hjk's avatar
hjk committed
323 324 325 326 327
    virtual void setupEngine() = 0;
    virtual void setupInferior() = 0;
    virtual void runEngine() = 0;
    virtual void shutdownInferior() = 0;
    virtual void shutdownEngine() = 0;
328
    virtual void resetInferior() {}
hjk's avatar
hjk committed
329

hjk's avatar
hjk committed
330 331 332
    virtual void detachDebugger();
    virtual void exitDebugger();
    virtual void executeStep();
hjk's avatar
hjk committed
333
    virtual void executeStepOut();
hjk's avatar
hjk committed
334 335 336 337 338 339 340 341 342
    virtual void executeNext();
    virtual void executeStepI();
    virtual void executeNextI();
    virtual void executeReturn();

    virtual void continueInferior();
    virtual void interruptInferior();
    virtual void requestInterruptInferior();

343
    virtual void executeRunToLine(const Internal::ContextData &data);
hjk's avatar
hjk committed
344
    virtual void executeRunToFunction(const QString &functionName);
345
    virtual void executeJumpToLine(const Internal::ContextData &data);
hjk's avatar
hjk committed
346 347 348 349

    virtual void frameUp();
    virtual void frameDown();

350
    void setTargetState(DebuggerState state);
351
    void setMasterEngine(DebuggerEngine *masterEngine);
352

353
    DebuggerRunControl *runControl() const;
354
    Terminal *terminal() const;
hjk's avatar
hjk committed
355

356 357
    static QString msgStopped(const QString &reason = QString());
    static QString msgStoppedBySignal(const QString &meaning, const QString &name);
hjk's avatar
hjk committed
358 359
    static QString msgStoppedByException(const QString &description,
        const QString &threadId);
360
    static QString msgInterrupted();
hjk's avatar
hjk committed
361
    void showStoppedBySignalMessageBox(const QString meaning, QString name);
362 363
    void showStoppedByExceptionMessageBox(const QString &description);

364 365 366
    bool isStateDebugging() const;
    void setStateDebugging(bool on);

367
    static void validateExecutable(DebuggerStartParameters *sp);
David Schulz's avatar
David Schulz committed
368

369 370 371 372 373
    virtual void setupSlaveInferior();
    virtual void setupSlaveEngine();
    virtual void runSlaveEngine();
    virtual void shutdownSlaveEngine();

374 375 376
    virtual void slaveEngineStateChanged(DebuggerEngine *engine,
        DebuggerState state);

hjk's avatar
hjk committed
377
private:
378
    // Wrapper engine needs access to state of its subengines.
hjk's avatar
hjk committed
379 380 381
    friend class QmlCppEngine;
    friend class DebuggerPluginPrivate;
    friend class QmlAdapter;
hjk's avatar
hjk committed
382

383
    virtual void setState(DebuggerState state, bool forced = false);
384

hjk's avatar
hjk committed
385
    friend class DebuggerEnginePrivate;
386 387 388
    DebuggerEnginePrivate *d;
};

hjk's avatar
hjk committed
389
} // namespace Internal
390 391
} // namespace Debugger

392 393
Q_DECLARE_METATYPE(Debugger::Internal::ContextData)

394
#endif // DEBUGGER_DEBUGGERENGINE_H