augusto2112 created this revision.
augusto2112 added reviewers: labath, clayborg, jingham, aprantl.
augusto2112 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Implements the required functions on gdb-remote so the '--include-existing' 
flag of process attach works correctly on Linux.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D94672

Files:
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h

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
@@ -68,7 +68,7 @@
   /// \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 @@
 
   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);
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
@@ -162,6 +162,12 @@
   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::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,31 +353,43 @@
   ProcessInstanceInfoList exclusion_list;
   ProcessInstanceInfoMatch match_info;
   match_info.GetProcessInfo().GetExecutableFile().SetFile(
-      process_name, llvm::sys::path::Style::posix);
+      process_name, llvm::sys::path::Style::native);
   match_info.SetNameMatchType(NameMatch::EndsWith);
 
-  // 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) {
+    // 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());
+  } else {
+    LLDB_LOG(log, "including existing processes in search");
+  }
 
   LLDB_LOG(log, "waiting for '{0}' to appear", process_name);
 
-  auto is_in_exclusion_list =
-      [&exclusion_list](const ProcessInstanceInfo &info) {
-        for (auto &excluded : exclusion_list) {
-          if (excluded.GetProcessID() == info.GetProcessID())
-            return true;
-        }
-        return false;
-      };
+  StreamString name_with_slash_stream;
+  name_with_slash_stream.Format("/{0}", process_name);
+  auto name_with_slash = name_with_slash_stream.GetString();
+
+  // Exclude a process if it's in the exclusion list, OR if the process info's
+  // name doesn't exactly match the desired name, nor ends with a slash followed
+  // by the desired name.
+  auto should_exclude_process = [&exclusion_list, &process_name,
+                                 &name_with_slash](
+                                    const ProcessInstanceInfo &info) {
+    for (auto &excluded : exclusion_list) {
+      if (excluded.GetProcessID() == info.GetProcessID())
+        return true;
+    }
+    auto info_name = info.GetNameAsStringRef();
+    return info_name != process_name && !info_name.endswith(name_with_slash);
+  };
 
   ProcessInstanceInfoList loop_process_list;
   while (true) {
     loop_process_list.clear();
     if (Host::FindProcesses(match_info, loop_process_list)) {
-      // Remove all the elements that are in the exclusion list.
-      llvm::erase_if(loop_process_list, is_in_exclusion_list);
+      llvm::erase_if(loop_process_list, should_exclude_process);
 
       // One match! We found the desired process.
       if (loop_process_list.size() == 1) {
@@ -3275,7 +3293,43 @@
 
   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);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to