[Lldb-commits] [lldb] [lldb] Define accelerator synchronization action fields (PR #237458)

satyanarayana reddy janga via lldb-commits lldb-commits at lists.llvm.org
Fri Oct 30 19:13:40 PDT 2026


https://github.com/satyajanga created https://github.com/llvm/llvm-project/pull/237458

This extends the vendor-neutral `AcceleratorActions` JSON schema with optional
fields for coordinating an accelerator process:

- the accelerator server's `stop_id`
- wait for that stop to be installed
- resume the accelerator process
- wait for that stop to resume

False and absent values remain omitted from serialized actions, preserving the
existing wire representation for current producers. This draft defines and
tests only the common protocol model; dispatch and cross-process
synchronization are intentionally left to a follow-up.

Validation:

- focused LLDB utility build and unit tests
- LLVM C++ formatting check


>From 60c28b70e6630b027cfdd75ebc11184e32089587 Mon Sep 17 00:00:00 2001
From: satya janga <satyajanga at fb.com>
Date: Fri, 30 Oct 2026 19:12:48 -0700
Subject: [PATCH] [lldb] Add accelerator synchronization action schema

---
 lldb/docs/resources/lldbgdbremote.md          | 17 ++++++++++++++--
 .../Utility/AcceleratorGDBRemotePackets.h     | 11 ++++++++++
 .../Utility/AcceleratorGDBRemotePackets.cpp   | 17 +++++++++++++++-
 .../AcceleratorGDBRemotePacketsTest.cpp       | 20 +++++++++++++++++++
 4 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/lldb/docs/resources/lldbgdbremote.md b/lldb/docs/resources/lldbgdbremote.md
index 53a36646444bfe..5473cdd1f0a0e7 100644
--- a/lldb/docs/resources/lldbgdbremote.md
+++ b/lldb/docs/resources/lldbgdbremote.md
@@ -2917,8 +2917,8 @@ FPGAs) alongside the native host process via accelerator plugins installed
 in lldb-server.
 
 An accelerator plugin drives the client by returning a list of
-`AcceleratorActions` (currently just breakpoints to set in the native
-process). The client can receive `AcceleratorActions` at two points:
+`AcceleratorActions`. The client can receive `AcceleratorActions` at two
+points:
 
 1. Once, in response to the `jAcceleratorPluginInitialize` packet sent when
    the native process is launched or attached.
@@ -2997,6 +2997,19 @@ following fields:
 | `exe_path`      | string | Optional path to the executable to use when creating the accelerator target. If omitted, an empty target is created. |
 | `synchronous`   | bool   | If true, connect synchronously: the client blocks until the accelerator process is connected and stopped before continuing. If false, the connection is made asynchronously. |
 
+An `accelerator_action` may also include the following optional fields for
+synchronizing its associated accelerator process:
+
+| Key                                      | Type    | Description |
+|------------------------------------------|---------|-------------|
+| `stop_id`                                | integer | Accelerator GDB server stop identifier associated with the wait actions. |
+| `wait_for_accelerator_process_to_stop`   | bool    | Request that the client wait for the accelerator process to reach `stop_id`. Requires `stop_id`. |
+| `resume_accelerator_process`             | bool    | Request that the client resume the accelerator process. |
+| `wait_for_accelerator_process_to_resume` | bool    | Request that the client wait for the accelerator process to resume from `stop_id`. Requires `stop_id`. |
+
+These fields define the protocol schema. A subsequent client change will act
+on them; adding the fields does not yet synchronize process execution.
+
 **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 6a2ea74ff2bc37..89fb9010d76e78 100644
--- a/lldb/include/lldb/Utility/AcceleratorGDBRemotePackets.h
+++ b/lldb/include/lldb/Utility/AcceleratorGDBRemotePackets.h
@@ -139,11 +139,22 @@ struct AcceleratorActions {
   std::string session_name;
   /// Unique identifier for this action within the plugin.
   int64_t identifier = 0;
+  /// Stop identifier from the accelerator process's GDB server. The wait
+  /// actions below use this to refer to a specific accelerator process stop.
+  std::optional<uint32_t> stop_id;
   /// 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;
+  /// Request that the client wait for the accelerator process to reach
+  /// stop_id.
+  bool wait_for_accelerator_process_to_stop = false;
+  /// Request that the client resume the accelerator process.
+  bool resume_accelerator_process = false;
+  /// Request that the client wait for the accelerator process to resume from
+  /// stop_id.
+  bool wait_for_accelerator_process_to_resume = false;
 };
 
 bool fromJSON(const llvm::json::Value &value, AcceleratorActions &data,
diff --git a/lldb/source/Utility/AcceleratorGDBRemotePackets.cpp b/lldb/source/Utility/AcceleratorGDBRemotePackets.cpp
index 722baa1fceaac7..f4d09dea9680ac 100644
--- a/lldb/source/Utility/AcceleratorGDBRemotePackets.cpp
+++ b/lldb/source/Utility/AcceleratorGDBRemotePackets.cpp
@@ -108,8 +108,15 @@ bool fromJSON(const Value &value, AcceleratorActions &data, Path path) {
   return o && o.map("plugin_name", data.plugin_name) &&
          o.map("session_name", data.session_name) &&
          o.map("identifier", data.identifier) &&
+         o.mapOptional("stop_id", data.stop_id) &&
          o.map("breakpoints", data.breakpoints) &&
-         o.mapOptional("connect_info", data.connect_info);
+         o.mapOptional("connect_info", data.connect_info) &&
+         o.mapOptional("wait_for_accelerator_process_to_stop",
+                       data.wait_for_accelerator_process_to_stop) &&
+         o.mapOptional("resume_accelerator_process",
+                       data.resume_accelerator_process) &&
+         o.mapOptional("wait_for_accelerator_process_to_resume",
+                       data.wait_for_accelerator_process_to_resume);
 }
 
 json::Value toJSON(const AcceleratorActions &data) {
@@ -121,6 +128,14 @@ json::Value toJSON(const AcceleratorActions &data) {
   };
   if (data.connect_info)
     obj["connect_info"] = *data.connect_info;
+  if (data.stop_id)
+    obj["stop_id"] = *data.stop_id;
+  if (data.wait_for_accelerator_process_to_stop)
+    obj["wait_for_accelerator_process_to_stop"] = true;
+  if (data.resume_accelerator_process)
+    obj["resume_accelerator_process"] = true;
+  if (data.wait_for_accelerator_process_to_resume)
+    obj["wait_for_accelerator_process_to_resume"] = true;
   return obj;
 }
 
diff --git a/lldb/unittests/Utility/AcceleratorGDBRemotePacketsTest.cpp b/lldb/unittests/Utility/AcceleratorGDBRemotePacketsTest.cpp
index 857805e56761bd..f216c86093ea6a 100644
--- a/lldb/unittests/Utility/AcceleratorGDBRemotePacketsTest.cpp
+++ b/lldb/unittests/Utility/AcceleratorGDBRemotePacketsTest.cpp
@@ -124,6 +124,10 @@ TEST(AcceleratorGDBRemotePacketsTest, AcceleratorBreakpointHitArgsGetSymbol) {
 TEST(AcceleratorGDBRemotePacketsTest, AcceleratorActions) {
   AcceleratorActions actions("mock", 1);
   actions.session_name = "Mock Session";
+  actions.stop_id = 42;
+  actions.wait_for_accelerator_process_to_stop = true;
+  actions.resume_accelerator_process = true;
+  actions.wait_for_accelerator_process_to_resume = true;
   AcceleratorBreakpointInfo bp;
   bp.identifier = 1;
   bp.by_name = AcceleratorBreakpointByName{std::nullopt, "main"};
@@ -134,6 +138,10 @@ TEST(AcceleratorGDBRemotePacketsTest, AcceleratorActions) {
   EXPECT_EQ("mock", deserialized->plugin_name);
   EXPECT_EQ("Mock Session", deserialized->session_name);
   EXPECT_EQ(1, deserialized->identifier);
+  EXPECT_EQ(42u, deserialized->stop_id);
+  EXPECT_TRUE(deserialized->wait_for_accelerator_process_to_stop);
+  EXPECT_TRUE(deserialized->resume_accelerator_process);
+  EXPECT_TRUE(deserialized->wait_for_accelerator_process_to_resume);
   ASSERT_EQ(1u, deserialized->breakpoints.size());
   EXPECT_EQ(1, deserialized->breakpoints[0].identifier);
   EXPECT_EQ("main", deserialized->breakpoints[0].by_name->function_name);
@@ -142,10 +150,22 @@ TEST(AcceleratorGDBRemotePacketsTest, AcceleratorActions) {
 TEST(AcceleratorGDBRemotePacketsTest, AcceleratorActionsEmpty) {
   AcceleratorActions actions("test", 0);
 
+  json::Value serialized_value = toJSON(actions);
+  const json::Object *serialized = serialized_value.getAsObject();
+  ASSERT_NE(nullptr, serialized);
+  EXPECT_EQ(nullptr, serialized->get("stop_id"));
+  EXPECT_EQ(nullptr, serialized->get("wait_for_accelerator_process_to_stop"));
+  EXPECT_EQ(nullptr, serialized->get("resume_accelerator_process"));
+  EXPECT_EQ(nullptr, serialized->get("wait_for_accelerator_process_to_resume"));
+
   Expected<AcceleratorActions> deserialized = roundtripJSON(actions);
   ASSERT_THAT_EXPECTED(deserialized, Succeeded());
   EXPECT_EQ("test", deserialized->plugin_name);
   EXPECT_TRUE(deserialized->breakpoints.empty());
+  EXPECT_FALSE(deserialized->stop_id);
+  EXPECT_FALSE(deserialized->wait_for_accelerator_process_to_stop);
+  EXPECT_FALSE(deserialized->resume_accelerator_process);
+  EXPECT_FALSE(deserialized->wait_for_accelerator_process_to_resume);
 }
 
 TEST(AcceleratorGDBRemotePacketsTest, LLDBSettings) {



More information about the lldb-commits mailing list