augusto2112 updated this revision to Diff 314231.
augusto2112 added a comment.
Re-include deleted files.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D93895/new/
https://reviews.llvm.org/D93895
Files:
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
lldb/test/API/tools/lldb-server/TestGdbRemoteAttachWait.py
Index: lldb/test/API/tools/lldb-server/TestGdbRemoteAttachWait.py
===================================================================
--- /dev/null
+++ lldb/test/API/tools/lldb-server/TestGdbRemoteAttachWait.py
@@ -0,0 +1,69 @@
+
+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 TestGdbRemoteAttachWait(gdbremote_testcase.GdbRemoteTestCaseBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_attach_with_vAttachWait(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: $vAttachWait;{}#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)
+
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -59,6 +59,17 @@
/// attach operation.
Status AttachToProcess(lldb::pid_t pid);
+ /// Wait to attach to a process with a given name.
+ ///
+ /// This method supports waiting for the next instance of a process
+ /// with a given name and attaching llgs to that via the configured
+ /// Platform.
+ ///
+ /// \return
+ /// An Status object indicating the success or failure of the
+ /// attach operation.
+ Status AttachWaitProcess(llvm::StringRef process_name);
+
// NativeProcessProtocol::NativeDelegate overrides
void InitializeDelegate(NativeProcessProtocol *process) override;
@@ -170,6 +181,8 @@
PacketResult Handle_vAttach(StringExtractorGDBRemote &packet);
+ PacketResult Handle_vAttachWait(StringExtractorGDBRemote &packet);
+
PacketResult Handle_D(StringExtractorGDBRemote &packet);
PacketResult Handle_qThreadStopInfo(StringExtractorGDBRemote &packet);
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -159,6 +159,9 @@
RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_vAttach,
&GDBRemoteCommunicationServerLLGS::Handle_vAttach);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_vAttachWait,
+ &GDBRemoteCommunicationServerLLGS::Handle_vAttachWait);
RegisterMemberFunctionHandler(
StringExtractorGDBRemote::eServerPacketType_vCont,
&GDBRemoteCommunicationServerLLGS::Handle_vCont);
@@ -334,6 +337,60 @@
return Status();
}
+Status GDBRemoteCommunicationServerLLGS::AttachWaitProcess(
+ llvm::StringRef process_name) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ // TODO: Make the polling interval configurable
+ std::chrono::milliseconds waitfor_interval = std::chrono::seconds(1);
+
+ // Create the matcher used to search the process list
+ ProcessInstanceInfoList exclusion_list;
+ ProcessInstanceInfoMatch match_info;
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ process_name, llvm::sys::path::Style::posix);
+ match_info.SetNameMatchType(NameMatch::EndsWith);
+
+ // Create the excluded process list before polling begins
+ Host::FindProcesses(match_info, exclusion_list);
+
+ if (log)
+ LLDB_LOG(log, "waiting for '{0}' to appear", process_name);
+
+ lldb::pid_t waitfor_pid = LLDB_INVALID_PROCESS_ID;
+ ProcessInstanceInfoList loop_process_list;
+
+ while (waitfor_pid == LLDB_INVALID_PROCESS_ID) {
+ loop_process_list.clear();
+ if (Host::FindProcesses(match_info, loop_process_list)) {
+ // The for loop is to checking for the first matching process that was
+ // not in the excluded process list.
+ for (size_t i = 0; i < loop_process_list.size(); i++) {
+ waitfor_pid = loop_process_list[i].GetProcessID();
+ for (size_t j = 0; j < exclusion_list.size(); j++) {
+ if (exclusion_list[j].GetProcessID() == waitfor_pid) {
+ waitfor_pid = LLDB_INVALID_PROCESS_ID;
+ }
+ }
+
+ // If waitfor_pid is not in our exclusion list then use it
+ if (waitfor_pid != LLDB_INVALID_PROCESS_ID) {
+ if (log)
+ LLDB_LOG(log, "found pid {1}", waitfor_pid);
+ break;
+ }
+ }
+ }
+ // If we have not found the new process sleep until next poll.
+ if (waitfor_pid == LLDB_INVALID_PROCESS_ID) {
+ if (log)
+ LLDB_LOG(log, "sleep {1} seconds", waitfor_interval);
+ std::this_thread::sleep_for(waitfor_interval);
+ }
+ }
+
+ return AttachToProcess(waitfor_pid);
+}
+
void GDBRemoteCommunicationServerLLGS::InitializeDelegate(
NativeProcessProtocol *process) {
assert(process && "process cannot be NULL");
@@ -3188,6 +3245,38 @@
return SendStopReasonForState(m_debugged_process_up->GetState());
}
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_vAttachWait(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Consume the ';' after vAttach.
+ packet.SetFilePos(strlen("vAttachWait"));
+ if (!packet.GetBytesLeft() || packet.GetChar() != ';')
+ return SendIllFormedResponse(packet, "vAttachWait missing expected ';'");
+
+ // Allocate the buffer for the process name from vAttachWait
+ std::string process_name;
+ if (!packet.GetHexByteString(process_name))
+ return SendIllFormedResponse(packet,
+ "vAttachWait failed to parse process name");
+
+ if (log)
+ LLDB_LOG(log, "attempting to attach to process named '{0}'", process_name);
+
+ Status error = AttachWaitProcess(process_name);
+
+ if (error.Fail()) {
+ if (log)
+ 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_D(StringExtractorGDBRemote &packet) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits