File indexing completed on 2024-04-28 04:38:34

0001 /*
0002     SPDX-FileCopyrightText: 2007 Vladimir Prus <ghost@cs.msu.su>
0003     SPDX-FileCopyrightText: 2016 Aetf <aetf@unlimitedcodeworks.xyz>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef MIDEBUGGER_H
0009 #define MIDEBUGGER_H
0010 
0011 #include "mi/mi.h"
0012 #include "mi/miparser.h"
0013 
0014 #include <KProcess>
0015 
0016 #include <QByteArray>
0017 #include <QObject>
0018 
0019 #include <memory>
0020 
0021 class KConfigGroup;
0022 class KProcess;
0023 
0024 namespace KDevMI {
0025 
0026 namespace MI {
0027 class MICommand;
0028 }
0029 
0030 
0031 class MIDebugger : public QObject
0032 {
0033     Q_OBJECT
0034 public:
0035     explicit MIDebugger(QObject* parent = nullptr);
0036     ~MIDebugger() override;
0037 
0038     /** Starts the debugger.  This should be done after connecting to all
0039         signals the client is interested in.  */
0040     virtual bool start(KConfigGroup& config, const QStringList& extraArguments = {}) = 0;
0041 
0042     /** Executes a command.  This method may be called at
0043         most once each time 'ready' is emitted.  When the
0044         debugger instance is just constructed, one should wait
0045         for 'ready' as well.
0046 
0047         The ownership of 'command' is transferred to the debugger.  */
0048     void execute(std::unique_ptr<MI::MICommand> command);
0049 
0050     /** Returns true if 'execute' can be called immediately.  */
0051     bool isReady() const;
0052 
0053     /** FIXME: temporary, to be eliminated.  */
0054     MI::MICommand* currentCommand() const;
0055 
0056     /** Arrange to debugger to stop doing whatever it's doing,
0057         and start waiting for a command.
0058         FIXME: probably should make sure that 'ready' is
0059         emitted, or something.  */
0060     void interrupt();
0061 
0062     /** Kills the debugger.  */
0063     void kill();
0064 
0065 Q_SIGNALS:
0066     /** Emitted when debugger becomes ready -- i.e. when
0067         isReady call will return true.  */
0068     void ready();
0069 
0070     /** Emitted when the debugger itself exits. This could happen because
0071         it just crashed due to internal bug, or we killed it
0072         explicitly.  */
0073     void exited(bool abnormal, const QString &msg);
0074 
0075     /** Emitted when debugger reports stop, with 'r' being the
0076         data provided by the debugger. */
0077     void programStopped(const MI::AsyncRecord& r);
0078 
0079     /** Emitted when debugger believes that the program is running.  */
0080     void programRunning();
0081 
0082     /** Emitted for each MI stream record found.  Presently only
0083      used to recognize some CLI messages that mean that the program
0084     has died. 
0085     FIXME: connect to parseCliLine
0086     */
0087     void streamRecord(const MI::StreamRecord& s);
0088 
0089     /** Reports an async notification record.  */
0090     void notification(const MI::AsyncRecord& n);
0091 
0092     /** Emitted for error that is not handled by the
0093         command being executed. */
0094     void error(const MI::ResultRecord& s);
0095 
0096     /** Reports output from the running application.
0097         Generally output will only be available when
0098         using remote debugger targets. When running locally,
0099         the output will either appear on debugger stdout, and
0100         ignored, or routed via pty.  */
0101     void applicationOutput(const QString& s);
0102 
0103     /** Reports output of a command explicitly typed by
0104         the user, or output from .gdbinit commands.  */
0105     void userCommandOutput(const QString& s);
0106 
0107     /** Reports output of a command issued internally
0108         by KDevelop. */
0109     void internalCommandOutput(const QString& s);
0110 
0111     /** Reports debugger internal output, including stderr output from debugger
0112         and the 'log' MI channel */
0113     void debuggerInternalOutput(const QString& s);
0114 
0115 protected Q_SLOTS:
0116     void readyReadStandardOutput();
0117     void readyReadStandardError();
0118     void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
0119     void processErrored(QProcess::ProcessError);
0120 
0121 protected:
0122     void processLine(const QByteArray& line);
0123 
0124 protected:
0125     QString m_debuggerExecutable;
0126     KProcess* m_process = nullptr;
0127 
0128     std::unique_ptr<MI::MICommand> m_currentCmd;
0129     MI::MIParser m_parser;
0130 
0131     /** The unprocessed output from debugger. Output is
0132         processed as soon as we see newline. */
0133     QByteArray m_buffer;
0134 };
0135 
0136 }
0137 
0138 #endif