Adding Support for Error Strings in Remote Packets

Summary:
This patch adds support for sending strings along with
error codes in the reply packets. The implementation is
based on the feedback recieved in the lldb-dev mailing
list. The patch also adds an extra packet for the client
to query if the server has the capability to provide
strings along with error replys.

Reviewers: labath, jingham, sas, lldb-commits, clayborg

Reviewed By: labath, clayborg

Differential Revision: https://reviews.llvm.org/D34945

llvm-svn: 307768
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index dac675e..4be92b7 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -20,6 +20,7 @@
 // Project includes
 #include "ProcessGDBRemoteLog.h"
 #include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/StreamString.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -27,7 +28,12 @@
 
 GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(
     const char *comm_name, const char *listener_name)
-    : GDBRemoteCommunication(comm_name, listener_name), m_exit_now(false) {}
+    : GDBRemoteCommunication(comm_name, listener_name), m_exit_now(false) {
+  RegisterPacketHandler(
+      StringExtractorGDBRemote::eServerPacketType_QEnableErrorStrings,
+      [this](StringExtractorGDBRemote packet, Status &error, bool &interrupt,
+             bool &quit) { return this->Handle_QErrorStringEnable(packet); });
+}
 
 GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() {}
 
@@ -100,6 +106,24 @@
 }
 
 GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServer::SendErrorResponse(const Status &error) {
+  if (m_send_error_strings) {
+    lldb_private::StreamString packet;
+    packet.Printf("E%2.2x;", static_cast<uint8_t>(error.GetError()));
+    packet.PutCStringAsRawHex8(error.AsCString());
+    return SendPacketNoLock(packet.GetString());
+  } else
+    return SendErrorResponse(error.GetError());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServer::Handle_QErrorStringEnable(
+    StringExtractorGDBRemote &packet) {
+  m_send_error_strings = true;
+  return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServer::SendIllFormedResponse(
     const StringExtractorGDBRemote &failed_packet, const char *message) {
   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));