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/GDBRemoteCommunication.cpp16
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h12
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp124
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h9
4 files changed, 131 insertions, 30 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 38b823f77aa..a779db25756 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -511,6 +511,18 @@ GDBRemoteCommunication::SendInterrupt
return false;
}
+bool
+GDBRemoteCommunication::WaitForNotRunning (const TimeValue *timeout_ptr)
+{
+ return m_public_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
+}
+
+bool
+GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
+{
+ return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
+}
+
size_t
GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
{
@@ -522,14 +534,14 @@ GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint3
}
size_t
-GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, TimeValue* timeout_time_ptr)
+GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
{
Mutex::Locker locker(m_sequence_mutex);
return WaitForPacketNoLock (response, timeout_time_ptr);
}
size_t
-GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, TimeValue* timeout_time_ptr)
+GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
{
bool checksum_error = false;
response.Clear ();
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index bcbaeb5ebd9..3ebabeb7085 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -81,7 +81,7 @@ public:
// wait indefinitely.
size_t
WaitForPacket (StringExtractorGDBRemote &response,
- lldb_private::TimeValue* timeout);
+ const lldb_private::TimeValue* timeout);
char
GetAck (uint32_t timeout_seconds);
@@ -222,7 +222,10 @@ public:
{
return m_public_is_running.GetValue();
}
-
+
+ bool
+ WaitForNotRunning (const lldb_private::TimeValue *timeout_ptr);
+
bool
GetHostInfo (uint32_t timeout_seconds);
@@ -256,7 +259,10 @@ protected:
size_t
WaitForPacketNoLock (StringExtractorGDBRemote &response,
- lldb_private::TimeValue* timeout_time_ptr);
+ const lldb_private::TimeValue* timeout_ptr);
+
+ bool
+ WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
//------------------------------------------------------------------
// Classes that inherit from GDBRemoteCommunication can see and modify these
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 5abe070f962..fe4e06820fc 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1157,7 +1157,13 @@ ProcessGDBRemote::DoHalt (bool &caused_stop)
}
Error
-ProcessGDBRemote::WillDetach ()
+ProcessGDBRemote::InterruptIfRunning
+(
+ bool discard_thread_plans,
+ bool catch_stop_event,
+ bool resume_private_state_thread,
+ EventSP &stop_event_sp
+)
{
Error error;
@@ -1166,30 +1172,54 @@ ProcessGDBRemote::WillDetach ()
bool timed_out = false;
bool sent_interrupt = false;
Mutex::Locker locker;
- PausePrivateStateThread();
- m_thread_list.DiscardThreadPlans();
- m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
- if (!m_gdb_comm.SendInterrupt (locker, 2, sent_interrupt, timed_out))
+
+ if (catch_stop_event)
+ PausePrivateStateThread();
+
+ if (discard_thread_plans)
+ m_thread_list.DiscardThreadPlans();
+
+ //m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ if (!m_gdb_comm.SendInterrupt (locker, 1, sent_interrupt, timed_out))
{
if (timed_out)
error.SetErrorString("timed out sending interrupt packet");
else
error.SetErrorString("unknown error sending interrupt packet");
- ResumePrivateStateThread();
+ if (catch_stop_event)
+ ResumePrivateStateThread();
+ return error;
}
- TimeValue timeout_time;
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithSeconds(2);
+
+
+ if (catch_stop_event)
+ {
+ TimeValue timeout_time;
+ timeout_time = TimeValue::Now();
+ timeout_time.OffsetWithSeconds(1);
+ StateType state = WaitForProcessStopPrivate (&timeout_time, stop_event_sp);
- EventSP event_sp;
- StateType state = WaitForStateChangedEventsPrivate (&timeout_time, event_sp);
- if (state != eStateStopped)
- error.SetErrorString("unable to stop target");
+ if (state == eStateInvalid)
+ error.SetErrorString("unable to verify target stopped");
+ }
+
+ if (catch_stop_event && resume_private_state_thread)
+ ResumePrivateStateThread();
}
return error;
}
Error
+ProcessGDBRemote::WillDetach ()
+{
+ bool discard_thread_plans = true;
+ bool catch_stop_event = true;
+ bool resume_private_state_thread = false; // DoDetach will resume the thread
+ EventSP event_sp;
+ return InterruptIfRunning (discard_thread_plans, catch_stop_event, resume_private_state_thread, event_sp);
+}
+
+Error
ProcessGDBRemote::DoDetach()
{
Error error;
@@ -1223,6 +1253,16 @@ ProcessGDBRemote::DoDetach()
}
Error
+ProcessGDBRemote::WillDestroy ()
+{
+ bool discard_thread_plans = true;
+ bool catch_stop_event = true;
+ bool resume_private_state_thread = true;
+ EventSP event_sp;
+ return InterruptIfRunning (discard_thread_plans, catch_stop_event, resume_private_state_thread, event_sp);
+}
+
+Error
ProcessGDBRemote::DoDestroy ()
{
Error error;
@@ -1233,10 +1273,40 @@ ProcessGDBRemote::DoDestroy ()
// Interrupt if our inferior is running...
if (m_gdb_comm.IsConnected())
{
- // Don't get a response when killing our
- m_gdb_comm.SendPacket ("k", 1);
+ m_continue_packet.Clear();
+ m_continue_packet.Printf("k");
+ Listener listener ("gdb-remote.kill-packet-sent");
+ if (listener.StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
+ {
+ EventSP event_sp;
+ TimeValue timeout;
+ timeout = TimeValue::Now();
+ timeout.OffsetWithSeconds (1);
+ m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (m_continue_packet.GetData(), m_continue_packet.GetSize()));
+
+ // Wait for the async thread to send the "k" packet
+ if (listener.WaitForEvent (&timeout, event_sp))
+ {
+ if (log)
+ log->Printf ("ProcessGDBRemote::DoDestroy() got confirmation the \"k\" packet was sent");
+ }
+ else
+ {
+ if (log)
+ log->Printf ("ProcessGDBRemote::DoDestroy() timed out waiting for \"k\" packet to be sent");
+ error.SetErrorString("Resume timed out.");
+ }
+
+ // Wait for the async thread to exit which will indicate we stopped.
+ // Hopefully the stop will be a process exited state since we are
+ // asking the process to go away.
+ if (!m_gdb_comm.WaitForNotRunning (&timeout))
+ {
+ if (log)
+ log->Printf ("ProcessGDBRemote::DoDestroy() timed out waiting for \"k\" stop reply packet");
+ }
+ }
}
-
StopAsyncThread ();
m_gdb_comm.StopReadThread();
KillDebugserverProcess ();
@@ -1851,14 +1921,14 @@ ProcessGDBRemote::StartDebugserverProcess
log->Printf("%s arguments:\n%s", debugserver_args.GetArgumentAtIndex(0), strm.GetData());
}
- error.SetError(::posix_spawnp (&m_debugserver_pid,
- debugserver_path,
- file_actions_err.Success() ? &file_actions : NULL,
- &attr,
- debugserver_args.GetArgumentVector(),
- (char * const*)inferior_envp),
- eErrorTypePOSIX);
-
+ error.SetError (::posix_spawnp (&m_debugserver_pid,
+ debugserver_path,
+ file_actions_err.Success() ? &file_actions : NULL,
+ &attr,
+ debugserver_args.GetArgumentVector(),
+ (char * const*)inferior_envp),
+ eErrorTypePOSIX);
+
::posix_spawnattr_destroy (&attr);
@@ -1907,7 +1977,11 @@ ProcessGDBRemote::MonitorDebugserverProcess
// debugserver that we are tracking...
ProcessGDBRemote *process = (ProcessGDBRemote *)callback_baton;
-
+
+ LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf ("ProcessGDBRemote::MonitorDebugserverProcess (baton=%p, pid=%i, signo=%i (0x%x), exit_status=%i)", callback_baton, debugserver_pid, signo, signo, exit_status);
+
if (process)
{
// Sleep for a half a second to make sure our inferior process has
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index ebb4cca23d4..d8a2cebbd33 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -149,6 +149,9 @@ public:
DoSignal (int signal);
virtual lldb_private::Error
+ WillDestroy ();
+
+ virtual lldb_private::Error
DoDestroy ();
virtual void
@@ -382,6 +385,12 @@ protected:
const char *bytes,
size_t bytes_len);
+ lldb_private::Error
+ InterruptIfRunning (bool discard_thread_plans,
+ bool catch_stop_event,
+ bool resume_private_state_thread,
+ lldb::EventSP &stop_event_sp);
+
private:
//------------------------------------------------------------------
// For ProcessGDBRemote only
OpenPOWER on IntegriCloud