diff options
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
4 files changed, 65 insertions, 14 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 5925812f7f3..1a7b27b40f9 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -34,6 +34,7 @@ using namespace lldb_private; GDBRemoteCommunication::GDBRemoteCommunication() : Communication("gdb-remote.packets"), m_send_acks (true), + m_thread_suffix_supported (false), m_rx_packet_listener ("gdbremote.rx_packet"), m_sequence_mutex (Mutex::eMutexTypeRecursive), m_is_running (false), diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index 7bc795dcf7a..c0d8685db39 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -100,6 +100,18 @@ public: } bool + GetThreadSuffixSupported () const + { + return m_thread_suffix_supported; + } + + void + SetThreadSuffixSupported (bool enabled) + { + m_thread_suffix_supported = enabled; + } + + bool SendAsyncSignal (int signo); bool @@ -244,7 +256,8 @@ protected: //------------------------------------------------------------------ // Classes that inherit from GDBRemoteCommunication can see and modify these //------------------------------------------------------------------ - bool m_send_acks; + bool m_send_acks:1, + m_thread_suffix_supported:1; lldb_private::Listener m_rx_packet_listener; lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time lldb_private::Predicate<bool> m_is_running; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index eaf91eb98b1..2c00b9a8431 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -217,15 +217,19 @@ GDBRemoteRegisterContext::ReadRegisterBytes (uint32_t reg, DataExtractor &data) Mutex::Locker locker; if (gdb_comm.GetSequenceMutex (locker)) { - if (GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID())) + const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); + if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID())) { - char packet[32]; + char packet[64]; StringExtractorGDBRemote response; - int packet_len; + int packet_len = 0; if (m_read_all_at_once) { // Get all registers in one packet - packet_len = ::snprintf (packet, sizeof(packet), "g"); + if (thread_suffix_supported) + packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4x;", m_thread.GetID()); + else + packet_len = ::snprintf (packet, sizeof(packet), "g"); assert (packet_len < (sizeof(packet) - 1)); if (gdb_comm.SendPacketAndWaitForResponse(packet, response, 1, false)) { @@ -237,7 +241,10 @@ GDBRemoteRegisterContext::ReadRegisterBytes (uint32_t reg, DataExtractor &data) else { // Get each register individually - packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg); + if (thread_suffix_supported) + packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4x;", reg, m_thread.GetID()); + else + packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg); assert (packet_len < (sizeof(packet) - 1)); if (gdb_comm.SendPacketAndWaitForResponse(packet, response, 1, false)) PrivateSetRegisterValue (reg, response); @@ -319,7 +326,8 @@ GDBRemoteRegisterContext::WriteRegisterBytes (uint32_t reg, DataExtractor &data, Mutex::Locker locker; if (gdb_comm.GetSequenceMutex (locker)) { - if (GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID())) + const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); + if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID())) { uint32_t offset, end_offset; StreamString packet; @@ -336,6 +344,9 @@ GDBRemoteRegisterContext::WriteRegisterBytes (uint32_t reg, DataExtractor &data, eByteOrderHost, eByteOrderHost); + if (thread_suffix_supported) + packet.Printf (";thread:%4.4x;", m_thread.GetID()); + // Invalidate all register values InvalidateIfNeeded (true); @@ -361,6 +372,9 @@ GDBRemoteRegisterContext::WriteRegisterBytes (uint32_t reg, DataExtractor &data, eByteOrderHost, eByteOrderHost); + if (thread_suffix_supported) + packet.Printf (";thread:%4.4x;", m_thread.GetID()); + // Invalidate just this register m_reg_valid[reg] = false; if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), @@ -391,16 +405,31 @@ GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) Mutex::Locker locker; if (gdb_comm.GetSequenceMutex (locker)) { - if (GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID())) + char packet[32]; + const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); + if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID())) { - if (gdb_comm.SendPacketAndWaitForResponse("g", response, 1, false)) + int packet_len = 0; + if (thread_suffix_supported) + packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4x", m_thread.GetID()); + else + packet_len = ::snprintf (packet, sizeof(packet), "g"); + assert (packet_len < (sizeof(packet) - 1)); + + if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 1, false)) { if (response.IsErrorPacket()) return false; - + response.GetStringRef().insert(0, 1, 'G'); - data_sp.reset (new DataBufferHeap(response.GetStringRef().c_str(), - response.GetStringRef().size())); + if (thread_suffix_supported) + { + char thread_id_cstr[64]; + ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4x;", m_thread.GetID()); + response.GetStringRef().append (thread_id_cstr); + } + data_sp.reset (new DataBufferHeap (response.GetStringRef().c_str(), + response.GetStringRef().size())); return true; } } @@ -419,7 +448,8 @@ GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data Mutex::Locker locker; if (gdb_comm.GetSequenceMutex (locker)) { - if (GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID())) + const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); + if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID())) { if (gdb_comm.SendPacketAndWaitForResponse((const char *)data_sp->GetBytes(), data_sp->GetByteSize(), diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 80580f8dddc..26aa4564281 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -554,6 +554,13 @@ ProcessGDBRemote::ConnectToDebugserver (const char *host_port) if (response.IsOKPacket()) m_gdb_comm.SetAckMode (false); } + + if (m_gdb_comm.SendPacketAndWaitForResponse("QThreadSuffixSupported", response, 1, false)) + { + if (response.IsOKPacket()) + m_gdb_comm.SetThreadSuffixSupported (true); + } + } return error; } @@ -2021,7 +2028,7 @@ ProcessGDBRemote::SetCurrentGDBRemoteThreadForRun (int tid) return true; char packet[32]; - const int packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid); + const int packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid); assert (packet_len + 1 < sizeof(packet)); StringExtractorGDBRemote response; if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, false)) |