Recommitting r180831 with trivial fix - remember to return errors if you compute.


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@180898 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 9351b93..6657c2c 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -52,6 +52,7 @@
     m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
     m_supports_memory_region_info  (eLazyBoolCalculate),
     m_supports_watchpoint_support_info  (eLazyBoolCalculate),
+    m_supports_detach_stay_stopped (eLazyBoolCalculate),
     m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
     m_attach_or_wait_reply(eLazyBoolCalculate),
     m_prepare_for_reg_writing_reply (eLazyBoolCalculate),
@@ -1396,10 +1397,48 @@
     return false;
 }
 
-bool
-GDBRemoteCommunicationClient::Detach ()
+Error
+GDBRemoteCommunicationClient::Detach (bool keep_stopped)
 {
-    return SendPacket ("D", 1) > 0;
+    Error error;
+    
+    if (keep_stopped)
+    {
+        if (m_supports_detach_stay_stopped == eLazyBoolCalculate)
+        {
+            char packet[64];
+            const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
+            assert (packet_len < sizeof(packet));
+            StringExtractorGDBRemote response;
+            if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+            {
+                m_supports_detach_stay_stopped = eLazyBoolYes;        
+            }
+            else
+            {
+                m_supports_detach_stay_stopped = eLazyBoolNo;
+            }
+        }
+
+        if (m_supports_detach_stay_stopped == eLazyBoolNo)
+        {
+            error.SetErrorString("Stays stopped not supported by this target.");
+            return error;
+        }
+        else
+        {
+            size_t num_sent = SendPacket ("D1", 2);
+            if (num_sent == 0)
+                error.SetErrorString ("Sending extended disconnect packet failed.");
+        }
+    }
+    else
+    {
+        size_t num_sent = SendPacket ("D", 1);
+        if (num_sent == 0)
+            error.SetErrorString ("Sending disconnect packet failed.");
+    }
+    return error;
 }
 
 Error
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 25b697d..4075eeb 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -199,8 +199,8 @@
     bool
     DeallocateMemory (lldb::addr_t addr);
 
-    bool
-    Detach ();
+    lldb_private::Error
+    Detach (bool keep_stopped);
 
     lldb_private::Error
     GetMemoryRegionInfo (lldb::addr_t addr, 
@@ -381,6 +381,7 @@
     lldb_private::LazyBool m_supports_alloc_dealloc_memory;
     lldb_private::LazyBool m_supports_memory_region_info;
     lldb_private::LazyBool m_supports_watchpoint_support_info;
+    lldb_private::LazyBool m_supports_detach_stay_stopped;
     lldb_private::LazyBool m_watchpoints_trigger_after_instruction;
     lldb_private::LazyBool m_attach_or_wait_reply;
     lldb_private::LazyBool m_prepare_for_reg_writing_reply;
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 1b4627a..06e15ab 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1696,25 +1696,29 @@
 }
 
 Error
-ProcessGDBRemote::DoDetach()
+ProcessGDBRemote::DoDetach(bool keep_stopped)
 {
     Error error;
     Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
     if (log)
-        log->Printf ("ProcessGDBRemote::DoDetach()");
-
+        log->Printf ("ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
+ 
     DisableAllBreakpointSites ();
 
     m_thread_list.DiscardThreadPlans();
 
-    bool success = m_gdb_comm.Detach ();
+    error = m_gdb_comm.Detach (keep_stopped);
     if (log)
     {
-        if (success)
+        if (error.Success())
             log->PutCString ("ProcessGDBRemote::DoDetach() detach packet sent successfully");
         else
-            log->PutCString ("ProcessGDBRemote::DoDetach() detach packet send failed");
+            log->Printf ("ProcessGDBRemote::DoDetach() detach packet send failed: %s", error.AsCString() ? error.AsCString() : "<unknown error>");
     }
+    
+    if (!error.Success())
+        return error;
+
     // Sleep for one second to let the process get all detached...
     StopAsyncThread ();
 
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index dc4ec56..5cbb13f 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -141,7 +141,7 @@
     DoHalt (bool &caused_stop);
 
     virtual lldb_private::Error
-    DoDetach ();
+    DoDetach (bool keep_stopped);
     
     virtual bool
     DetachRequiresHalt() { return true; }