augusto2112 updated this revision to Diff 313954.
augusto2112 added a comment.

Fix formatting issues


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 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 attach_with_vAttachWait(self):
+        # Add attach packets.
+        self.test_sequence.add_log_lines([
+            # Do the attach.
+            "read packet: $vAttachWait;{}#00".format(''.join(str(ord(c)) for c in "a.out")),
+        ], True)
+
+
+        # Start the inferior, start the debug monitor, nothing is attached yet.
+        procs = self.prep_debug_monitor_and_inferior(
+            inferior_args=["sleep:60"])
+        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))
+
+
+        self.test_sequence.add_log_lines([
+            # 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)
+
+    @debugserver_test
+    def test_attach_with_vAttach_debugserver(self):
+        self.build()
+        self.set_inferior_startup_attach_manually()
+        self.attach_with_vAttachWait()
+
+    @llgs_test
+    def test_attach_with_vAttach_llgs(self):
+        self.build()
+        self.set_inferior_startup_attach_manually()
+        self.attach_with_vAttachWait()
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
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to