Modified the stop reply packet to be able to send the thread name using the
new "hexname" key for the "key:value;" duple that is part of the packet. This
allows for thread names to contain special characters such as $ # : ; + -

Debugserver now detects if the thread name contains special characters and
sends the chars in hex format if needed.



git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@123053 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index d19e198..1f4d63d 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -517,18 +517,25 @@
                     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/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 934c00a..3775d5b 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1036,6 +1036,15 @@
                     // 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/source/Utility/StringExtractor.cpp b/source/Utility/StringExtractor.cpp
index dc1483d..c410ffd 100644
--- a/source/Utility/StringExtractor.cpp
+++ b/source/Utility/StringExtractor.cpp
@@ -336,6 +336,16 @@
     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/source/Utility/StringExtractor.h b/source/Utility/StringExtractor.h
index 3817ecb..ed67b92 100644
--- a/source/Utility/StringExtractor.h
+++ b/source/Utility/StringExtractor.h
@@ -110,6 +110,9 @@
     uint64_t
     GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value);
 
+    size_t
+    GetHexByteString (std::string &str);
+
 protected:
     //------------------------------------------------------------------
     // For StringExtractor only