summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp45
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h5
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp16
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h2
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; }
OpenPOWER on IntegriCloud