diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index d19e19802da2..1f4d63d482a4 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -517,18 +517,25 @@ GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, std::string &response_str = response.GetStringRef(); if (packet_data[0] == '$') { - assert (packet_size >= 4); // Must have at least '$#CC' where CC is checksum - assert (packet_data[packet_size-3] == '#'); - assert (::isxdigit (packet_data[packet_size-2])); // Must be checksum hex byte - assert (::isxdigit (packet_data[packet_size-1])); // Must be checksum hex byte - response_str.assign (packet_data + 1, packet_size - 4); + bool success = false; + if (packet_size < 4) + ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data); + else if (packet_data[packet_size-3] != '#' || + !::isxdigit (packet_data[packet_size-2]) || + !::isxdigit (packet_data[packet_size-1])) + ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data); + else + success = true; + + if (success) + response_str.assign (packet_data + 1, packet_size - 4); if (m_send_acks) { char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16); char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size()); checksum_error = packet_checksum != actual_checksum; // Send the ack or nack if needed - if (checksum_error) + if (checksum_error || !success) SendAck('-'); else SendAck('+'); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 934c00a3d1a4..3775d5b9ff69 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1036,6 +1036,15 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) // thread in big endian hex tid = Args::StringToUInt32 (value.c_str(), 0, 16); } + else if (name.compare("hexname") == 0) + { + StringExtractor name_extractor; + // Swap "value" over into "name_extractor" + name_extractor.GetStringRef().swap(value); + // Now convert the HEX bytes into a string value + name_extractor.GetHexByteString (value); + thread_name.swap (value); + } else if (name.compare("name") == 0) { thread_name.swap (value); diff --git a/lldb/source/Utility/StringExtractor.cpp b/lldb/source/Utility/StringExtractor.cpp index dc1483d01cda..c410ffd39b13 100644 --- a/lldb/source/Utility/StringExtractor.cpp +++ b/lldb/source/Utility/StringExtractor.cpp @@ -336,6 +336,16 @@ StringExtractor::GetHexWithFixedSize (uint32_t byte_size, bool little_endian, ui return fail_value; } +size_t +StringExtractor::GetHexByteString (std::string &str) +{ + str.clear(); + char ch; + while ((ch = GetHexU8()) != '\0') + str.append(1, ch); + return str.size(); +} + bool StringExtractor::GetNameColonValue (std::string &name, std::string &value) { diff --git a/lldb/source/Utility/StringExtractor.h b/lldb/source/Utility/StringExtractor.h index 3817ecbf6b06..ed67b926c2a2 100644 --- a/lldb/source/Utility/StringExtractor.h +++ b/lldb/source/Utility/StringExtractor.h @@ -110,6 +110,9 @@ public: uint64_t GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value); + size_t + GetHexByteString (std::string &str); + protected: //------------------------------------------------------------------ // For StringExtractor only diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index bb8c59ea0ebe..7fa05073d72d 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -1922,7 +1922,21 @@ RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid) const char *thread_name = DNBThreadGetName (pid, tid); if (thread_name && thread_name[0]) - ostrm << std::hex << "name:" << thread_name << ';'; + { + size_t thread_name_len = strlen(thread_name); + + if (::strcspn (thread_name, "$#+-;:") == thread_name_len) + ostrm << std::hex << "name:" << thread_name << ';'; + else + { + // the thread name contains special chars, send as hex bytes + ostrm << std::hex << "hexname:"; + uint8_t *u_thread_name = (uint8_t *)thread_name; + for (int i = 0; i < thread_name_len; i++) + ostrm << RAWHEX8(u_thread_name[i]); + ostrm << ';'; + } + } thread_identifier_info_data_t thread_ident_info; if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))