[Lldb-commits] [lldb] [lldb-server] Add connection info to accelerator plugin protocol (PR #201449)

satyanarayana reddy janga via lldb-commits lldb-commits at lists.llvm.org
Mon Jun 8 05:22:00 PDT 2026


https://github.com/satyajanga updated https://github.com/llvm/llvm-project/pull/201449

>From c3066373d89e5ea8c862a0ae1419acb0ca0345b6 Mon Sep 17 00:00:00 2001
From: satya janga <satyajanga at fb.com>
Date: Sat, 6 Jun 2026 08:25:45 -0700
Subject: [PATCH] [lldb] Add connection info to the accelerator plugin protocol

Add AcceleratorConnectionInfo, describing how the client should create a
new target and reverse-connect to a separate GDB server that serves an
accelerator's state (e.g. a GPU debug stub). It carries the connect URL
and optional exe path, platform name, triple, and a synchronous flag.

A connect_info field is added to AcceleratorActions so a plugin can ask
the client to establish such a connection alongside (or instead of)
setting breakpoints. This is the wire-format foundation; the client-side
handling that acts on connect_info comes in a follow-up.

Adds JSON serialization, unit tests, and documents the new fields in the
jAcceleratorPluginInitialize packet.
---
 lldb/docs/resources/lldbgdbremote.md          | 16 +++++-
 .../Utility/AcceleratorGDBRemotePackets.h     | 27 ++++++++++
 .../Utility/AcceleratorGDBRemotePackets.cpp   | 25 ++++++++-
 .../AcceleratorGDBRemotePacketsTest.cpp       | 53 +++++++++++++++++++
 4 files changed, 117 insertions(+), 4 deletions(-)

diff --git a/lldb/docs/resources/lldbgdbremote.md b/lldb/docs/resources/lldbgdbremote.md
index 1fc04e5ce9e11..862e696f156f1 100644
--- a/lldb/docs/resources/lldbgdbremote.md
+++ b/lldb/docs/resources/lldbgdbremote.md
@@ -2750,9 +2750,21 @@ breakpoints to be set in the native process. See
 `jAcceleratorPluginBreakpointHit` for the callback when those breakpoints
 are hit.
 
+An `accelerator_action` may also include a `connect_info` object asking the
+client to create a new target and connect to a separate GDB server that
+serves the accelerator's state (for example a GPU debug stub). It has the
+following fields:
+
+| Key             | Type   | Description |
+|-----------------|--------|-------------|
+| `connect_url`   | string | Connection URL to connect to, as used by `process connect <url>`. |
+| `exe_path`      | string | Optional path to the executable to use when creating the accelerator target. If omitted, an empty target is created. |
+| `platform_name` | string | Optional name of the platform to select for the accelerator target. |
+| `triple`        | string | Optional target triple to use as the architecture for the accelerator target. |
+| `synchronous`   | bool   | If true, the client waits for the accelerator process to finish initializing before continuing. |
+
 In future patches, each `accelerator_action` will include additional fields
-such as connection info for secondary debug sessions and synchronization
-options.
+such as synchronization options for the accelerator process.
 
 **Priority To Implement:** Required for hardware accelerator debugging
 support. Not needed for non-hardware-accelerator debugging.
diff --git a/lldb/include/lldb/Utility/AcceleratorGDBRemotePackets.h b/lldb/include/lldb/Utility/AcceleratorGDBRemotePackets.h
index 9ba36fc540a52..69cf2bd2e7def 100644
--- a/lldb/include/lldb/Utility/AcceleratorGDBRemotePackets.h
+++ b/lldb/include/lldb/Utility/AcceleratorGDBRemotePackets.h
@@ -85,6 +85,30 @@ bool fromJSON(const llvm::json::Value &value,
               AcceleratorBreakpointHitArgs &data, llvm::json::Path path);
 llvm::json::Value toJSON(const AcceleratorBreakpointHitArgs &data);
 
+/// Information the client needs to create a reverse connection to an
+/// accelerator GDB server (e.g. a separate process serving the accelerator's
+/// register and memory state). When an AcceleratorActions carries this, the
+/// client creates a new target and connects to \a connect_url.
+struct AcceleratorConnectionInfo {
+  /// Path to the executable to use when creating the accelerator target. If
+  /// not set, an empty target is created.
+  std::optional<std::string> exe_path;
+  /// Name of the platform to select for the accelerator target.
+  std::optional<std::string> platform_name;
+  /// Target triple to use as the architecture for the accelerator target.
+  std::optional<std::string> triple;
+  /// Connection URL the client should connect to (as in "process connect
+  /// <url>").
+  std::string connect_url;
+  /// If true, the client waits for the accelerator process to finish
+  /// initializing before continuing.
+  bool synchronous = false;
+};
+
+bool fromJSON(const llvm::json::Value &value, AcceleratorConnectionInfo &data,
+              llvm::json::Path path);
+llvm::json::Value toJSON(const AcceleratorConnectionInfo &data);
+
 /// Actions to be performed in the native process on behalf of an accelerator
 /// plugin. AcceleratorActions are returned in the following contexts:
 ///
@@ -114,6 +138,9 @@ struct AcceleratorActions {
   int64_t identifier = 0;
   /// New breakpoints to set. Nothing to set if this is empty.
   std::vector<AcceleratorBreakpointInfo> breakpoints;
+  /// If set, the client should create a new target and connect to the
+  /// accelerator GDB server described here.
+  std::optional<AcceleratorConnectionInfo> connect_info;
 };
 
 bool fromJSON(const llvm::json::Value &value, AcceleratorActions &data,
diff --git a/lldb/source/Utility/AcceleratorGDBRemotePackets.cpp b/lldb/source/Utility/AcceleratorGDBRemotePackets.cpp
index 34067b1fa64c7..18282b5ebdfb3 100644
--- a/lldb/source/Utility/AcceleratorGDBRemotePackets.cpp
+++ b/lldb/source/Utility/AcceleratorGDBRemotePackets.cpp
@@ -86,21 +86,42 @@ AcceleratorBreakpointHitArgs::GetSymbolValue(StringRef symbol_name) const {
   return std::nullopt;
 }
 
+bool fromJSON(const Value &value, AcceleratorConnectionInfo &data, Path path) {
+  ObjectMapper o(value, path);
+  return o && o.mapOptional("exe_path", data.exe_path) &&
+         o.mapOptional("platform_name", data.platform_name) &&
+         o.mapOptional("triple", data.triple) &&
+         o.map("connect_url", data.connect_url) &&
+         o.map("synchronous", data.synchronous);
+}
+
+json::Value toJSON(const AcceleratorConnectionInfo &data) {
+  return Object{
+      {"exe_path", data.exe_path},       {"platform_name", data.platform_name},
+      {"triple", data.triple},           {"connect_url", data.connect_url},
+      {"synchronous", data.synchronous},
+  };
+}
+
 bool fromJSON(const Value &value, AcceleratorActions &data, Path path) {
   ObjectMapper o(value, path);
   return o && o.map("plugin_name", data.plugin_name) &&
          o.map("session_name", data.session_name) &&
          o.map("identifier", data.identifier) &&
-         o.map("breakpoints", data.breakpoints);
+         o.map("breakpoints", data.breakpoints) &&
+         o.mapOptional("connect_info", data.connect_info);
 }
 
 json::Value toJSON(const AcceleratorActions &data) {
-  return Object{
+  Object obj{
       {"plugin_name", data.plugin_name},
       {"session_name", data.session_name},
       {"identifier", data.identifier},
       {"breakpoints", data.breakpoints},
   };
+  if (data.connect_info)
+    obj["connect_info"] = *data.connect_info;
+  return obj;
 }
 
 bool fromJSON(const Value &value, AcceleratorBreakpointHitResponse &data,
diff --git a/lldb/unittests/Utility/AcceleratorGDBRemotePacketsTest.cpp b/lldb/unittests/Utility/AcceleratorGDBRemotePacketsTest.cpp
index fdcb0585fa3c7..f06df0119617a 100644
--- a/lldb/unittests/Utility/AcceleratorGDBRemotePacketsTest.cpp
+++ b/lldb/unittests/Utility/AcceleratorGDBRemotePacketsTest.cpp
@@ -187,3 +187,56 @@ TEST(AcceleratorGDBRemotePacketsTest,
   EXPECT_EQ("exit",
             deserialized->actions->breakpoints[0].by_name->function_name);
 }
+
+TEST(AcceleratorGDBRemotePacketsTest, AcceleratorConnectionInfo) {
+  AcceleratorConnectionInfo conn;
+  conn.exe_path = "/path/to/accel.elf";
+  conn.platform_name = "remote-gdb-server";
+  conn.triple = "amdgcn-amd-amdhsa";
+  conn.connect_url = "connect://localhost:1234";
+  conn.synchronous = true;
+
+  Expected<AcceleratorConnectionInfo> deserialized = roundtripJSON(conn);
+  ASSERT_THAT_EXPECTED(deserialized, Succeeded());
+  EXPECT_EQ(conn.exe_path, deserialized->exe_path);
+  EXPECT_EQ(conn.platform_name, deserialized->platform_name);
+  EXPECT_EQ(conn.triple, deserialized->triple);
+  EXPECT_EQ(conn.connect_url, deserialized->connect_url);
+  EXPECT_EQ(conn.synchronous, deserialized->synchronous);
+}
+
+TEST(AcceleratorGDBRemotePacketsTest, AcceleratorConnectionInfoMinimal) {
+  AcceleratorConnectionInfo conn;
+  conn.connect_url = "connect://localhost:5678";
+
+  Expected<AcceleratorConnectionInfo> deserialized = roundtripJSON(conn);
+  ASSERT_THAT_EXPECTED(deserialized, Succeeded());
+  EXPECT_EQ(std::nullopt, deserialized->exe_path);
+  EXPECT_EQ(std::nullopt, deserialized->platform_name);
+  EXPECT_EQ(std::nullopt, deserialized->triple);
+  EXPECT_EQ(conn.connect_url, deserialized->connect_url);
+  EXPECT_FALSE(deserialized->synchronous);
+}
+
+TEST(AcceleratorGDBRemotePacketsTest, AcceleratorActionsWithConnectInfo) {
+  AcceleratorActions actions("mock", 3);
+  AcceleratorConnectionInfo conn;
+  conn.connect_url = "connect://localhost:9999";
+  conn.synchronous = true;
+  actions.connect_info = std::move(conn);
+
+  Expected<AcceleratorActions> deserialized = roundtripJSON(actions);
+  ASSERT_THAT_EXPECTED(deserialized, Succeeded());
+  ASSERT_TRUE(deserialized->connect_info.has_value());
+  EXPECT_EQ("connect://localhost:9999",
+            deserialized->connect_info->connect_url);
+  EXPECT_TRUE(deserialized->connect_info->synchronous);
+}
+
+TEST(AcceleratorGDBRemotePacketsTest, AcceleratorActionsWithoutConnectInfo) {
+  AcceleratorActions actions("mock", 4);
+
+  Expected<AcceleratorActions> deserialized = roundtripJSON(actions);
+  ASSERT_THAT_EXPECTED(deserialized, Succeeded());
+  EXPECT_FALSE(deserialized->connect_info.has_value());
+}



More information about the lldb-commits mailing list