[utilities/kate] /: gdbplugin: also consider and handle exec inspect extra data

Christoph Cullmann null at kde.org
Mon Aug 25 17:27:31 BST 2025


Git commit 19f89639a7cd2facd101b788d445132c0e783839 by Christoph Cullmann, on behalf of Mark Nauwelaerts.
Committed on 25/08/2025 at 16:21.
Pushed by cullmann into branch 'master'.

gdbplugin: also consider and handle exec inspect extra data

M  +3    -0    addons/gdbplugin/configview.cpp
M  +45   -4    addons/gdbplugin/dap/client.cpp
M  +4    -0    addons/gdbplugin/dap/client.h
M  +1    -0    doc/kate/plugins.docbook

https://invent.kde.org/utilities/kate/-/commit/19f89639a7cd2facd101b788d445132c0e783839

diff --git a/addons/gdbplugin/configview.cpp b/addons/gdbplugin/configview.cpp
index e963ed7625..b280b293c3 100644
--- a/addons/gdbplugin/configview.cpp
+++ b/addons/gdbplugin/configview.cpp
@@ -451,6 +451,9 @@ DAPTargetConf ConfigView::currentDAPTarget(bool full, QString &errorMessage) con
             env[Utils::ExecConfig::ENV_KATE_EXEC_PLUGIN] = QStringLiteral("dap");
             env[QStringLiteral("KATE_EXEC_SERVER")] = cfg.debugger;
             env[QStringLiteral("KATE_EXEC_PROFILE")] = cfg.debuggerProfile;
+            // optionally enable mount (intro)inspection
+            if (cfg.dapSettings->pathMap)
+                env[Utils::ExecConfig::ENV_KATE_EXEC_INSPECT] = QStringLiteral("1");
             settings[M_ENV] = env;
         }
 
diff --git a/addons/gdbplugin/dap/client.cpp b/addons/gdbplugin/dap/client.cpp
index 17ef394090..bbca750a77 100644
--- a/addons/gdbplugin/dap/client.cpp
+++ b/addons/gdbplugin/dap/client.cpp
@@ -82,8 +82,10 @@ Client::Client(const settings::ClientSettings &clientSettings, Utils::PathMappin
     , m_protocol(clientSettings.protocolSettings)
     , m_launchCommand(extractCommand(clientSettings.protocolSettings.launchRequest))
     , m_msgParser(new MessageParser())
+    , m_outputMsgParser(new MessageParser())
 {
     m_msgContext = std::make_unique<ClientMessageContext>(pm);
+    m_checkExtraData = pm.get();
     m_bus = createBus(clientSettings.busSettings);
     m_bus->setParent(this);
     bind();
@@ -93,6 +95,7 @@ Client::~Client()
 {
     detach();
     delete m_msgParser;
+    delete m_outputMsgParser;
 }
 
 void Client::bind()
@@ -102,8 +105,7 @@ void Client::bind()
     connect(m_bus, &Bus::closed, this, &Client::finished);
     if (m_protocol.redirectStderr)
         connect(m_bus, &Bus::serverOutput, this, &Client::onServerOutput);
-    if (m_protocol.redirectStdout)
-        connect(m_bus, &Bus::processOutput, this, &Client::onProcessOutput);
+    connect(m_bus, &Bus::processOutput, this, &Client::onProcessOutput);
 }
 
 void Client::detach()
@@ -763,9 +765,30 @@ void Client::onServerOutput(const QByteArray &message)
     Q_EMIT outputProduced(dap::Output(QString::fromLocal8Bit(message), dap::Output::Category::Console));
 }
 
-void Client::onProcessOutput(const QByteArray &message)
+void Client::onProcessOutput(const QByteArray &_message)
 {
-    Q_EMIT outputProduced(dap::Output(QString::fromLocal8Bit(message), dap::Output::Category::Stdout));
+    auto message = _message;
+    if (m_checkExtraData) {
+        if (m_outputMsgParser->m_buffer.isEmpty() && !message.startsWith(DAP_CONTENT_LENGTH)) {
+            m_checkExtraData = false;
+        } else {
+            m_outputMsgParser->push(message);
+            auto extra = m_outputMsgParser->read();
+            if (!extra.size()) {
+                // need more
+                return;
+            }
+            // only 1 attempt, so no more
+            m_checkExtraData = false;
+            processExtraData(extra);
+            // consider remainder
+            message = std::move(m_outputMsgParser->m_buffer);
+            if (!message.size())
+                return;
+        }
+    }
+    if (m_protocol.redirectStdout)
+        Q_EMIT outputProduced(dap::Output(QString::fromLocal8Bit(message), dap::Output::Category::Stdout));
 }
 
 QString Client::extractCommand(const QJsonObject &launchRequest)
@@ -778,6 +801,16 @@ QString Client::extractCommand(const QJsonObject &launchRequest)
     return command;
 }
 
+void Client::processExtraData(const QByteArray &data)
+{
+    auto ctx = static_cast<ClientMessageContext *>(m_msgContext.get());
+    auto mapping = ctx->pathMap;
+    Q_ASSERT(mapping);
+    qCInfo(DAPCLIENT) << "process extra data" << data;
+    bool ok = Utils::updateMapping(*mapping, data);
+    qCInfo(DAPCLIENT) << "map updated" << ok << "now;\n" << *mapping;
+}
+
 void Client::read()
 {
     m_msgParser->push(m_bus->read());
@@ -786,6 +819,14 @@ void Client::read()
         if (!data.size())
             break;
 
+        // check oob data
+        if (m_checkExtraData && data.front() != '{' && !isblank(data.front())) {
+            /* this does not make for valid json, so treat as extra */
+            processExtraData(data);
+            m_checkExtraData = false;
+            continue;
+        }
+
         // parse payload
         QJsonParseError jsonError;
         const auto message = QJsonDocument::fromJson(data, &jsonError);
diff --git a/addons/gdbplugin/dap/client.h b/addons/gdbplugin/dap/client.h
index 2dddb88708..6b41519228 100644
--- a/addons/gdbplugin/dap/client.h
+++ b/addons/gdbplugin/dap/client.h
@@ -192,6 +192,8 @@ private:
     void onServerOutput(const QByteArray &message);
     void onProcessOutput(const QByteArray &message);
 
+    void processExtraData(const QByteArray &data);
+
     /*
      * server capabilities
      */
@@ -219,6 +221,8 @@ private:
     class MessageParser;
     // unique_ptr does not work well with undefined type on some platforms
     MessageParser *const m_msgParser = nullptr;
+    bool m_checkExtraData = false;
+    MessageParser *const m_outputMsgParser = nullptr;
 };
 
 }
diff --git a/doc/kate/plugins.docbook b/doc/kate/plugins.docbook
index f59dfb7984..8578f6235c 100644
--- a/doc/kate/plugins.docbook
+++ b/doc/kate/plugins.docbook
@@ -2010,6 +2010,7 @@ may be provided in a <literal>.kateproject</literal>.
         "mapRemoteRoot": true,
         "pathMappings": [
             // either of the following forms are possible
+            // a more automagic alternative exists as well, see referenced section
             [ "/dir/on/host", "/mounted/in/container" ]
             { "localRoot": "/local/dir", "remoteRoot": "/remote/dir" }
         ]


More information about the kde-doc-english mailing list