[llvm-branch-commits] [lldb] 2afaf07 - Implement vAttachOrWait
Pavel Labath via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Jan 24 12:43:42 PST 2021
Author: Augusto Noronha
Date: 2021-01-24T21:30:09+01:00
New Revision: 2afaf072f5c1467767081571f2a3747b3ba91354
URL: https://github.com/llvm/llvm-project/commit/2afaf072f5c1467767081571f2a3747b3ba91354
DIFF: https://github.com/llvm/llvm-project/commit/2afaf072f5c1467767081571f2a3747b3ba91354.diff
LOG: Implement vAttachOrWait
Implements the required functions on gdb-remote so the '--include-existing' flag of process attach works correctly on Linux.
Reviewed By: labath, clayborg
Differential Revision: https://reviews.llvm.org/D94672
Added:
lldb/test/API/tools/lldb-server/TestGdbRemoteAttachOrWait.py
Modified:
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 2c8bcf477f50..62a09a2a432c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -162,6 +162,12 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_vAttachWait,
&GDBRemoteCommunicationServerLLGS::Handle_vAttachWait);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_qVAttachOrWaitSupported,
+ &GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vAttachOrWait,
+ &GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait);
RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_vCont,
&GDBRemoteCommunicationServerLLGS::Handle_vCont);
@@ -338,7 +344,7 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
}
Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess(
- llvm::StringRef process_name) {
+ llvm::StringRef process_name, bool include_existing) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
std::chrono::milliseconds polling_interval = std::chrono::milliseconds(1);
@@ -347,13 +353,17 @@ Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess(
ProcessInstanceInfoList exclusion_list;
ProcessInstanceInfoMatch match_info;
match_info.GetProcessInfo().GetExecutableFile().SetFile(
- process_name, llvm::sys::path::Style::posix);
- match_info.SetNameMatchType(NameMatch::EndsWith);
+ process_name, llvm::sys::path::Style::native);
+ match_info.SetNameMatchType(NameMatch::Equals);
- // Create the excluded process list before polling begins.
- Host::FindProcesses(match_info, exclusion_list);
- LLDB_LOG(log, "placed '{0}' processes in the exclusion list.",
- exclusion_list.size());
+ if (include_existing) {
+ LLDB_LOG(log, "including existing processes in search");
+ } else {
+ // Create the excluded process list before polling begins.
+ Host::FindProcesses(match_info, exclusion_list);
+ LLDB_LOG(log, "placed '{0}' processes in the exclusion list.",
+ exclusion_list.size());
+ }
LLDB_LOG(log, "waiting for '{0}' to appear", process_name);
@@ -3275,7 +3285,43 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttachWait(
LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name);
- Status error = AttachWaitProcess(process_name);
+ Status error = AttachWaitProcess(process_name, false);
+ if (error.Fail()) {
+ LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name,
+ error);
+ return SendErrorResponse(error);
+ }
+
+ // Notify we attached by sending a stop packet.
+ return SendStopReasonForState(m_debugged_process_up->GetState());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qVAttachOrWaitSupported(
+ StringExtractorGDBRemote &packet) {
+ return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Consume the ';' after the identifier.
+ packet.SetFilePos(strlen("vAttachOrWait"));
+
+ if (!packet.GetBytesLeft() || packet.GetChar() != ';')
+ return SendIllFormedResponse(packet, "vAttachOrWait missing expected ';'");
+
+ // Allocate the buffer for the process name from vAttachWait.
+ std::string process_name;
+ if (!packet.GetHexByteString(process_name))
+ return SendIllFormedResponse(packet,
+ "vAttachOrWait failed to parse process name");
+
+ LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name);
+
+ Status error = AttachWaitProcess(process_name, true);
if (error.Fail()) {
LLDB_LOG(log, "failed to attach to process named '{0}': {1}", process_name,
error);
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index cdeba95b46ee..c51139924559 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -68,7 +68,7 @@ class GDBRemoteCommunicationServerLLGS
/// \return
/// An Status object indicating the success or failure of the
/// attach operation.
- Status AttachWaitProcess(llvm::StringRef process_name);
+ Status AttachWaitProcess(llvm::StringRef process_name, bool include_existing);
// NativeProcessProtocol::NativeDelegate overrides
void InitializeDelegate(NativeProcessProtocol *process) override;
@@ -183,6 +183,10 @@ class GDBRemoteCommunicationServerLLGS
PacketResult Handle_vAttachWait(StringExtractorGDBRemote &packet);
+ PacketResult Handle_qVAttachOrWaitSupported(StringExtractorGDBRemote &packet);
+
+ PacketResult Handle_vAttachOrWait(StringExtractorGDBRemote &packet);
+
PacketResult Handle_D(StringExtractorGDBRemote &packet);
PacketResult Handle_qThreadStopInfo(StringExtractorGDBRemote &packet);
diff --git a/lldb/test/API/tools/lldb-server/TestGdbRemoteAttachOrWait.py b/lldb/test/API/tools/lldb-server/TestGdbRemoteAttachOrWait.py
new file mode 100644
index 000000000000..c91e94b7b30d
--- /dev/null
+++ b/lldb/test/API/tools/lldb-server/TestGdbRemoteAttachOrWait.py
@@ -0,0 +1,111 @@
+
+import os
+from time import sleep
+
+import gdbremote_testcase
+import lldbgdbserverutils
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestGdbRemoteAttachOrWait(gdbremote_testcase.GdbRemoteTestCaseBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_launch_before_attach_with_vAttachOrWait(self):
+ exe = '%s_%d' % (self.testMethodName, os.getpid())
+ self.build(dictionary={'EXE': exe})
+ self.set_inferior_startup_attach_manually()
+
+ # Start the inferior, start the debug monitor, nothing is attached yet.
+ procs = self.prep_debug_monitor_and_inferior(
+ inferior_args=["sleep:60"],
+ inferior_exe_path=self.getBuildArtifact(exe))
+ self.assertIsNotNone(procs)
+
+ # Make sure the target process has been launched.
+ inferior = procs.get("inferior")
+ self.assertIsNotNone(inferior)
+ self.assertTrue(inferior.pid > 0)
+ self.assertTrue(
+ lldbgdbserverutils.process_is_running(
+ inferior.pid, True))
+
+ # Add attach packets.
+ self.test_sequence.add_log_lines([
+ # Do the attach.
+ "read packet: $vAttachOrWait;{}#00".format(lldbgdbserverutils.gdbremote_hex_encode_string(exe)),
+ # Expect a stop notification from the attach.
+ {"direction": "send",
+ "regex": r"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$",
+ "capture": {1: "stop_signal_hex"}},
+ ], True)
+ self.add_process_info_collection_packets()
+
+ # Run the stream
+ context = self.expect_gdbremote_sequence()
+ self.assertIsNotNone(context)
+
+ # Gather process info response
+ process_info = self.parse_process_info_response(context)
+ self.assertIsNotNone(process_info)
+
+ # Ensure the process id matches what we expected.
+ pid_text = process_info.get('pid', None)
+ self.assertIsNotNone(pid_text)
+ reported_pid = int(pid_text, base=16)
+ self.assertEqual(reported_pid, inferior.pid)
+
+ def test_launch_after_attach_with_vAttachOrWait(self):
+ exe = '%s_%d' % (self.testMethodName, os.getpid())
+ self.build(dictionary={'EXE': exe})
+ self.set_inferior_startup_attach_manually()
+
+ server = self.connect_to_debug_monitor()
+ self.assertIsNotNone(server)
+
+ self.add_no_ack_remote_stream()
+ self.test_sequence.add_log_lines([
+ # Do the attach.
+ "read packet: $vAttachOrWait;{}#00".format(lldbgdbserverutils.gdbremote_hex_encode_string(exe)),
+ ], True)
+ # Run the stream until attachWait.
+ context = self.expect_gdbremote_sequence()
+ self.assertIsNotNone(context)
+
+ # Sleep so we're sure that the inferior is launched after we ask for the attach.
+ sleep(1)
+
+ # Launch the inferior.
+ inferior = self.launch_process_for_attach(
+ inferior_args=["sleep:60"],
+ exe_path=self.getBuildArtifact(exe))
+ self.assertIsNotNone(inferior)
+ self.assertTrue(inferior.pid > 0)
+ self.assertTrue(
+ lldbgdbserverutils.process_is_running(
+ inferior.pid, True))
+
+ # Make sure the attach succeeded.
+ self.test_sequence.add_log_lines([
+ {"direction": "send",
+ "regex": r"^\$T([0-9a-fA-F]{2})[^#]*#[0-9a-fA-F]{2}$",
+ "capture": {1: "stop_signal_hex"}},
+ ], True)
+ self.add_process_info_collection_packets()
+
+
+ # Run the stream sending the response..
+ context = self.expect_gdbremote_sequence()
+ self.assertIsNotNone(context)
+
+ # Gather process info response.
+ process_info = self.parse_process_info_response(context)
+ self.assertIsNotNone(process_info)
+
+ # Ensure the process id matches what we expected.
+ pid_text = process_info.get('pid', None)
+ self.assertIsNotNone(pid_text)
+ reported_pid = int(pid_text, base=16)
+ self.assertEqual(reported_pid, inferior.pid)
More information about the llvm-branch-commits
mailing list