diff options
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
4 files changed, 56 insertions, 12 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 9351b93761b..6657c2ca27b 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -52,6 +52,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) : 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 @@ GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr) 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/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 25b697de8ef..4075eebddec 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -199,8 +199,8 @@ public: 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 @@ protected: 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/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 35e455d5f24..aa27ae8257e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1703,25 +1703,29 @@ ProcessGDBRemote::DoHalt (bool &caused_stop) } 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/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index dc4ec561b03..5cbb13f4914 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -141,7 +141,7 @@ public: DoHalt (bool &caused_stop); virtual lldb_private::Error - DoDetach (); + DoDetach (bool keep_stopped); virtual bool DetachRequiresHalt() { return true; } |