File indexing completed on 2024-05-05 05:51:31

0001 /**
0002  * Description: Common interface for GDB and DAP clients
0003  *
0004  *  SPDX-FileCopyrightText: 2022 Héctor Mesa Jiménez <wmj.py@gmx.com>
0005  *
0006  *  SPDX-License-Identifier: LGPL-2.0-or-later
0007  */
0008 
0009 #include "backend.h"
0010 #include "dapbackend.h"
0011 #include "gdbbackend.h"
0012 #include <KLocalizedString>
0013 #include <KMessageBox>
0014 
0015 Backend::Backend(QObject *parent)
0016     : BackendInterface(parent)
0017     , m_debugger(nullptr)
0018 {
0019 }
0020 
0021 void Backend::runDebugger(const GDBTargetConf &conf, const QStringList &ioFifos)
0022 {
0023     if (m_debugger && m_debugger->debuggerRunning()) {
0024         KMessageBox::error(nullptr, i18n("A debugging session is on course. Please, use re-run or stop the current session."));
0025         return;
0026     }
0027 
0028     GdbBackend *gdb;
0029 
0030     if (m_mode != GDB) {
0031         unbind();
0032         m_debugger = gdb = new GdbBackend(this);
0033         m_mode = GDB;
0034         bind();
0035     } else {
0036         gdb = qobject_cast<GdbBackend *>(m_debugger);
0037     }
0038 
0039     gdb->runDebugger(conf, ioFifos);
0040 
0041     if (m_displayQueryLocals) {
0042         gdb->slotQueryLocals(*m_displayQueryLocals);
0043     }
0044 }
0045 
0046 void Backend::runDebugger(const DAPTargetConf &conf)
0047 {
0048     if (m_debugger && m_debugger->debuggerRunning()) {
0049         KMessageBox::error(nullptr, i18n("A debugging session is on course. Please, use re-run or stop the current session."));
0050         return;
0051     }
0052 
0053     DapBackend *dap;
0054 
0055     unbind();
0056     m_debugger = dap = new DapBackend(this);
0057     m_mode = DAP;
0058     bind();
0059 
0060     dap->runDebugger(conf);
0061 
0062     if (m_displayQueryLocals) {
0063         dap->slotQueryLocals(*m_displayQueryLocals);
0064     }
0065 }
0066 
0067 void Backend::bind()
0068 {
0069     connect(m_debugger, &BackendInterface::debugLocationChanged, this, &BackendInterface::debugLocationChanged);
0070     connect(m_debugger, &BackendInterface::breakPointSet, this, &BackendInterface::breakPointSet);
0071     connect(m_debugger, &BackendInterface::breakPointCleared, this, &BackendInterface::breakPointCleared);
0072     connect(m_debugger, &BackendInterface::clearBreakpointMarks, this, &BackendInterface::clearBreakpointMarks);
0073     connect(m_debugger, &BackendInterface::stackFrameInfo, this, &BackendInterface::stackFrameInfo);
0074     connect(m_debugger, &BackendInterface::stackFrameChanged, this, &BackendInterface::stackFrameChanged);
0075     connect(m_debugger, &BackendInterface::threadInfo, this, &BackendInterface::threadInfo);
0076 
0077     connect(m_debugger, &BackendInterface::variableInfo, this, &BackendInterface::variableInfo);
0078     connect(m_debugger, &BackendInterface::variableScopeOpened, this, &BackendInterface::variableScopeOpened);
0079     connect(m_debugger, &BackendInterface::variableScopeClosed, this, &BackendInterface::variableScopeClosed);
0080 
0081     connect(m_debugger, &BackendInterface::outputText, this, &BackendInterface::outputText);
0082     connect(m_debugger, &BackendInterface::outputError, this, &BackendInterface::outputError);
0083     connect(m_debugger, &BackendInterface::readyForInput, this, &BackendInterface::readyForInput);
0084     connect(m_debugger, &BackendInterface::programEnded, this, &BackendInterface::programEnded);
0085     connect(m_debugger, &BackendInterface::gdbEnded, this, &BackendInterface::gdbEnded);
0086     connect(m_debugger, &BackendInterface::sourceFileNotFound, this, &BackendInterface::sourceFileNotFound);
0087     connect(m_debugger, &BackendInterface::scopesInfo, this, &BackendInterface::scopesInfo);
0088 
0089     connect(m_debugger, &BackendInterface::debuggerCapabilitiesChanged, this, &BackendInterface::debuggerCapabilitiesChanged);
0090 
0091     connect(m_debugger, &BackendInterface::debuggeeOutput, this, &BackendInterface::debuggeeOutput);
0092     connect(m_debugger, &BackendInterface::backendError, this, &BackendInterface::backendError);
0093 }
0094 
0095 void Backend::unbind()
0096 {
0097     if (!m_debugger)
0098         return;
0099     disconnect(m_debugger, nullptr, this, nullptr);
0100     delete m_debugger;
0101 }
0102 
0103 bool Backend::debuggerRunning() const
0104 {
0105     return m_debugger && m_debugger->debuggerRunning();
0106 }
0107 
0108 bool Backend::debuggerBusy() const
0109 {
0110     return !m_debugger || m_debugger->debuggerBusy();
0111 }
0112 
0113 bool Backend::hasBreakpoint(QUrl const &url, int line) const
0114 {
0115     return m_debugger && m_debugger->hasBreakpoint(url, line);
0116 }
0117 
0118 bool Backend::supportsMovePC() const
0119 {
0120     return m_debugger && m_debugger->supportsMovePC();
0121 }
0122 
0123 bool Backend::supportsRunToCursor() const
0124 {
0125     return m_debugger && m_debugger->supportsRunToCursor();
0126 }
0127 
0128 bool Backend::canSetBreakpoints() const
0129 {
0130     return m_debugger && m_debugger->canSetBreakpoints();
0131 }
0132 
0133 bool Backend::canMove() const
0134 {
0135     return m_debugger && m_debugger->canMove();
0136 }
0137 
0138 bool Backend::canContinue() const
0139 {
0140     return m_debugger && m_debugger->canContinue();
0141 }
0142 
0143 void Backend::toggleBreakpoint(QUrl const &url, int line)
0144 {
0145     if (m_debugger)
0146         m_debugger->toggleBreakpoint(url, line);
0147 }
0148 
0149 void Backend::movePC(QUrl const &url, int line)
0150 {
0151     if (m_debugger)
0152         m_debugger->movePC(url, line);
0153 }
0154 
0155 void Backend::runToCursor(QUrl const &url, int line)
0156 {
0157     if (m_debugger)
0158         m_debugger->runToCursor(url, line);
0159 }
0160 
0161 void Backend::issueCommand(QString const &cmd)
0162 {
0163     if (m_debugger)
0164         m_debugger->issueCommand(cmd);
0165 }
0166 
0167 QString Backend::targetName() const
0168 {
0169     if (m_debugger)
0170         return m_debugger->targetName();
0171     return QString();
0172 }
0173 
0174 void Backend::setFileSearchPaths(const QStringList &paths)
0175 {
0176     if (m_debugger)
0177         m_debugger->setFileSearchPaths(paths);
0178 }
0179 
0180 void Backend::slotInterrupt()
0181 {
0182     if (m_debugger)
0183         m_debugger->slotInterrupt();
0184 }
0185 
0186 void Backend::slotStepInto()
0187 {
0188     if (m_debugger)
0189         m_debugger->slotStepInto();
0190 }
0191 
0192 void Backend::slotStepOver()
0193 {
0194     if (m_debugger)
0195         m_debugger->slotStepOver();
0196 }
0197 
0198 void Backend::slotStepOut()
0199 {
0200     if (m_debugger)
0201         m_debugger->slotStepOut();
0202 }
0203 
0204 void Backend::slotContinue()
0205 {
0206     if (m_debugger)
0207         m_debugger->slotContinue();
0208 }
0209 
0210 void Backend::slotKill()
0211 {
0212     if (m_debugger)
0213         m_debugger->slotKill();
0214 }
0215 
0216 void Backend::slotReRun()
0217 {
0218     if (m_debugger)
0219         m_debugger->slotReRun();
0220 }
0221 
0222 QString Backend::slotPrintVariable(const QString &variable)
0223 {
0224     if (m_debugger)
0225         return m_debugger->slotPrintVariable(variable);
0226     return QString();
0227 }
0228 
0229 void Backend::slotQueryLocals(bool display)
0230 {
0231     if (m_debugger) {
0232         m_debugger->slotQueryLocals(display);
0233         m_displayQueryLocals = std::nullopt;
0234     } else {
0235         m_displayQueryLocals = display;
0236     }
0237 }
0238 
0239 void Backend::changeStackFrame(int index)
0240 {
0241     if (m_debugger)
0242         m_debugger->changeStackFrame(index);
0243 }
0244 
0245 void Backend::changeThread(int thread)
0246 {
0247     if (m_debugger)
0248         m_debugger->changeThread(thread);
0249 }
0250 
0251 void Backend::changeScope(int scopeId)
0252 {
0253     if (m_debugger)
0254         m_debugger->changeScope(scopeId);
0255 }
0256 
0257 #include "moc_backend.cpp"