diff options
7 files changed, 475 insertions, 131 deletions
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index c609deb5b7b..8303be8d937 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -606,6 +606,18 @@ typedef enum ObjCRuntimeVersions { eAppleObjC_V2 = 2 } ObjCRuntimeVersions; + +//---------------------------------------------------------------------- +// LazyBool is for boolean values that need to be calculated lazily. +// Values start off set to eLazyBoolCalculate, and then they can be +// calculated once and set to eLazyBoolNo or eLazyBoolYes. +//---------------------------------------------------------------------- +typedef enum LazyBool { + eLazyBoolCalculate = -1, + eLazyBoolNo = 0, + eLazyBoolYes = 1 +} LazyBool; + } // namespace lldb diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 6442e21b224..9ebb143a150 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -34,8 +34,15 @@ using namespace lldb_private; //---------------------------------------------------------------------- GDBRemoteCommunication::GDBRemoteCommunication() : Communication("gdb-remote.packets"), - m_send_acks (true), - m_thread_suffix_supported (false), + m_supports_not_sending_acks (eLazyBoolCalculate), + m_supports_thread_suffix (eLazyBoolCalculate), + m_supports_qHostInfo (eLazyBoolCalculate), + m_supports_vCont_all (eLazyBoolCalculate), + m_supports_vCont_any (eLazyBoolCalculate), + m_supports_vCont_c (eLazyBoolCalculate), + m_supports_vCont_C (eLazyBoolCalculate), + m_supports_vCont_s (eLazyBoolCalculate), + m_supports_vCont_S (eLazyBoolCalculate), m_rx_packet_listener ("gdbremote.rx_packet"), m_sequence_mutex (Mutex::eMutexTypeRecursive), m_public_is_running (false), @@ -79,7 +86,7 @@ GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_ int checksum = 0; // We only need to compute the checksum if we are sending acks - if (m_send_acks) + if (GetSendAcks ()) { for (size_t i = 0; i < payload_length; ++i) checksum += payload[i]; @@ -109,6 +116,112 @@ GDBRemoteCommunication::SendNack () return Write (&nack_char, 1, status, NULL) == 1; } +bool +GDBRemoteCommunication::GetSendAcks () +{ + if (m_supports_not_sending_acks == eLazyBoolCalculate) + { + StringExtractorGDBRemote response; + m_supports_not_sending_acks = eLazyBoolNo; + if (SendPacketAndWaitForResponse("QStartNoAckMode", response, 1, false)) + { + if (response.IsOKPacket()) + m_supports_not_sending_acks = eLazyBoolYes; + } + } + return m_supports_not_sending_acks != eLazyBoolYes; +} + +void +GDBRemoteCommunication::ResetDiscoverableSettings() +{ + m_supports_not_sending_acks = eLazyBoolCalculate; + m_supports_thread_suffix = eLazyBoolCalculate; + m_supports_qHostInfo = eLazyBoolCalculate; + m_supports_vCont_c = eLazyBoolCalculate; + m_supports_vCont_C = eLazyBoolCalculate; + m_supports_vCont_s = eLazyBoolCalculate; + m_supports_vCont_S = eLazyBoolCalculate; + m_arch.Clear(); + m_os.Clear(); + m_vendor.Clear(); + m_byte_order = lldb::endian::InlHostByteOrder(); + m_pointer_byte_size = 0; +} + + +bool +GDBRemoteCommunication::GetThreadSuffixSupported () +{ + if (m_supports_thread_suffix == eLazyBoolCalculate) + { + StringExtractorGDBRemote response; + m_supports_thread_suffix = eLazyBoolNo; + if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, 1, false)) + { + if (response.IsOKPacket()) + m_supports_thread_suffix = eLazyBoolYes; + } + } + return m_supports_thread_suffix; +} +bool +GDBRemoteCommunication::GetVContSupported (char flavor) +{ + if (m_supports_vCont_c == eLazyBoolCalculate) + { + StringExtractorGDBRemote response; + m_supports_vCont_c = eLazyBoolNo; + m_supports_vCont_C = eLazyBoolNo; + m_supports_vCont_s = eLazyBoolNo; + m_supports_vCont_S = eLazyBoolNo; + if (SendPacketAndWaitForResponse("vCont?", response, 1, false)) + { + const char *response_cstr = response.GetStringRef().c_str(); + if (::strstr (response_cstr, ";c")) + m_supports_vCont_c = eLazyBoolYes; + + if (::strstr (response_cstr, ";C")) + m_supports_vCont_C = eLazyBoolYes; + + if (::strstr (response_cstr, ";s")) + m_supports_vCont_s = eLazyBoolYes; + + if (::strstr (response_cstr, ";S")) + m_supports_vCont_S = eLazyBoolYes; + + if (m_supports_vCont_c == eLazyBoolYes && + m_supports_vCont_C == eLazyBoolYes && + m_supports_vCont_s == eLazyBoolYes && + m_supports_vCont_S == eLazyBoolYes) + { + m_supports_vCont_all = eLazyBoolYes; + } + + if (m_supports_vCont_c == eLazyBoolYes || + m_supports_vCont_C == eLazyBoolYes || + m_supports_vCont_s == eLazyBoolYes || + m_supports_vCont_S == eLazyBoolYes) + { + m_supports_vCont_any = eLazyBoolYes; + } + } + } + + switch (flavor) + { + case 'a': return m_supports_vCont_any; + case 'A': return m_supports_vCont_all; + case 'c': return m_supports_vCont_c; + case 'C': return m_supports_vCont_C; + case 's': return m_supports_vCont_s; + case 'S': return m_supports_vCont_S; + default: break; + } + return false; +} + + size_t GDBRemoteCommunication::SendPacketAndWaitForResponse ( @@ -451,7 +564,7 @@ GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_le size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL); if (bytes_written == packet.GetSize()) { - if (m_send_acks) + if (GetSendAcks ()) { if (GetAck (1) != '+') return 0; @@ -643,7 +756,7 @@ GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, if (success) response_str.assign (packet_data + 1, packet_size - 4); - if (m_send_acks) + if (GetSendAcks ()) { char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16); char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size()); @@ -829,66 +942,66 @@ GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uin } bool -GDBRemoteCommunication::GetHostInfo (uint32_t timeout_seconds) +GDBRemoteCommunication::GetHostInfo () { - m_arch.Clear(); - m_os.Clear(); - m_vendor.Clear(); - m_byte_order = lldb::endian::InlHostByteOrder(); - m_pointer_byte_size = 0; - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse ("qHostInfo", response, timeout_seconds, false)) + if (m_supports_qHostInfo == eLazyBoolCalculate) { - if (response.IsUnsupportedPacket()) - return false; + m_supports_qHostInfo = eLazyBoolNo; - - std::string name; - std::string value; - uint32_t cpu = LLDB_INVALID_CPUTYPE; - uint32_t sub = 0; - - while (response.GetNameColonValue(name, value)) + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse ("qHostInfo", response, 1, false)) { - if (name.compare("cputype") == 0) - { - // exception type in big endian hex - cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0); - } - else if (name.compare("cpusubtype") == 0) - { - // exception count in big endian hex - sub = Args::StringToUInt32 (value.c_str(), 0, 0); - } - else if (name.compare("ostype") == 0) - { - // exception data in big endian hex - m_os.SetCString(value.c_str()); - } - else if (name.compare("vendor") == 0) - { - m_vendor.SetCString(value.c_str()); - } - else if (name.compare("endian") == 0) - { - if (value.compare("little") == 0) - m_byte_order = eByteOrderLittle; - else if (value.compare("big") == 0) - m_byte_order = eByteOrderBig; - else if (value.compare("pdp") == 0) - m_byte_order = eByteOrderPDP; - } - else if (name.compare("ptrsize") == 0) + if (response.IsUnsupportedPacket()) + return false; + + m_supports_qHostInfo = eLazyBoolYes; + + std::string name; + std::string value; + uint32_t cpu = LLDB_INVALID_CPUTYPE; + uint32_t sub = 0; + + while (response.GetNameColonValue(name, value)) { - m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0); + if (name.compare("cputype") == 0) + { + // exception type in big endian hex + cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0); + } + else if (name.compare("cpusubtype") == 0) + { + // exception count in big endian hex + sub = Args::StringToUInt32 (value.c_str(), 0, 0); + } + else if (name.compare("ostype") == 0) + { + // exception data in big endian hex + m_os.SetCString(value.c_str()); + } + else if (name.compare("vendor") == 0) + { + m_vendor.SetCString(value.c_str()); + } + else if (name.compare("endian") == 0) + { + if (value.compare("little") == 0) + m_byte_order = eByteOrderLittle; + else if (value.compare("big") == 0) + m_byte_order = eByteOrderBig; + else if (value.compare("pdp") == 0) + m_byte_order = eByteOrderPDP; + } + else if (name.compare("ptrsize") == 0) + { + m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0); + } } + + if (cpu != LLDB_INVALID_CPUTYPE) + m_arch.SetMachOArch (cpu, sub); } - - if (cpu != LLDB_INVALID_CPUTYPE) - m_arch.SetMachOArch (cpu, sub); } - return HostInfoIsValid(); + return m_supports_qHostInfo == eLazyBoolYes; } int @@ -918,7 +1031,7 @@ const lldb_private::ArchSpec & GDBRemoteCommunication::GetHostArchitecture () { if (!HostInfoIsValid ()) - GetHostInfo (1); + GetHostInfo (); return m_arch; } @@ -926,7 +1039,7 @@ const lldb_private::ConstString & GDBRemoteCommunication::GetOSString () { if (!HostInfoIsValid ()) - GetHostInfo (1); + GetHostInfo (); return m_os; } @@ -934,7 +1047,7 @@ const lldb_private::ConstString & GDBRemoteCommunication::GetVendorString() { if (!HostInfoIsValid ()) - GetHostInfo (1); + GetHostInfo (); return m_vendor; } @@ -942,7 +1055,7 @@ lldb::ByteOrder GDBRemoteCommunication::GetByteOrder () { if (!HostInfoIsValid ()) - GetHostInfo (1); + GetHostInfo (); return m_byte_order; } @@ -950,7 +1063,7 @@ uint32_t GDBRemoteCommunication::GetAddressByteSize () { if (!HostInfoIsValid ()) - GetHostInfo (1); + GetHostInfo (); return m_pointer_byte_size; } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index 3ebabeb7085..1499ba90443 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -97,23 +97,8 @@ public: CalculcateChecksum (const char *payload, size_t payload_length); - void - SetAckMode (bool enabled) - { - m_send_acks = enabled; - } - bool - GetThreadSuffixSupported () const - { - return m_thread_suffix_supported; - } - - void - SetThreadSuffixSupported (bool enabled) - { - m_thread_suffix_supported = enabled; - } + GetThreadSuffixSupported (); bool SendAsyncSignal (int signo); @@ -229,12 +214,6 @@ public: bool GetHostInfo (uint32_t timeout_seconds); - bool - HostInfoIsValid () const - { - return m_pointer_byte_size != 0; - } - const lldb_private::ArchSpec & GetHostArchitecture (); @@ -250,6 +229,33 @@ public: uint32_t GetAddressByteSize (); + bool + GetVContSupported (char flavor); + + void + ResetDiscoverableSettings(); + + bool + GetHostInfo (); + + bool + GetSendAcks (); + + bool + GetSupportsThreadSuffix (); + + bool + HasFullVContSupport () + { + return GetVContSupported ('A'); + } + + bool + HasAnyVContSupport () + { + return GetVContSupported ('a'); + } + protected: typedef std::list<std::string> packet_collection; @@ -264,11 +270,24 @@ protected: bool WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr); + bool + HostInfoIsValid () const + { + return m_supports_qHostInfo != lldb::eLazyBoolCalculate; + } + //------------------------------------------------------------------ // Classes that inherit from GDBRemoteCommunication can see and modify these //------------------------------------------------------------------ - bool m_send_acks:1, - m_thread_suffix_supported:1; + lldb::LazyBool m_supports_not_sending_acks; + lldb::LazyBool m_supports_thread_suffix; + lldb::LazyBool m_supports_qHostInfo; + lldb::LazyBool m_supports_vCont_all; + lldb::LazyBool m_supports_vCont_any; + lldb::LazyBool m_supports_vCont_c; + lldb::LazyBool m_supports_vCont_C; + lldb::LazyBool m_supports_vCont_s; + lldb::LazyBool m_supports_vCont_S; 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_public_is_running; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 1c9b6ff5009..87bc0b9a67f 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -114,7 +114,10 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) : m_curr_tid (LLDB_INVALID_THREAD_ID), m_curr_tid_run (LLDB_INVALID_THREAD_ID), m_z0_supported (1), - m_continue_packet(), + m_continue_c_tids (), + m_continue_C_tids (), + m_continue_s_tids (), + m_continue_S_tids (), m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS), m_packet_timeout (1), m_max_memory_size (512), @@ -599,7 +602,6 @@ ProcessGDBRemote::ConnectToDebugserver (const char *connect_url) return error; } - m_gdb_comm.SetAckMode (true); if (m_gdb_comm.StartReadThread(&error)) { // Send an initial ack @@ -611,19 +613,11 @@ ProcessGDBRemote::ConnectToDebugserver (const char *connect_url) m_debugserver_pid, false); - StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse("QStartNoAckMode", response, 1, false)) - { - 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); - } - + m_gdb_comm.ResetDiscoverableSettings(); + m_gdb_comm.GetSendAcks (); + m_gdb_comm.GetThreadSuffixSupported (); + m_gdb_comm.GetHostInfo (); + m_gdb_comm.GetVContSupported ('c'); } return error; } @@ -847,12 +841,10 @@ ProcessGDBRemote::DidAttach () Error ProcessGDBRemote::WillResume () { - m_continue_packet.Clear(); - // Start the continue packet we will use to run the target. Each thread - // will append what it is supposed to be doing to this packet when the - // ThreadList::WillResume() is called. If a thread it supposed - // to stay stopped, then don't append anything to this string. - m_continue_packet.Printf("vCont"); + m_continue_c_tids.clear(); + m_continue_C_tids.clear(); + m_continue_s_tids.clear(); + m_continue_S_tids.clear(); return Error(); } @@ -867,14 +859,210 @@ ProcessGDBRemote::DoResume () Listener listener ("gdb-remote.resume-packet-sent"); if (listener.StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent)) { - EventSP event_sp; - TimeValue timeout; - timeout = TimeValue::Now(); - timeout.OffsetWithSeconds (5); - m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (m_continue_packet.GetData(), m_continue_packet.GetSize())); - - if (listener.WaitForEvent (&timeout, event_sp) == false) - error.SetErrorString("Resume timed out."); + StreamString continue_packet; + bool continue_packet_error = false; + if (m_gdb_comm.HasAnyVContSupport ()) + { + continue_packet.PutCString ("vCont"); + + if (!m_continue_c_tids.empty()) + { + if (m_gdb_comm.GetVContSupported ('c')) + { + for (tid_collection::const_iterator t_pos = m_continue_c_tids.begin(), t_end = m_continue_c_tids.end(); t_pos != t_end; ++t_pos) + continue_packet.Printf(";c:%4.4x", *t_pos); + } + else + continue_packet_error = true; + } + + if (!continue_packet_error && !m_continue_C_tids.empty()) + { + if (m_gdb_comm.GetVContSupported ('C')) + { + for (tid_sig_collection::const_iterator s_pos = m_continue_C_tids.begin(), s_end = m_continue_C_tids.end(); s_pos != s_end; ++s_pos) + continue_packet.Printf(";C%2.2x:%4.4x", s_pos->second, s_pos->first); + } + else + continue_packet_error = true; + } + + if (!continue_packet_error && !m_continue_s_tids.empty()) + { + if (m_gdb_comm.GetVContSupported ('s')) + { + for (tid_collection::const_iterator t_pos = m_continue_s_tids.begin(), t_end = m_continue_s_tids.end(); t_pos != t_end; ++t_pos) + continue_packet.Printf(";s:%4.4x", *t_pos); + } + else + continue_packet_error = true; + } + + if (!continue_packet_error && !m_continue_S_tids.empty()) + { + if (m_gdb_comm.GetVContSupported ('S')) + { + for (tid_sig_collection::const_iterator s_pos = m_continue_S_tids.begin(), s_end = m_continue_S_tids.end(); s_pos != s_end; ++s_pos) + continue_packet.Printf(";S%2.2x:%4.4x", s_pos->second, s_pos->first); + } + else + continue_packet_error = true; + } + + if (continue_packet_error) + continue_packet.GetString().clear(); + } + else + continue_packet_error = true; + + if (continue_packet_error) + { + continue_packet_error = false; + // Either no vCont support, or we tried to use part of the vCont + // packet that wasn't supported by the remote GDB server. + // We need to try and make a simple packet that can do our continue + const size_t num_threads = GetThreadList().GetSize(); + const size_t num_continue_c_tids = m_continue_c_tids.size(); + const size_t num_continue_C_tids = m_continue_C_tids.size(); + const size_t num_continue_s_tids = m_continue_s_tids.size(); + const size_t num_continue_S_tids = m_continue_S_tids.size(); + if (num_continue_c_tids > 0) + { + if (num_continue_c_tids == num_threads) + { + // All threads are resuming... + SetCurrentGDBRemoteThreadForRun (-1); + continue_packet.PutChar ('c'); + } + else if (num_continue_c_tids == 1 && + num_continue_C_tids == 0 && + num_continue_s_tids == 0 && + num_continue_S_tids == 0 ) + { + // Only one thread is continuing + SetCurrentGDBRemoteThreadForRun (m_continue_c_tids.front()); + continue_packet.PutChar ('c'); + } + else + { + // We can't represent this continue packet.... + continue_packet_error = true; + } + } + + if (!continue_packet_error && num_continue_C_tids > 0) + { + if (num_continue_C_tids == num_threads) + { + const int continue_signo = m_continue_C_tids.front().second; + if (num_continue_C_tids > 1) + { + for (size_t i=1; i<num_threads; ++i) + { + if (m_continue_C_tids[i].second != continue_signo) + continue_packet_error = true; + } + } + if (!continue_packet_error) + { + // Add threads continuing with the same signo... + SetCurrentGDBRemoteThreadForRun (-1); + continue_packet.Printf("C%2.2x", continue_signo); + } + } + else if (num_continue_c_tids == 0 && + num_continue_C_tids == 1 && + num_continue_s_tids == 0 && + num_continue_S_tids == 0 ) + { + // Only one thread is continuing with signal + SetCurrentGDBRemoteThreadForRun (m_continue_C_tids.front().first); + continue_packet.Printf("C%2.2x", m_continue_C_tids.front().second); + } + else + { + // We can't represent this continue packet.... + continue_packet_error = true; + } + } + + if (!continue_packet_error && num_continue_s_tids > 0) + { + if (num_continue_s_tids == num_threads) + { + // All threads are resuming... + SetCurrentGDBRemoteThreadForRun (-1); + continue_packet.PutChar ('s'); + } + else if (num_continue_c_tids == 0 && + num_continue_C_tids == 0 && + num_continue_s_tids == 1 && + num_continue_S_tids == 0 ) + { + // Only one thread is stepping + SetCurrentGDBRemoteThreadForRun (m_continue_s_tids.front()); + continue_packet.PutChar ('s'); + } + else + { + // We can't represent this continue packet.... + continue_packet_error = true; + } + } + + if (!continue_packet_error && num_continue_S_tids > 0) + { + if (num_continue_S_tids == num_threads) + { + const int step_signo = m_continue_S_tids.front().second; + // Are all threads trying to step with the same signal? + if (num_continue_S_tids > 1) + { + for (size_t i=1; i<num_threads; ++i) + { + if (m_continue_S_tids[i].second != step_signo) + continue_packet_error = true; + } + } + if (!continue_packet_error) + { + // Add threads stepping with the same signo... + SetCurrentGDBRemoteThreadForRun (-1); + continue_packet.Printf("S%2.2x", step_signo); + } + } + else if (num_continue_c_tids == 0 && + num_continue_C_tids == 0 && + num_continue_s_tids == 0 && + num_continue_S_tids == 1 ) + { + // Only one thread is stepping with signal + SetCurrentGDBRemoteThreadForRun (m_continue_S_tids.front().first); + continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second); + } + else + { + // We can't represent this continue packet.... + continue_packet_error = true; + } + } + } + + if (continue_packet_error) + { + error.SetErrorString ("can't make continue packet for this resume"); + } + else + { + EventSP event_sp; + TimeValue timeout; + timeout = TimeValue::Now(); + timeout.OffsetWithSeconds (5); + m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (continue_packet.GetData(), continue_packet.GetSize())); + + if (listener.WaitForEvent (&timeout, event_sp) == false) + error.SetErrorString("Resume timed out."); + } } return error; @@ -2118,7 +2306,11 @@ ProcessGDBRemote::SetCurrentGDBRemoteThread (int tid) return true; char packet[32]; - const int packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid); + int packet_len; + if (tid <= 0) + packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid); + else + packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid); assert (packet_len + 1 < sizeof(packet)); StringExtractorGDBRemote response; if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, false)) @@ -2139,7 +2331,12 @@ ProcessGDBRemote::SetCurrentGDBRemoteThreadForRun (int tid) return true; char packet[32]; - const int packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid); + int packet_len; + if (tid <= 0) + packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid); + else + 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)) diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 8db580b53f9..3e61ac6b840 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -14,6 +14,7 @@ // C++ Includes #include <list> +#include <vector> // Other libraries and framework includes #include "lldb/Core/ArchSpec.h" @@ -343,7 +344,12 @@ protected: lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all other operations lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for continue, step, etc uint32_t m_z0_supported:1; // Set to non-zero if Z0 and z0 packets are supported - lldb_private::StreamString m_continue_packet; + typedef std::vector<lldb::tid_t> tid_collection; + typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection; + tid_collection m_continue_c_tids; // 'c' for continue + tid_sig_collection m_continue_C_tids; // 'C' for continue with signal + tid_collection m_continue_s_tids; // 's' for step + tid_sig_collection m_continue_S_tids; // 'S' for step with signal lldb::addr_t m_dispatch_queue_offsets_addr; uint32_t m_packet_timeout; size_t m_max_memory_size; // The maximum number of bytes to read/write when reading and writing memory diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 37084072e78..6acefff3216 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -93,25 +93,25 @@ ThreadGDBRemote::WillResume (StateType resume_state) if (log) log->Printf ("Resuming thread: %4.4x with state: %s.", GetID(), StateAsCString(resume_state)); + ProcessGDBRemote &process = GetGDBProcess(); switch (resume_state) { case eStateSuspended: case eStateStopped: - // Don't append anything for threads that should stay stopped. break; case eStateRunning: if (m_process.GetUnixSignals().SignalIsValid (signo)) - GetGDBProcess().m_continue_packet.Printf(";C%2.2x:%4.4x", signo, GetID()); + process.m_continue_C_tids.push_back(std::make_pair(GetID(), signo)); else - GetGDBProcess().m_continue_packet.Printf(";c:%4.4x", GetID()); + process.m_continue_c_tids.push_back(GetID()); break; case eStateStepping: if (m_process.GetUnixSignals().SignalIsValid (signo)) - GetGDBProcess().m_continue_packet.Printf(";S%2.2x:%4.4x", signo, GetID()); + process.m_continue_S_tids.push_back(std::make_pair(GetID(), signo)); else - GetGDBProcess().m_continue_packet.Printf(";s:%4.4x", GetID()); + process.m_continue_s_tids.push_back(GetID()); break; default: diff --git a/lldb/tools/debugserver/source/DNBLog.cpp b/lldb/tools/debugserver/source/DNBLog.cpp index 52aa0815275..21661f1dcaf 100644 --- a/lldb/tools/debugserver/source/DNBLog.cpp +++ b/lldb/tools/debugserver/source/DNBLog.cpp @@ -93,6 +93,9 @@ DNBLogEnabled () static inline void _DNBLogVAPrintf(uint32_t flags, const char *format, va_list args) { + static PThreadMutex g_LogThreadedMutex(PTHREAD_MUTEX_RECURSIVE); + PTHREAD_MUTEX_LOCKER(locker, g_LogThreadedMutex); + if (g_log_callback) g_log_callback(g_log_baton, flags, format, args); } @@ -140,12 +143,6 @@ _DNBLogDebugVerbose (const char *format, ...) } -static pthread_mutex_t * -GetLogThreadedMutex() -{ - static PThreadMutex g_LogThreadedMutex(PTHREAD_MUTEX_RECURSIVE); - return g_LogThreadedMutex.Mutex(); -} static uint32_t g_message_id = 0; //---------------------------------------------------------------------- @@ -157,7 +154,7 @@ _DNBLogThreaded (const char *format, ...) { if (DNBLogEnabled ()) { - PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex()); + //PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex()); char *arg_msg = NULL; va_list args; @@ -202,7 +199,7 @@ _DNBLogThreadedIf (uint32_t log_bit, const char *format, ...) { if (DNBLogEnabled () && (log_bit & g_log_bits) == log_bit) { - PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex()); + //PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex()); char *arg_msg = NULL; va_list args; |