diff options
Diffstat (limited to 'lldb/source/Plugins/Process')
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 |