cdbengine.h 11.7 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
2
**
hjk's avatar
hjk committed
3 4
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
7
**
hjk's avatar
hjk committed
8 9 10 11 12 13 14
** 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
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
15 16
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17 18 19 20 21 22 23 24 25
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
con's avatar
con committed
26 27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
29 30 31 32 33

#ifndef DEBUGGER_CDBENGINE_H
#define DEBUGGER_CDBENGINE_H

#include "debuggerengine.h"
34
#include "breakpoint.h"
hjk's avatar
hjk committed
35
#include "threaddata.h"
36

37 38 39 40 41 42 43 44
#include <QSharedPointer>
#include <QProcess>
#include <QVariantList>
#include <QMap>
#include <QMultiHash>
#include <QTime>
#include <QPair>
#include <QList>
45

46 47 48
namespace Utils {
class ConsoleProcess;
}
49
namespace Debugger {
50
namespace Internal {
51

52
class DisassemblerAgent;
53 54 55
struct CdbBuiltinCommand;
struct CdbExtensionCommand;
struct CdbOptions;
56
struct MemoryViewCookie;
57
class ByteArrayInputStream;
58
class GdbMi;
59 60 61 62 63 64 65 66 67 68 69 70 71 72

class CdbEngine : public Debugger::DebuggerEngine
{
    Q_OBJECT

public:
    typedef QSharedPointer<CdbOptions> OptionsPtr;

    enum CommandFlags { QuietCommand = 0x1 };
    // Flag bits for a sequence of commands
    enum CommandSequenceFlags {
        CommandListStack = 0x1,
        CommandListThreads = 0x2,
        CommandListRegisters = 0x4,
73 74
        CommandListModules = 0x8,
        CommandListBreakPoints = 0x10
75 76 77 78 79 80 81
    };

    typedef QSharedPointer<CdbBuiltinCommand> CdbBuiltinCommandPtr;
    typedef QSharedPointer<CdbExtensionCommand> CdbExtensionCommandPtr;
    typedef void (CdbEngine::*BuiltinCommandHandler)(const CdbBuiltinCommandPtr &);
    typedef void (CdbEngine::*ExtensionCommandHandler)(const CdbExtensionCommandPtr &);

82 83
    CdbEngine(const DebuggerStartParameters &sp, const OptionsPtr &options);
    ~CdbEngine();
84

85 86
    // Factory function that returns 0 if the debug engine library cannot be found.

87
    virtual bool setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor,
88
                                      const DebuggerToolTipContext &ctx);
89 90 91 92 93 94
    virtual void setupEngine();
    virtual void setupInferior();
    virtual void runEngine();
    virtual void shutdownInferior();
    virtual void shutdownEngine();
    virtual void detachDebugger();
95 96
    virtual void updateWatchData(const WatchData &data,
                                 const WatchUpdateFlags & flags = WatchUpdateFlags());
hjk's avatar
hjk committed
97
    virtual bool hasCapability(unsigned cap) const;
98
    virtual void watchPoint(const QPoint &);
99 100 101 102 103 104 105 106 107 108 109
    virtual void setRegisterValue(int regnr, const QString &value);

    virtual void executeStep();
    virtual void executeStepOut();
    virtual void executeNext();
    virtual void executeStepI();
    virtual void executeNextI();

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

110
    virtual void executeRunToLine(const ContextData &data);
111
    virtual void executeRunToFunction(const QString &functionName);
112
    virtual void executeJumpToLine(const ContextData &data);
113
    virtual void assignValueInDebugger(const WatchData *w, const QString &expr, const QVariant &value);
114
    virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages);
115 116

    virtual void activateFrame(int index);
hjk's avatar
hjk committed
117
    virtual void selectThread(ThreadId threadId);
118

119
    virtual bool stateAcceptsBreakpointChanges() const;
120
    virtual bool acceptsBreakpoint(BreakpointModelId id) const;
121 122
    virtual void attemptBreakpointSynchronization();

123 124
    virtual void fetchDisassembler(DisassemblerAgent *agent);
    virtual void fetchMemory(MemoryAgent *, QObject *, quint64 addr, quint64 length);
125
    virtual void changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, const QByteArray &data);
126 127 128 129 130 131 132 133 134 135

    virtual void reloadModules();
    virtual void loadSymbols(const QString &moduleName);
    virtual void loadAllSymbols();
    virtual void requestModuleSymbols(const QString &moduleName);

    virtual void reloadRegisters();
    virtual void reloadSourceFiles();
    virtual void reloadFullStack();

136
    static QString extensionLibraryName(bool is64Bit);
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159

private slots:
    void readyReadStandardOut();
    void readyReadStandardError();
    void processError();
    void processFinished();
    void postCommand(const QByteArray &cmd, unsigned flags);
    void postBuiltinCommand(const QByteArray &cmd,
                            unsigned flags,
                            BuiltinCommandHandler handler,
                            unsigned nextCommandFlag = 0,
                            const QVariant &cookie = QVariant());

    void postExtensionCommand(const QByteArray &cmd,
                              const QByteArray &arguments,
                              unsigned flags,
                              ExtensionCommandHandler handler,
                              unsigned nextCommandFlag = 0,
                              const QVariant &cookie = QVariant());

    void postCommandSequence(unsigned mask);
    void operateByInstructionTriggered(bool);

160
    void consoleStubError(const QString &);
161 162 163
    void consoleStubProcessStarted();
    void consoleStubExited();

164
private:
165
    typedef QHash<BreakpointModelId, BreakpointResponse> PendingBreakPointMap;
166 167 168 169 170 171 172 173
    typedef QPair<QString, QString> SourcePathMapping;
    struct NormalizedSourceFileName // Struct for caching mapped/normalized source files.
    {
        NormalizedSourceFileName(const QString &fn = QString(), bool e = false) : fileName(fn), exists(e) {}

        QString fileName;
        bool exists;
    };
174

175 176 177 178
    enum SpecialStopMode
    {
        NoSpecialStop,
        SpecialStopSynchronizeBreakpoints,
179 180
        SpecialStopGetWidgetAt,
        CustomSpecialStop // Associated with m_specialStopData, handleCustomSpecialStop()
181
    };
182 183 184 185 186
    enum ParseStackResultFlags // Flags returned by parseStackTrace
    {
        ParseStackStepInto = 1 // Need to execute a step, hit on a call frame in "Step into"
    };

187

188
    bool startConsole(const DebuggerStartParameters &sp, QString *errorMessage);
189
    void init();
190
    unsigned examineStopReason(const GdbMi &stopReason, QString *message,
191 192 193
                               QString *exceptionBoxMessage,
                               bool conditionalBreakPointTriggered = false);
    void processStop(const GdbMi &stopReason, bool conditionalBreakPointTriggered = false);
194
    bool commandsPending() const;
195 196
    void handleExtensionMessage(char t, int token, const QByteArray &what, const QByteArray &message);
    bool doSetupEngine(QString *errorMessage);
197
    bool launchCDB(const DebuggerStartParameters &sp, QString *errorMessage);
198 199 200
    void handleSessionAccessible(unsigned long cdbExState);
    void handleSessionInaccessible(unsigned long cdbExState);
    void handleSessionIdle(const QByteArray &message);
201
    bool doInterruptInferior(SpecialStopMode sm);
202
    void doInterruptInferiorCustomSpecialStop(const QVariant &v);
203 204 205
    void doContinueInferior();
    inline void parseOutputLine(QByteArray line);
    inline bool isCdbProcessRunning() const { return m_process.state() != QProcess::NotRunning; }
206
    bool canInterruptInferior() const;
207
    void syncOperateByInstruction(bool operateByInstruction);
208
    void postWidgetAtCommand();
209
    void handleCustomSpecialStop(const QVariant &v);
210
    void postFetchMemory(const MemoryViewCookie &c);
211 212 213 214 215
    inline void postDisassemblerCommand(quint64 address, const QVariant &cookie = QVariant());
    void postDisassemblerCommand(quint64 address, quint64 endAddress,
                                 const QVariant &cookie = QVariant());
    void postResolveSymbol(const QString &module, const QString &function,
                           const QVariant &cookie =  QVariant());
216
    void evaluateExpression(QByteArray exp, const QVariant &cookie = QVariant());
217 218
    // Builtin commands
    void dummyHandler(const CdbBuiltinCommandPtr &);
219
    void handleStackTrace(const CdbExtensionCommandPtr &);
220 221 222
    void handleRegisters(const CdbBuiltinCommandPtr &);
    void handleDisassembler(const CdbBuiltinCommandPtr &);
    void handleJumpToLineAddressResolution(const CdbBuiltinCommandPtr &);
223
    void handleExpression(const CdbExtensionCommandPtr &);
224 225
    void handleResolveSymbol(const CdbBuiltinCommandPtr &command);
    void handleResolveSymbol(const QList<quint64> &addresses, const QVariant &cookie);
226
    void jumpToAddress(quint64 address);
227

228 229 230 231
    // Extension commands
    void handleThreads(const CdbExtensionCommandPtr &);
    void handlePid(const CdbExtensionCommandPtr &reply);
    void handleLocals(const CdbExtensionCommandPtr &reply);
232
    void handleAddWatch(const CdbExtensionCommandPtr &reply);
233 234 235 236
    void handleExpandLocals(const CdbExtensionCommandPtr &reply);
    void handleRegisters(const CdbExtensionCommandPtr &reply);
    void handleModules(const CdbExtensionCommandPtr &reply);
    void handleMemory(const CdbExtensionCommandPtr &);
237
    void handleWidgetAt(const CdbExtensionCommandPtr &);
238 239
    void handleBreakPoints(const CdbExtensionCommandPtr &);
    void handleBreakPoints(const GdbMi &value);
240
    NormalizedSourceFileName sourceMapNormalizeFileNameFromDebugger(const QString &f);
241
    void updateLocalVariable(const QByteArray &iname);
242
    void updateLocals(bool forNewStackFrame = false);
243
    int elapsedLogTime() const;
244
    void addLocalsOptions(ByteArrayInputStream &s) const;
245
    unsigned parseStackTrace(const GdbMi &data, bool sourceStepInto);
246 247 248 249 250 251

    const QByteArray m_creatorExtPrefix;
    const QByteArray m_tokenPrefix;
    const OptionsPtr m_options;

    QProcess m_process;
252 253
    QScopedPointer<Utils::ConsoleProcess> m_consoleStub;
    DebuggerStartMode m_effectiveStartMode;
254
    QByteArray m_outputBuffer;
255
    //! Debugger accessible (expecting commands)
256 257 258 259
    bool m_accessible;
    SpecialStopMode m_specialStopMode;
    int m_nextCommandToken;
    QList<CdbBuiltinCommandPtr> m_builtinCommandQueue;
260
    int m_currentBuiltinCommandIndex; //!< Current command whose output is recorded.
261
    QList<CdbExtensionCommandPtr> m_extensionCommandQueue;
262
    QMap<QString, NormalizedSourceFileName> m_normalizedFileCache;
263 264
    const QByteArray m_extensionCommandPrefixBA; //!< Library name used as prefix
    bool m_operateByInstructionPending; //!< Creator operate by instruction action changed.
265 266 267 268 269
    bool m_operateByInstruction;
    bool m_notifyEngineShutdownOnTermination;
    bool m_hasDebuggee;
    QTime m_logTime;
    mutable int m_elapsedLogTime;
270
    QByteArray m_extensionMessageBuffer;
271
    bool m_sourceStepInto;
272 273
    int m_watchPointX;
    int m_watchPointY;
274 275
    PendingBreakPointMap m_pendingBreakpointMap;
    QHash<QString, QString> m_fileNameModuleHash;
276
    QMultiHash<QString, quint64> m_symbolAddressCache;
277
    QHash<QByteArray, QString> m_watchInameToName;
278
    bool m_ignoreCdbOutput;
279
    QVariantList m_customSpecialStopData;
280
    QList<SourcePathMapping> m_sourcePathMappings;
281
    QScopedPointer<GdbMi> m_coreStopReason;
282 283
};

284
} // namespace Internal
285 286 287
} // namespace Debugger

#endif // DEBUGGER_CDBENGINE_H