Skip to content

Conversation

@ashgti
Copy link
Contributor

@ashgti ashgti commented May 7, 2025

This adds types for the 'continue' request and updates the existing handler to the new base class.

This adds types for the 'continue' request and updates the existing handler to the new base class.
@llvmbot
Copy link
Member

llvmbot commented May 7, 2025

@llvm/pr-subscribers-lldb

Author: John Harrison (ashgti)

Changes

This adds types for the 'continue' request and updates the existing handler to the new base class.


Full diff: https://github.com/llvm/llvm-project/pull/138987.diff

4 Files Affected:

  • (modified) lldb/tools/lldb-dap/Handler/ContinueRequestHandler.cpp (+33-66)
  • (modified) lldb/tools/lldb-dap/Handler/RequestHandler.h (+6-3)
  • (modified) lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp (+12)
  • (modified) lldb/tools/lldb-dap/Protocol/ProtocolRequests.h (+25-3)
diff --git a/lldb/tools/lldb-dap/Handler/ContinueRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/ContinueRequestHandler.cpp
index 214e3c59c594c..ca4c9141eca38 100644
--- a/lldb/tools/lldb-dap/Handler/ContinueRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/ContinueRequestHandler.cpp
@@ -7,74 +7,41 @@
 //===----------------------------------------------------------------------===//
 
 #include "DAP.h"
-#include "JSONUtils.h"
-#include "RequestHandler.h"
+#include "Handler/RequestHandler.h"
+#include "LLDBUtils.h"
+#include "Protocol/ProtocolRequests.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBProcess.h"
+#include "llvm/Support/Error.h"
+
+using namespace llvm;
+using namespace lldb;
+using namespace lldb_dap::protocol;
 
 namespace lldb_dap {
 
-// "ContinueRequest": {
-//   "allOf": [ { "$ref": "#/definitions/Request" }, {
-//     "type": "object",
-//     "description": "Continue request; value of command field is 'continue'.
-//                     The request starts the debuggee to run again.",
-//     "properties": {
-//       "command": {
-//         "type": "string",
-//         "enum": [ "continue" ]
-//       },
-//       "arguments": {
-//         "$ref": "#/definitions/ContinueArguments"
-//       }
-//     },
-//     "required": [ "command", "arguments"  ]
-//   }]
-// },
-// "ContinueArguments": {
-//   "type": "object",
-//   "description": "Arguments for 'continue' request.",
-//   "properties": {
-//     "threadId": {
-//       "type": "integer",
-//       "description": "Continue execution for the specified thread (if
-//                       possible). If the backend cannot continue on a single
-//                       thread but will continue on all threads, it should
-//                       set the allThreadsContinued attribute in the response
-//                       to true."
-//     }
-//   },
-//   "required": [ "threadId" ]
-// },
-// "ContinueResponse": {
-//   "allOf": [ { "$ref": "#/definitions/Response" }, {
-//     "type": "object",
-//     "description": "Response to 'continue' request.",
-//     "properties": {
-//       "body": {
-//         "type": "object",
-//         "properties": {
-//           "allThreadsContinued": {
-//             "type": "boolean",
-//             "description": "If true, the continue request has ignored the
-//                             specified thread and continued all threads
-//                             instead. If this attribute is missing a value
-//                             of 'true' is assumed for backward
-//                             compatibility."
-//           }
-//         }
-//       }
-//     },
-//     "required": [ "body" ]
-//   }]
-// }
-void ContinueRequestHandler::operator()(
-    const llvm::json::Object &request) const {
-  llvm::json::Object response;
-  FillResponse(request, response);
-  lldb::SBProcess process = dap.target.GetProcess();
-  lldb::SBError error = process.Continue();
-  llvm::json::Object body;
-  body.try_emplace("allThreadsContinued", true);
-  response.try_emplace("body", std::move(body));
-  dap.SendJSON(llvm::json::Value(std::move(response)));
+/// The request resumes execution of all threads. If the debug adapter supports
+/// single thread execution (see capability
+/// `supportsSingleThreadExecutionRequests`), setting the `singleThread`
+/// argument to true resumes only the specified thread. If not all threads were
+/// resumed, the `allThreadsContinued` attribute of the response should be set
+/// to false.
+Expected<ContinueResponseBody>
+ContinueRequestHandler::Run(const ContinueArguments &args) const {
+  SBProcess process = dap.target.GetProcess();
+  SBError error;
+
+  if (args.singleThread)
+    dap.GetLLDBThread(args.threadId).Resume(error);
+  else
+    error = process.Continue();
+
+  if (error.Fail())
+    return ToError(error);
+
+  ContinueResponseBody body;
+  body.allThreadsContinued = args.singleThread;
+  return body;
 }
+
 } // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h b/lldb/tools/lldb-dap/Handler/RequestHandler.h
index 37cc902e1c98e..c8f795e3dd33e 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.h
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.h
@@ -224,11 +224,14 @@ class CompletionsRequestHandler : public LegacyRequestHandler {
   void operator()(const llvm::json::Object &request) const override;
 };
 
-class ContinueRequestHandler : public LegacyRequestHandler {
+class ContinueRequestHandler
+    : public RequestHandler<protocol::ContinueArguments,
+                            llvm::Expected<protocol::ContinueResponseBody>> {
 public:
-  using LegacyRequestHandler::LegacyRequestHandler;
+  using RequestHandler::RequestHandler;
   static llvm::StringLiteral GetCommand() { return "continue"; }
-  void operator()(const llvm::json::Object &request) const override;
+  llvm::Expected<protocol::ContinueResponseBody>
+  Run(const protocol::ContinueArguments &args) const override;
 };
 
 class ConfigurationDoneRequestHandler : public LegacyRequestHandler {
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
index d9ffc0c04e134..950e8d17e3489 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
@@ -261,6 +261,18 @@ bool fromJSON(const json::Value &Params, LaunchRequestArguments &LRA,
          parseEnv(Params, LRA.env, P) && parseTimeout(Params, LRA.timeout, P);
 }
 
+bool fromJSON(const llvm::json::Value &Params, ContinueArguments &CA,
+              llvm::json::Path P) {
+  json::ObjectMapper O(Params, P);
+  return O && O.map("threadId", CA.threadId) &&
+         O.mapOptional("singleThread", CA.singleThread);
+}
+
+llvm::json::Value toJSON(const ContinueResponseBody &CRB) {
+  json::Object Body{{"allThreadsContinued", CRB.allThreadsContinued}};
+  return std::move(Body);
+}
+
 bool fromJSON(const llvm::json::Value &Params, SetVariableArguments &SVA,
               llvm::json::Path P) {
   json::ObjectMapper O(Params, P);
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h
index 110e90837c0cd..18222d61f9a14 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h
@@ -294,6 +294,28 @@ bool fromJSON(const llvm::json::Value &, LaunchRequestArguments &,
 /// field is required.
 using LaunchResponseBody = VoidResponse;
 
+/// Arguments for `continue` request.
+struct ContinueArguments {
+  /// Specifies the active thread. If the debug adapter supports single thread
+  /// execution (see `supportsSingleThreadExecutionRequests`) and the argument
+  /// `singleThread` is true, only the thread with this ID is resumed.
+  lldb::tid_t threadId = LLDB_INVALID_THREAD_ID;
+
+  /// If this flag is true, execution is resumed only for the thread with given
+  /// `threadId`.
+  bool singleThread = false;
+};
+bool fromJSON(const llvm::json::Value &, ContinueArguments &, llvm::json::Path);
+
+/// Response to `continue` request.
+struct ContinueResponseBody {
+  // If omitted or set to `true`, this response signals to the client that all
+  // threads have been resumed. The value `false` indicates that not all threads
+  // were resumed.
+  bool allThreadsContinued = true;
+};
+llvm::json::Value toJSON(const ContinueResponseBody &);
+
 /// Arguments for `setVariable` request.
 struct SetVariableArguments {
   /// The reference of the variable container. The `variablesReference` must
@@ -390,7 +412,7 @@ llvm::json::Value toJSON(const SourceResponseBody &);
 struct NextArguments {
   /// Specifies the thread for which to resume execution for one step (of the
   /// given granularity).
-  uint64_t threadId = LLDB_INVALID_THREAD_ID;
+  lldb::tid_t threadId = LLDB_INVALID_THREAD_ID;
 
   /// If this flag is true, all other suspended threads are not resumed.
   bool singleThread = false;
@@ -409,7 +431,7 @@ using NextResponse = VoidResponse;
 struct StepInArguments {
   /// Specifies the thread for which to resume execution for one step-into (of
   /// the given granularity).
-  uint64_t threadId = LLDB_INVALID_THREAD_ID;
+  lldb::tid_t threadId = LLDB_INVALID_THREAD_ID;
 
   /// If this flag is true, all other suspended threads are not resumed.
   bool singleThread = false;
@@ -431,7 +453,7 @@ using StepInResponse = VoidResponse;
 struct StepOutArguments {
   /// Specifies the thread for which to resume execution for one step-out (of
   /// the given granularity).
-  uint64_t threadId = LLDB_INVALID_THREAD_ID;
+  lldb::tid_t threadId = LLDB_INVALID_THREAD_ID;
 
   /// If this flag is true, all other suspended threads are not resumed.
   std::optional<bool> singleThread;

@ashgti ashgti requested review from da-viper and eronnen May 7, 2025 23:22
Copy link
Member

@JDevlieghere JDevlieghere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very straightforward. LGTM.

@ashgti ashgti merged commit 155bf37 into llvm:main May 8, 2025
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants