Add "vAttachOrWait" to debugserver, so you can implement "attach to the process if it exists OR wait for it" without race conditions.  Use that in lldb.


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@160578 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 180c1f3..b4263d1 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -50,6 +50,7 @@
     m_supports_memory_region_info  (eLazyBoolCalculate),
     m_supports_watchpoint_support_info  (eLazyBoolCalculate),
     m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
+    m_attach_or_wait_reply(eLazyBoolCalculate),
     m_supports_qProcessInfoPID (true),
     m_supports_qfProcessInfo (true),
     m_supports_qUserName (true),
@@ -133,6 +134,26 @@
     }
 }
 
+bool
+GDBRemoteCommunicationClient::GetVAttachOrWaitSupported ()
+{
+    if (m_attach_or_wait_reply == eLazyBoolCalculate)
+    {
+        m_attach_or_wait_reply = eLazyBoolNo;
+        
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false))
+        {
+            if (response.IsOKResponse())
+                m_attach_or_wait_reply = eLazyBoolYes;
+        }
+    }
+    if (m_attach_or_wait_reply == eLazyBoolYes)
+        return true;
+    else
+        return false;
+}
+
 
 void
 GDBRemoteCommunicationClient::ResetDiscoverableSettings()
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index a283389..eee3aa5 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -221,6 +221,9 @@
     bool
     GetVContSupported (char flavor);
 
+    bool
+    GetVAttachOrWaitSupported ();
+    
     void
     ResetDiscoverableSettings();
 
@@ -365,7 +368,8 @@
     lldb_private::LazyBool m_supports_memory_region_info;
     lldb_private::LazyBool m_supports_watchpoint_support_info;
     lldb_private::LazyBool m_watchpoints_trigger_after_instruction;
-
+    lldb_private::LazyBool m_attach_or_wait_reply;
+    
     bool
         m_supports_qProcessInfoPID:1,
         m_supports_qfProcessInfo:1,
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 6e48482..dbb121e 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -742,6 +742,7 @@
     m_gdb_comm.GetListThreadsInStopReplySupported ();
     m_gdb_comm.GetHostInfo ();
     m_gdb_comm.GetVContSupported ('c');
+    m_gdb_comm.GetVAttachOrWaitSupported();
     
     size_t num_cmds = GetExtraStartupCommands().GetArgumentCount();
     for (size_t idx = 0; idx < num_cmds; idx++)
@@ -929,7 +930,19 @@
             StreamString packet;
             
             if (wait_for_launch)
-                packet.PutCString("vAttachWait");
+            {
+                if (!m_gdb_comm.GetVAttachOrWaitSupported())
+                {
+                    packet.PutCString ("vAttachWait");
+                }
+                else
+                {
+                    if (attach_info.GetIgnoreExisting())
+                        packet.PutCString("vAttachWait");
+                    else
+                        packet.PutCString ("vAttachOrWait");
+                }
+            }
             else
                 packet.PutCString("vAttachName");
             packet.PutChar(';');