diff options
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote')
6 files changed, 321 insertions, 51 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 707fe46c26f..15ab58975cc 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -32,7 +32,8 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, const char m_rx_packet_listener (listener_name), m_sequence_mutex (Mutex::eMutexTypeRecursive), m_public_is_running (false), - m_private_is_running (false) + m_private_is_running (false), + m_send_acks (true) { m_rx_packet_listener.StartListeningForEvents(this, Communication::eBroadcastBitPacketAvailable | @@ -127,7 +128,10 @@ GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_le if (GetSendAcks ()) { if (GetAck () != '+') + { + printf("get ack failed..."); return 0; + } } } else @@ -238,9 +242,10 @@ GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &packet, c } } } - else if (Communication::eBroadcastBitReadThreadDidExit) + else if (event_type | Communication::eBroadcastBitReadThreadDidExit) { // Our read thread exited on us so just fall through and return zero... + Disconnect(); } } return 0; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index 858f67c6534..e8129ce919f 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -88,15 +88,18 @@ public: return m_public_is_running.GetValue(); } + bool + GetSendAcks () + { + return m_send_acks; + } + //------------------------------------------------------------------ // Client and server must implement these pure virtual functions //------------------------------------------------------------------ virtual bool GetThreadSuffixSupported () = 0; - virtual bool - GetSendAcks () = 0; - //------------------------------------------------------------------ // Set the global packet timeout. // @@ -135,6 +138,10 @@ protected: 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; lldb_private::Predicate<bool> m_private_is_running; + bool m_send_acks; + + + private: //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 7700ab2b7f5..e158e5c6237 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -50,7 +50,10 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() : m_async_packet (), m_async_response (), m_async_signal (-1), - m_host_arch() + m_host_arch(), + m_os_version_major (UINT32_MAX), + m_os_version_minor (UINT32_MAX), + m_os_version_update (UINT32_MAX) { m_rx_packet_listener.StartListeningForEvents(this, Communication::eBroadcastBitPacketAvailable | @@ -73,19 +76,36 @@ GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() } bool -GDBRemoteCommunicationClient::GetSendAcks () +GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr) +{ + // Start the read thread after we send the handshake ack since if we + // fail to send the handshake ack, there is no reason to continue... + if (SendAck()) + return StartReadThread (error_ptr); + + if (error_ptr) + error_ptr->SetErrorString("failed to send the handshake ack"); + return false; +} + +void +GDBRemoteCommunicationClient::QueryNoAckModeSupported () { if (m_supports_not_sending_acks == eLazyBoolCalculate) { - StringExtractorGDBRemote response; + m_send_acks = true; m_supports_not_sending_acks = eLazyBoolNo; + + StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false)) { if (response.IsOKResponse()) + { + m_send_acks = false; m_supports_not_sending_acks = eLazyBoolYes; + } } } - return m_supports_not_sending_acks != eLazyBoolYes; } void @@ -664,6 +684,79 @@ GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_valu } bool +GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major, + uint32_t &minor, + uint32_t &update) +{ + if (GetHostInfo ()) + { + if (m_os_version_major != UINT32_MAX) + { + major = m_os_version_major; + minor = m_os_version_minor; + update = m_os_version_update; + return true; + } + } + return false; +} + +bool +GDBRemoteCommunicationClient::GetOSBuildString (std::string &s) +{ + if (GetHostInfo ()) + { + if (!m_os_build.empty()) + { + s = m_os_build; + return true; + } + } + s.clear(); + return false; +} + + +bool +GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s) +{ + if (GetHostInfo ()) + { + if (!m_os_kernel.empty()) + { + s = m_os_kernel; + return true; + } + } + s.clear(); + return false; +} + +bool +GDBRemoteCommunicationClient::GetHostname (std::string &s) +{ + if (GetHostInfo ()) + { + if (!m_hostname.empty()) + { + s = m_hostname; + return true; + } + } + s.clear(); + return false; +} + +ArchSpec +GDBRemoteCommunicationClient::GetSystemArchitecture () +{ + if (GetHostInfo ()) + return m_host_arch; + return ArchSpec(); +} + + +bool GDBRemoteCommunicationClient::GetHostInfo () { if (m_supports_qHostInfo == eLazyBoolCalculate) @@ -685,7 +778,9 @@ GDBRemoteCommunicationClient::GetHostInfo () std::string arch_name; std::string os_name; std::string vendor_name; + std::string triple; uint32_t pointer_byte_size = 0; + StringExtractor extractor; ByteOrder byte_order = eByteOrderInvalid; while (response.GetNameColonValue(name, value)) { @@ -703,6 +798,31 @@ GDBRemoteCommunicationClient::GetHostInfo () { arch_name.swap (value); } + else if (name.compare("triple") == 0) + { + // The triple comes as ASCII hex bytes since it contains '-' chars + extractor.GetStringRef().swap(value); + extractor.SetFilePos(0); + extractor.GetHexByteString (triple); + } + else if (name.compare("os_build") == 0) + { + extractor.GetStringRef().swap(value); + extractor.SetFilePos(0); + extractor.GetHexByteString (m_os_build); + } + else if (name.compare("hostname") == 0) + { + extractor.GetStringRef().swap(value); + extractor.SetFilePos(0); + extractor.GetHexByteString (m_hostname); + } + else if (name.compare("os_kernel") == 0) + { + extractor.GetStringRef().swap(value); + extractor.SetFilePos(0); + extractor.GetHexByteString (m_os_kernel); + } else if (name.compare("ostype") == 0) { os_name.swap (value); @@ -724,13 +844,52 @@ GDBRemoteCommunicationClient::GetHostInfo () { pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0); } + else if (name.compare("os_version") == 0) + { + Args::StringToVersion (value.c_str(), + m_os_version_major, + m_os_version_minor, + m_os_version_update); + } } - if (arch_name.empty()) + if (triple.empty()) { - if (cpu != LLDB_INVALID_CPUTYPE) + if (arch_name.empty()) + { + if (cpu != LLDB_INVALID_CPUTYPE) + { + m_host_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub); + if (pointer_byte_size) + { + assert (pointer_byte_size == m_host_arch.GetAddressByteSize()); + } + if (byte_order != eByteOrderInvalid) + { + assert (byte_order == m_host_arch.GetByteOrder()); + } + if (!vendor_name.empty()) + m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name)); + if (!os_name.empty()) + m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name)); + + } + } + else { - m_host_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub); + std::string triple; + triple += arch_name; + triple += '-'; + if (vendor_name.empty()) + triple += "unknown"; + else + triple += vendor_name; + triple += '-'; + if (os_name.empty()) + triple += "unknown"; + else + triple += os_name; + m_host_arch.SetTriple (triple.c_str()); if (pointer_byte_size) { assert (pointer_byte_size == m_host_arch.GetAddressByteSize()); @@ -739,29 +898,21 @@ GDBRemoteCommunicationClient::GetHostInfo () { assert (byte_order == m_host_arch.GetByteOrder()); } - if (!vendor_name.empty()) - m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name)); - if (!os_name.empty()) - m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name)); - + } } else { - std::string triple; - triple += arch_name; - triple += '-'; - if (vendor_name.empty()) - triple += "unknown"; - else - triple += vendor_name; - triple += '-'; - if (os_name.empty()) - triple += "unknown"; - else - triple += os_name; m_host_arch.SetTriple (triple.c_str()); - } + if (pointer_byte_size) + { + assert (pointer_byte_size == m_host_arch.GetAddressByteSize()); + } + if (byte_order != eByteOrderInvalid) + { + assert (byte_order == m_host_arch.GetByteOrder()); + } + } } } return m_supports_qHostInfo == eLazyBoolYes; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index bcf23f2c589..410d80de316 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -29,6 +29,13 @@ public: virtual ~GDBRemoteCommunicationClient(); + //------------------------------------------------------------------ + // After connecting, send the handshake to the server to make sure + // we are communicating with it. + //------------------------------------------------------------------ + bool + HandshakeWithServer (lldb_private::Error *error_ptr); + size_t SendPacketAndWaitForResponse (const char *send_payload, StringExtractorGDBRemote &response, @@ -49,8 +56,8 @@ public: virtual bool GetThreadSuffixSupported (); - virtual bool - GetSendAcks (); + void + QueryNoAckModeSupported (); bool SendAsyncSignal (int signo); @@ -186,6 +193,23 @@ public: GetHostInfo (); bool + GetOSVersion (uint32_t &major, + uint32_t &minor, + uint32_t &update); + + bool + GetOSBuildString (std::string &s); + + bool + GetOSKernelDescription (std::string &s); + + lldb_private::ArchSpec + GetSystemArchitecture (); + + bool + GetHostname (std::string &s); + + bool GetSupportsThreadSuffix (); bool @@ -232,7 +256,12 @@ protected: int m_async_signal; // We were asked to deliver a signal to the inferior process. lldb_private::ArchSpec m_host_arch; - uint32_t m_cpusubtype; + uint32_t m_os_version_major; + uint32_t m_os_version_minor; + uint32_t m_os_version_update; + std::string m_os_build; + std::string m_os_kernel; + std::string m_hostname; private: //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 18d6087e8b5..faee6776a83 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -35,8 +35,7 @@ using namespace lldb_private; //---------------------------------------------------------------------- GDBRemoteCommunicationServer::GDBRemoteCommunicationServer() : GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet"), - m_async_thread (LLDB_INVALID_HOST_THREAD), - m_send_acks (true) + m_async_thread (LLDB_INVALID_HOST_THREAD) { } @@ -73,6 +72,7 @@ GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() // bool GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout_ptr, + Error &error, bool &interrupt, bool &quit) { @@ -87,10 +87,12 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout break; case StringExtractorGDBRemote::eServerPacketType_invalid: + error.SetErrorString("invalid packet"); quit = true; break; case StringExtractorGDBRemote::eServerPacketType_interrupt: + error.SetErrorString("interrupt received"); interrupt = true; break; @@ -99,9 +101,20 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout case StringExtractorGDBRemote::eServerPacketType_qHostInfo: return Handle_qHostInfo (); + + case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode: + return Handle_QStartNoAckMode (); } return true; } + else + { + if (!IsConnected()) + error.SetErrorString("lost connection"); + else + error.SetErrorString("timeout"); + } + return false; } @@ -111,6 +124,19 @@ GDBRemoteCommunicationServer::SendUnimplementedResponse () return SendPacket (""); } +size_t +GDBRemoteCommunicationServer::SendOKResponse () +{ + return SendPacket ("OK"); +} + +bool +GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr) +{ + if (StartReadThread(error_ptr)) + return GetAck(); + return false; +} bool GDBRemoteCommunicationServer::Handle_qHostInfo () @@ -120,17 +146,18 @@ GDBRemoteCommunicationServer::Handle_qHostInfo () // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00 ArchSpec host_arch (Host::GetArchitecture ()); - const llvm::Triple &host_triple = host_arch.GetTriple(); - const llvm::StringRef arch_name (host_triple.getArchName()); - const llvm::StringRef vendor_name (host_triple.getOSName()); - const llvm::StringRef os_name (host_triple.getVendorName()); - response.Printf ("arch:%.*s;ostype:%.*s;vendor:%.*s;ptrsize:%u", - (int)arch_name.size(), arch_name.data(), - (int)os_name.size(), os_name.data(), - (int)vendor_name.size(), vendor_name.data(), - host_arch.GetAddressByteSize()); - + response.PutCString("triple:"); + response.PutCStringAsRawHex8(host_triple.getTriple().c_str()); + response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize()); + + uint32_t cpu = host_arch.GetMachOCPUType(); + uint32_t sub = host_arch.GetMachOCPUSubType(); + if (cpu != LLDB_INVALID_CPUTYPE) + response.Printf ("cputype:%u;", cpu); + if (sub != LLDB_INVALID_CPUTYPE) + response.Printf ("cpusubtype:%u;", sub); + switch (lldb::endian::InlHostByteOrder()) { case eByteOrderBig: response.PutCString ("endian:big;"); break; @@ -139,5 +166,52 @@ GDBRemoteCommunicationServer::Handle_qHostInfo () default: response.PutCString ("endian:unknown;"); break; } + uint32_t major = UINT32_MAX; + uint32_t minor = UINT32_MAX; + uint32_t update = UINT32_MAX; + if (Host::GetOSVersion (major, minor, update)) + { + if (major != UINT32_MAX) + { + response.Printf("os_version:%u", major); + if (minor != UINT32_MAX) + { + response.Printf(".%u", minor); + if (update != UINT32_MAX) + response.Printf(".%u", update); + } + response.PutChar(';'); + } + } + + std::string s; + if (Host::GetOSBuildString (s)) + { + response.PutCString ("os_build:"); + response.PutCStringAsRawHex8(s.c_str()); + response.PutChar(';'); + } + if (Host::GetOSKernelDescription (s)) + { + response.PutCString ("os_kernel:"); + response.PutCStringAsRawHex8(s.c_str()); + response.PutChar(';'); + } + if (Host::GetHostname (s)) + { + response.PutCString ("hostname:"); + response.PutCStringAsRawHex8(s.c_str()); + response.PutChar(';'); + } + return SendPacket (response.GetString().c_str(),response.GetString().size()) > 0; } + + +bool +GDBRemoteCommunicationServer::Handle_QStartNoAckMode () +{ + SendOKResponse (); + m_send_acks = false; + return true; +} diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h index 4e0b24ddea0..66ddc77bc95 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h @@ -35,6 +35,7 @@ public: bool GetPacketAndSendResponse (const lldb_private::TimeValue* timeout_ptr, + lldb_private::Error &error, bool &interrupt, bool &quit); @@ -44,23 +45,26 @@ public: return true; } - virtual bool - GetSendAcks () - { - return m_send_acks; - } + // After connecting, do a little handshake with the client to make sure + // we are at least communicating + bool + HandshakeWithClient (lldb_private::Error *error_ptr); protected: lldb::thread_t m_async_thread; - bool m_send_acks; size_t SendUnimplementedResponse (); + size_t + SendOKResponse (); bool Handle_qHostInfo (); + bool + Handle_QStartNoAckMode (); + private: //------------------------------------------------------------------ // For GDBRemoteCommunicationServer only |