summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
diff options
context:
space:
mode:
authorEwan Crawford <ewan@codeplay.com>2015-05-13 09:18:18 +0000
committerEwan Crawford <ewan@codeplay.com>2015-05-13 09:18:18 +0000
commit78baa19781920bf2b1332ffd1a88884bd2ba42be (patch)
treed3052f7dd08a7de25cb85783365d8c774d979c9b /lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
parentacf20fa233d680e6855e67b65c66c59a7d9ddf22 (diff)
downloadbcm5719-llvm-78baa19781920bf2b1332ffd1a88884bd2ba42be.tar.gz
bcm5719-llvm-78baa19781920bf2b1332ffd1a88884bd2ba42be.zip
Remote Non-Stop Support
Summary: This patch is the beginnings of support for Non-stop mode in the remote protocol. Letting a user examine stopped threads, while other threads execute freely. Non-stop mode is enabled using the setting target.non-stop-mode, which sends a QNonStop packet when establishing the remote connection. Changes are also made to treat the '?' stop reply packet differently in non-stop mode, according to spec https://sourceware.org/gdb/current/onlinedocs/gdb/Remote-Non_002dStop.html#Remote-Non_002dStop. A setting for querying the remote for default thread on setup is also included. Handling of '%' async notification packets will be added next. Reviewers: clayborg Subscribers: lldb-commits, ADodds, ted, deepak2427 Differential Revision: http://reviews.llvm.org/D9656 llvm-svn: 237239
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp62
1 files changed, 56 insertions, 6 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 814b1ad1191..01c48d75822 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -391,7 +391,8 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :
m_waiting_for_attach (false),
m_destroy_tried_resuming (false),
m_command_sp (),
- m_breakpoint_pc_offset (0)
+ m_breakpoint_pc_offset (0),
+ m_initial_tid (LLDB_INVALID_THREAD_ID)
{
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
@@ -769,8 +770,13 @@ ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url)
// We have a valid process
SetID (pid);
GetThreadList();
- if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, m_last_stop_packet, false) == GDBRemoteCommunication::PacketResult::Success)
+ if (m_gdb_comm.GetStopReply(m_last_stop_packet))
{
+
+ // '?' Packets must be handled differently in non-stop mode
+ if (GetTarget().GetNonStopModeEnabled())
+ HandleStopReplySequence();
+
if (!m_target.GetArchitecture().IsValid())
{
if (m_gdb_comm.GetProcessArchitecture().IsValid())
@@ -1052,8 +1058,13 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
return error;
}
- if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, m_last_stop_packet, false) == GDBRemoteCommunication::PacketResult::Success)
+ if (m_gdb_comm.GetStopReply(m_last_stop_packet))
{
+
+ // '?' Packets must be handled differently in non-stop mode
+ if (GetTarget().GetNonStopModeEnabled())
+ HandleStopReplySequence();
+
const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture();
if (process_arch.IsValid())
@@ -1153,12 +1164,22 @@ ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
error.SetErrorString("not connected to remote gdb server");
return error;
}
+
+ // Send $QNonStop:1 packet on startup if required
+ if (GetTarget().GetNonStopModeEnabled())
+ m_gdb_comm.SetNonStopMode(true);
+
m_gdb_comm.GetThreadSuffixSupported ();
m_gdb_comm.GetListThreadsInStopReplySupported ();
m_gdb_comm.GetHostInfo ();
m_gdb_comm.GetVContSupported ('c');
m_gdb_comm.GetVAttachOrWaitSupported();
-
+
+ // Ask the remote server for the default thread id
+ if (GetTarget().GetNonStopModeEnabled())
+ m_gdb_comm.GetDefaultThreadId(m_initial_tid);
+
+
size_t num_cmds = GetExtraStartupCommands().GetArgumentCount();
for (size_t idx = 0; idx < num_cmds; idx++)
{
@@ -1430,11 +1451,12 @@ ProcessGDBRemote::DoResume ()
bool continue_packet_error = false;
if (m_gdb_comm.HasAnyVContSupport ())
{
- if (m_continue_c_tids.size() == num_threads ||
+ if (!GetTarget().GetNonStopModeEnabled() &&
+ (m_continue_c_tids.size() == num_threads ||
(m_continue_c_tids.empty() &&
m_continue_C_tids.empty() &&
m_continue_s_tids.empty() &&
- m_continue_S_tids.empty()))
+ m_continue_S_tids.empty())))
{
// All threads are continuing, just send a "c" packet
continue_packet.PutCString ("c");
@@ -1662,6 +1684,27 @@ ProcessGDBRemote::DoResume ()
}
void
+ProcessGDBRemote::HandleStopReplySequence ()
+{
+ while(true)
+ {
+ // Send vStopped
+ StringExtractorGDBRemote response;
+ m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response, false);
+
+ // OK represents end of signal list
+ if (response.IsOKResponse())
+ break;
+
+ // If not OK or a normal packet we have a problem
+ if (!response.IsNormalResponse())
+ break;
+
+ SetLastStopPacket(response);
+ }
+}
+
+void
ProcessGDBRemote::ClearThreadIDList ()
{
Mutex::Locker locker(m_thread_list_real.GetMutex());
@@ -2095,6 +2138,13 @@ ProcessGDBRemote::RefreshStateAfterStop ()
UpdateThreadIDList();
}
+ // If we have queried for a default thread id
+ if (m_initial_tid != LLDB_INVALID_THREAD_ID)
+ {
+ m_thread_list.SetSelectedThreadByID(m_initial_tid);
+ m_initial_tid = LLDB_INVALID_THREAD_ID;
+ }
+
// Let all threads recover from stopping and do any clean up based
// on the previous thread state (if any).
m_thread_list_real.RefreshStateAfterStop();
OpenPOWER on IntegriCloud