File indexing completed on 2024-04-28 05:48:32
0001 /* 0002 SPDX-FileCopyrightText: 2022 Héctor Mesa Jiménez <wmj.py@gmx.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 #pragma once 0007 0008 #include <QObject> 0009 0010 #include "backendinterface.h" 0011 #include "configview.h" 0012 #include "dap/client.h" 0013 #include "dap/entities.h" 0014 #include "dap/settings.h" 0015 #include <memory> 0016 #include <optional> 0017 0018 class DapBackend : public BackendInterface 0019 { 0020 Q_OBJECT 0021 public: 0022 DapBackend(QObject *parent); 0023 ~DapBackend() override = default; 0024 0025 void runDebugger(const DAPTargetConf &conf); 0026 bool debuggerRunning() const override; 0027 bool debuggerBusy() const override; 0028 bool hasBreakpoint(QUrl const &url, int line) const override; 0029 0030 bool supportsMovePC() const override; 0031 bool supportsRunToCursor() const override; 0032 bool canSetBreakpoints() const override; 0033 bool canMove() const override; 0034 bool canContinue() const override; 0035 0036 void toggleBreakpoint(QUrl const &url, int line) override; 0037 void movePC(QUrl const &url, int line) override; 0038 void runToCursor(QUrl const &url, int line) override; 0039 0040 void issueCommand(QString const &cmd) override; 0041 0042 QString targetName() const override; 0043 void setFileSearchPaths(const QStringList &paths) override; 0044 0045 public Q_SLOTS: 0046 void slotInterrupt() override; 0047 void slotStepInto() override; 0048 void slotStepOver() override; 0049 void slotStepOut() override; 0050 void slotContinue() override; 0051 void slotKill() override; 0052 void slotReRun() override; 0053 QString slotPrintVariable(const QString &variable) override; 0054 0055 void slotQueryLocals(bool display) override; 0056 void changeStackFrame(int index) override; 0057 void changeThread(int index) override; 0058 void changeScope(int scopeId) override; 0059 0060 private: 0061 enum State { None, Initializing, Running, Stopped, Terminated, Disconnected, PostMortem }; 0062 enum Task { Idle, Busy }; 0063 0064 void unsetClient(); 0065 0066 void onError(const QString &message); 0067 void onTerminated(); 0068 void onStopped(const dap::StoppedEvent &info); 0069 void onThreads(const QList<dap::Thread> &threads); 0070 void onStackTrace(const int, const dap::StackTraceInfo &info); 0071 void onProgramEnded(int exitCode); 0072 void onRunning(); 0073 void onContinuedEvent(const dap::ContinuedEvent &info); 0074 void onInitialized(); 0075 void onErrorResponse(const QString &summary, const std::optional<dap::Message> &message); 0076 void onOutputProduced(const dap::Output &output); 0077 void onDebuggingProcess(const dap::ProcessInfo &info); 0078 void onThreadEvent(const dap::ThreadEvent &info); 0079 void onModuleEvent(const dap::ModuleEvent &info); 0080 void onScopes(const int frameId, const QList<dap::Scope> &scopes); 0081 void onVariables(const int variablesReference, const QList<dap::Variable> &variables); 0082 void onModules(const dap::ModulesInfo &modules); 0083 void onSourceBreakpoints(const QString &path, int reference, const std::optional<QList<dap::Breakpoint>> &breakpoints); 0084 void onBreakpointEvent(const dap::BreakpointEvent &info); 0085 void onExpressionEvaluated(const QString &expression, const std::optional<dap::EvaluateInfo> &info); 0086 void onGotoTargets(const dap::Source &, const int, const QList<dap::GotoTarget> &targets); 0087 void onCapabilitiesReceived(const dap::Capabilities &capabilities); 0088 void onServerDisconnected(); 0089 void onServerFinished(); 0090 0091 bool tryTerminate(); 0092 bool tryDisconnect(); 0093 void cmdShutdown(); 0094 void cmdHelp(const QString &cmd); 0095 void cmdEval(const QString &cmd); 0096 void cmdJump(const QString &cmd); 0097 void cmdRunToCursor(const QString &cmd); 0098 void cmdListModules(const QString &cmd); 0099 void cmdListBreakpoints(const QString &cmd); 0100 void cmdBreakpointOn(const QString &cmd); 0101 void cmdBreakpointOff(const QString &cmd); 0102 void cmdPause(const QString &cmd); 0103 void cmdContinue(const QString &cmd); 0104 void cmdNext(const QString &cmd); 0105 void cmdStepIn(const QString &cmd); 0106 void cmdStepOut(const QString &cmd); 0107 void cmdWhereami(const QString &cmd); 0108 0109 void resetState(State state = State::Running); 0110 void setState(State state); 0111 void setTaskState(Task state); 0112 0113 bool isConnectedState() const; 0114 bool isAttachedState() const; 0115 bool isRunningState() const; 0116 0117 void pushRequest(); 0118 void popRequest(); 0119 0120 QString resolveOrWarn(const QString &filename); 0121 std::optional<QString> resolveFilename(const QString &filename, bool fallback = true) const; 0122 dap::settings::ClientSettings &target2dap(const DAPTargetConf &target); 0123 std::optional<int> findBreakpoint(const QString &path, int line) const; 0124 std::optional<int> findBreakpointIntent(const QString &path, int line) const; 0125 0126 void insertBreakpoint(const QString &path, int line); 0127 // return false if nothing found 0128 bool removeBreakpoint(const QString &path, int line); 0129 void informBreakpointAdded(const QString &path, const dap::Breakpoint &bpoint); 0130 void informBreakpointRemoved(const QString &path, int line); 0131 void clearBreakpoints(); 0132 void informStackFrame(); 0133 0134 QString m_targetName; 0135 0136 void start(); 0137 0138 dap::Client *m_client = nullptr; 0139 std::optional<dap::settings::ClientSettings> m_settings; 0140 State m_state; 0141 Task m_task; 0142 0143 QString m_file; 0144 QString m_workDir; 0145 std::optional<int> m_currentThread; 0146 std::optional<int> m_watchedThread; 0147 std::optional<int> m_currentFrame; 0148 std::optional<int> m_currentScope; 0149 bool m_restart = false; 0150 bool m_queryLocals = false; 0151 0152 enum KillMode { Polite, Force }; 0153 0154 struct { 0155 std::optional<State> target = std::nullopt; 0156 std::optional<KillMode> userAction = std::nullopt; 0157 } m_shutdown; 0158 0159 void shutdownUntil(std::optional<State> state = std::nullopt); 0160 bool continueShutdown() const; 0161 0162 struct Cursor { 0163 int line; 0164 QString path; 0165 }; 0166 std::optional<Cursor> m_runToCursor; 0167 0168 int m_requests; 0169 0170 QStringList m_commandQueue; 0171 0172 std::map<QString, QList<std::optional<dap::Breakpoint>>> m_breakpoints; 0173 std::map<QString, QList<dap::SourceBreakpoint>> m_wantedBreakpoints; 0174 QList<dap::StackFrame> m_frames; 0175 };