Change ProcessGDBRemote last stop packet to a container.
In ProcessGDBRemote we currently have a single packet, m_last_stop_packet, used to set the thread stop info.
However in non-stop mode we can receive several stop reply packets in a sequence for different threads. As a result we need to use a container to hold them before they are processed.
This patch also changes the return type of CheckPacket() so we can detect async notification packets.
Reviewers: clayborg
Subscribers: labath, ted, deepak2427, lldb-commits
Differential Revision: http://reviews.llvm.org/D9853
llvm-svn: 238323
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 0399634..8f2efa2 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -374,7 +374,6 @@
m_flags (0),
m_gdb_comm (),
m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
- m_last_stop_packet (),
m_last_stop_packet_mutex (Mutex::eMutexTypeNormal),
m_register_info (),
m_async_broadcaster (NULL, "lldb.process.gdb-remote.async-broadcaster"),
@@ -769,8 +768,10 @@
// We have a valid process
SetID (pid);
GetThreadList();
- if (m_gdb_comm.GetStopReply(m_last_stop_packet))
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.GetStopReply(response))
{
+ SetLastStopPacket(response);
// '?' Packets must be handled differently in non-stop mode
if (GetTarget().GetNonStopModeEnabled())
@@ -788,7 +789,7 @@
}
}
- const StateType state = SetThreadStopInfo (m_last_stop_packet);
+ const StateType state = SetThreadStopInfo (response);
if (state == eStateStopped)
{
SetPrivateState (state);
@@ -1057,9 +1058,10 @@
return error;
}
- if (m_gdb_comm.GetStopReply(m_last_stop_packet))
+ StringExtractorGDBRemote response;
+ if (m_gdb_comm.GetStopReply(response))
{
-
+ SetLastStopPacket(response);
// '?' Packets must be handled differently in non-stop mode
if (GetTarget().GetNonStopModeEnabled())
HandleStopReplySequence();
@@ -1077,7 +1079,7 @@
m_target.MergeArchitecture(host_arch);
}
- SetPrivateState (SetThreadStopInfo (m_last_stop_packet));
+ SetPrivateState (SetThreadStopInfo (response));
if (!disable_stdio)
{
@@ -2123,7 +2125,25 @@
// Set the thread stop info. It might have a "threads" key whose value is
// a list of all thread IDs in the current process, so m_thread_ids might
// get set.
- SetThreadStopInfo (m_last_stop_packet);
+
+ // Scope for the lock
+ {
+ // Lock the thread stack while we access it
+ Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex);
+ // Get the number of stop packets on the stack
+ int nItems = m_stop_packet_stack.size();
+ // Iterate over them
+ for (int i = 0; i < nItems; i++)
+ {
+ // Get the thread stop info
+ StringExtractorGDBRemote stop_info = m_stop_packet_stack[i];
+ // Process thread stop info
+ SetThreadStopInfo(stop_info);
+ }
+ // Clear the thread stop stack
+ m_stop_packet_stack.clear();
+ }
+
// Check to see if SetThreadStopInfo() filled in m_thread_ids?
if (m_thread_ids.empty())
{
@@ -2395,7 +2415,6 @@
void
ProcessGDBRemote::SetLastStopPacket (const StringExtractorGDBRemote &response)
{
- Mutex::Locker locker (m_last_stop_packet_mutex);
const bool did_exec = response.GetStringRef().find(";reason:exec;") != std::string::npos;
if (did_exec)
{
@@ -2408,7 +2427,16 @@
BuildDynamicRegisterInfo (true);
m_gdb_comm.ResetDiscoverableSettings();
}
- m_last_stop_packet = response;
+
+ // Scope the lock
+ {
+ // Lock the thread stack while we access it
+ Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex);
+ // Add this stop packet to the stop packet stack
+ // This stack will get popped and examined when we switch to the
+ // Stopped state
+ m_stop_packet_stack.push_back(response);
+ }
}