summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp35
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp62
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h4
5 files changed, 104 insertions, 7 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index fbd2047b352..2700ffcb7aa 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -424,6 +424,7 @@ GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, Stri
content_length = total_length = 1; // The command is one byte long...
break;
+ case '%': // Async notify packet
case '$':
// Look for a standard gdb packet?
{
@@ -466,6 +467,7 @@ GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, Stri
case '+':
case '-':
case '\x03':
+ case '%':
case '$':
done = true;
break;
@@ -586,7 +588,7 @@ GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, Stri
}
}
- if (m_bytes[0] == '$')
+ if (m_bytes[0] == '$' || m_bytes[0] == '%')
{
assert (checksum_idx < m_bytes.size());
if (::isxdigit (m_bytes[checksum_idx+0]) ||
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 07c51dc5c02..ca74e55b439 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1621,6 +1621,22 @@ GDBRemoteCommunicationClient::GetGDBServerProgramVersion()
}
bool
+GDBRemoteCommunicationClient::GetDefaultThreadId (lldb::tid_t &tid)
+{
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qC",response,false) != PacketResult::Success)
+ return false;
+
+ if (!response.IsNormalResponse())
+ return false;
+
+ if (response.GetChar() == 'Q' && response.GetChar() == 'C')
+ tid = response.GetHexMaxU32(true, -1);
+
+ return true;
+}
+
+bool
GDBRemoteCommunicationClient::GetHostInfo (bool force)
{
Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS));
@@ -2759,6 +2775,25 @@ GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
return false;
}
+bool
+GDBRemoteCommunicationClient::SetNonStopMode (const bool enable)
+{
+ // Form non-stop packet request
+ char packet[32];
+ const int packet_len = ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
+ assert(packet_len < (int)sizeof(packet));
+
+ StringExtractorGDBRemote response;
+ // Send to target
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
+ if (response.IsOKResponse())
+ return true;
+
+ // Failed or not supported
+ return false;
+
+}
+
void
GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
{
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 10072730e74..99b29a92423 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -318,6 +318,9 @@ public:
bool
GetHostInfo (bool force = false);
+
+ bool
+ GetDefaultThreadId (lldb::tid_t &tid);
bool
GetOSVersion (uint32_t &major,
@@ -393,6 +396,9 @@ public:
lldb::addr_t addr, // Address of breakpoint or watchpoint
uint32_t length); // Byte Size of breakpoint or watchpoint
+ bool
+ SetNonStopMode (const bool enable);
+
void
TestPacketSpeed (const uint32_t num_packets);
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();
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index a199bf0a031..e9d117c12db 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -358,6 +358,7 @@ protected:
bool m_destroy_tried_resuming;
lldb::CommandObjectSP m_command_sp;
int64_t m_breakpoint_pc_offset;
+ lldb::tid_t m_initial_tid; // The inital thread ID, given by stub on attach
bool
StartAsyncThread ();
@@ -379,6 +380,9 @@ protected:
SetThreadStopInfo (StringExtractor& stop_packet);
void
+ HandleStopReplySequence ();
+
+ void
ClearThreadIDList ();
bool
OpenPOWER on IntegriCloud