[Lldb-commits] [lldb] [RFC][lldb-dap] Always stop on enrty for attaching (PR #134339)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Apr 3 22:04:40 PDT 2025
https://github.com/kusmour updated https://github.com/llvm/llvm-project/pull/134339
>From 18e4af1c5798b620e96a4447cb8cdab272775909 Mon Sep 17 00:00:00 2001
From: Wanyi Ye <wanyi at fb.com>
Date: Thu, 3 Apr 2025 21:02:04 -0400
Subject: [PATCH] [lldb-dap] Always stop on enrty for attaching
Recently upon debugging a program with thousands of threads, lldb-dap would hang at a `threads` request sent right after receiving the `configurationDone` response. Soon after it will end the debug session with "Process <pid> ex
ited with status = -1 (0xffffffff) lost connection".
This is because LLDB is still in the middle of resuming all the threads. And requesting threads will require stopp
ing the process. From the gdb-remote log it ended up getting `lldb::StateType::eStateInvalid` and just exit with s
tatus -1.
I don't think it's reasonable to allow getting threads from a running process. The alternative will be reject the
`threads` request if the process is not stopped.
---
lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py | 8 +++++++-
.../API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py | 3 +++
lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp | 8 +++++---
3 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py
index 9df44cc454d5d..85990776cce57 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attach.py
@@ -1,5 +1,5 @@
"""
-Test lldb-dap setBreakpoints request
+Test lldb-dap attach request
"""
@@ -35,6 +35,9 @@ def set_and_hit_breakpoint(self, continueToExit=True):
self.assertEqual(
len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
)
+ # Send a configurationDone request when process is ready to continue
+ self.dap_server.request_configurationDone()
+ self.assertTrue(self.verify_stop_exception_info("signal SIGSTOP"))
self.continue_to_breakpoints(breakpoint_ids)
if continueToExit:
self.continue_to_exit()
@@ -175,6 +178,9 @@ def test_commands(self):
functions = ["main"]
breakpoint_ids = self.set_function_breakpoints(functions)
self.assertEqual(len(breakpoint_ids), len(functions), "expect one breakpoint")
+ # Execute the configurationDone even if this is not real attaching
+ self.dap_server.request_configurationDone()
+ self.assertTrue(self.verify_stop_exception_info("signal SIGSTOP"))
self.continue_to_breakpoints(breakpoint_ids)
output = self.collect_console(timeout_secs=10, pattern=stopCommands[-1])
self.verify_commands("stopCommands", output, stopCommands)
diff --git a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
index 9024120c868fd..0256e3a49938e 100644
--- a/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
+++ b/lldb/test/API/tools/lldb-dap/attach/TestDAP_attachByPortNum.py
@@ -32,6 +32,9 @@ def set_and_hit_breakpoint(self, continueToExit=True):
self.assertEqual(
len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
)
+ # Send a configurationDone request when process is ready to continue
+ self.dap_server.request_configurationDone()
+ self.assertTrue(self.verify_stop_exception_info("signal SIGSTOP"))
self.continue_to_breakpoints(breakpoint_ids)
if continueToExit:
self.continue_to_exit()
diff --git a/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
index 5e622f3d3dcd4..aa7f3c0d57f9d 100644
--- a/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp
@@ -73,9 +73,11 @@ void AttachRequestHandler::operator()(const llvm::json::Object &request) const {
llvm::StringRef core_file = GetString(arguments, "coreFile").value_or("");
const uint64_t timeout_seconds =
GetInteger<uint64_t>(arguments, "timeout").value_or(30);
- dap.stop_at_entry = core_file.empty()
- ? GetBoolean(arguments, "stopOnEntry").value_or(false)
- : true;
+ // Clients like VS Code sends threads request right after receiving
+ // configurationDone reponse where the process might be resuming.
+ // Getting threads list on a running process is not supported by LLDB.
+ // Always stop the process after attaching.
+ dap.stop_at_entry = true;
dap.configuration.postRunCommands = GetStrings(arguments, "postRunCommands");
const llvm::StringRef debuggerRoot =
GetString(arguments, "debuggerRoot").value_or("");
More information about the lldb-commits
mailing list