From b42b48e051e9aaa374fe6da51acb15c7500072ca Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Fri, 19 Aug 2016 12:31:49 +0000 Subject: [PATCH] Remove the last manually constructed packet from gdb-remote register context + small refactor Summary: The tricky part here was that the exisiting implementation of WriteAllRegisters was expecting hex-encoded data (as that was what the first implementation I replaced was using, but here we had binary data to begin with. I thought the read/write register functions would be more useful if they handled the hex-encoding themselves (all the other client functions provide the responses in a more-or-less digested form). The read functions return a DataBuffer, so they can allocate as much memory as they need to, while the write functions functions take an llvm::ArrayRef, as that can be constructed from pretty much anything. Reviewers: clayborg Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D23659 llvm-svn: 279232 --- .../gdb-remote/GDBRemoteCommunicationClient.cpp | 42 ++++-- .../gdb-remote/GDBRemoteCommunicationClient.h | 19 ++- .../gdb-remote/GDBRemoteRegisterContext.cpp | 142 +++++++-------------- .../Process/gdb-remote/GDBRemoteRegisterContext.h | 4 +- .../Process/gdb-remote/ProcessGDBRemote.cpp | 5 +- .../Plugins/Process/gdb-remote/ThreadGDBRemote.cpp | 4 +- .../Plugins/Process/gdb-remote/ThreadGDBRemote.h | 3 +- .../GDBRemoteCommunicationClientTest.cpp | 42 +++--- 8 files changed, 115 insertions(+), 146 deletions(-) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index d893b86..79ff5d1 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -24,6 +24,7 @@ #include "lldb/Core/State.h" #include "lldb/Core/StreamGDBRemote.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/DataBufferHeap.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/StringConvert.h" #include "lldb/Host/TimeValue.h" @@ -3494,45 +3495,58 @@ GDBRemoteCommunicationClient::AvoidGPackets (ProcessGDBRemote *process) return m_avoid_g_packets == eLazyBoolYes; } -bool -GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg, StringExtractorGDBRemote &response) +DataBufferSP +GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg) { StreamString payload; payload.Printf("p%x", reg); - return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) == - PacketResult::Success; -} + StringExtractorGDBRemote response; + if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) != PacketResult::Success || + !response.IsNormalResponse()) + return nullptr; + DataBufferSP buffer_sp(new DataBufferHeap(response.GetStringRef().size() / 2, 0)); + response.GetHexBytes(buffer_sp->GetBytes(), buffer_sp->GetByteSize(), '\xcc'); + return buffer_sp; +} -bool -GDBRemoteCommunicationClient::ReadAllRegisters (lldb::tid_t tid, StringExtractorGDBRemote &response) +DataBufferSP +GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) { StreamString payload; payload.PutChar('g'); - return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) == - PacketResult::Success; + StringExtractorGDBRemote response; + if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) != PacketResult::Success || + !response.IsNormalResponse()) + return nullptr; + + DataBufferSP buffer_sp(new DataBufferHeap(response.GetStringRef().size() / 2, 0)); + response.GetHexBytes(buffer_sp->GetBytes(), buffer_sp->GetByteSize(), '\xcc'); + return buffer_sp; } bool -GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid, uint32_t reg_num, llvm::StringRef data) +GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid, uint32_t reg_num, llvm::ArrayRef data) { StreamString payload; payload.Printf("P%x=", reg_num); payload.PutBytesAsRawHex8(data.data(), data.size(), endian::InlHostByteOrder(), endian::InlHostByteOrder()); StringExtractorGDBRemote response; return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) == - PacketResult::Success; + PacketResult::Success && + response.IsOKResponse(); } bool -GDBRemoteCommunicationClient::WriteAllRegisters(lldb::tid_t tid, llvm::StringRef data) +GDBRemoteCommunicationClient::WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef data) { StreamString payload; payload.PutChar('G'); - payload.Write(data.data(), data.size()); + payload.PutBytesAsRawHex8(data.data(), data.size(), endian::InlHostByteOrder(), endian::InlHostByteOrder()); StringExtractorGDBRemote response; return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) == - PacketResult::Success; + PacketResult::Success && + response.IsOKResponse(); } bool diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 54e7079..eeeecb5 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -10,6 +10,8 @@ #ifndef liblldb_GDBRemoteCommunicationClient_h_ #define liblldb_GDBRemoteCommunicationClient_h_ +#include "GDBRemoteClientBase.h" + // C Includes // C++ Includes #include @@ -24,8 +26,6 @@ #include "lldb/Core/StructuredData.h" #include "lldb/Target/Process.h" -#include "GDBRemoteClientBase.h" - namespace lldb_private { namespace process_gdb_remote { @@ -485,23 +485,20 @@ public: bool CalculateMD5 (const FileSpec& file_spec, uint64_t &high, uint64_t &low); - - bool + lldb::DataBufferSP ReadRegister(lldb::tid_t tid, - uint32_t reg_num, // Must be the eRegisterKindProcessPlugin register number, to be sent to the remote - StringExtractorGDBRemote &response); + uint32_t reg_num); // Must be the eRegisterKindProcessPlugin register number - bool - ReadAllRegisters (lldb::tid_t tid, - StringExtractorGDBRemote &response); + lldb::DataBufferSP + ReadAllRegisters(lldb::tid_t tid); bool WriteRegister(lldb::tid_t tid, uint32_t reg_num, // eRegisterKindProcessPlugin register number - llvm::StringRef data); + llvm::ArrayRef data); bool - WriteAllRegisters(lldb::tid_t tid, llvm::StringRef data); + WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef data); bool SaveRegisterState(lldb::tid_t tid, uint32_t &save_id); diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index dd8ac9e..76a7d7d 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -130,7 +130,7 @@ GDBRemoteRegisterContext::ReadRegister (const RegisterInfo *reg_info, RegisterVa } bool -GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response) +GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef data) { const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); if (reg_info == NULL) @@ -139,14 +139,15 @@ GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor // Invalidate if needed InvalidateIfNeeded(false); - const uint32_t reg_byte_size = reg_info->byte_size; - const size_t bytes_copied = response.GetHexBytes (const_cast(m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)), reg_byte_size, '\xcc'); - bool success = bytes_copied == reg_byte_size; + const size_t reg_byte_size = reg_info->byte_size; + memcpy(const_cast(m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)), data.data(), + std::min(data.size(), reg_byte_size)); + bool success = data.size() >= reg_byte_size; if (success) { SetRegisterIsValid(reg, true); } - else if (bytes_copied > 0) + else if (data.size() > 0) { // Only set register is valid to false if we copied some bytes, else // leave it as it was. @@ -209,8 +210,9 @@ GDBRemoteRegisterContext::GetPrimordialRegister(const RegisterInfo *reg_info, const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB]; const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin]; StringExtractorGDBRemote response; - if (gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg, response)) - return PrivateSetRegisterValue (lldb_reg, response); + if (DataBufferSP buffer_sp = gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg)) + return PrivateSetRegisterValue(lldb_reg, + llvm::ArrayRef(buffer_sp->GetBytes(), buffer_sp->GetByteSize())); return false; } @@ -234,15 +236,19 @@ GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataE { if (m_read_all_at_once) { - StringExtractorGDBRemote response; - if (!gdb_comm.ReadAllRegisters(m_thread.GetProtocolID(), response)) - return false; - if (response.IsNormalResponse()) - if (response.GetHexBytes(const_cast(reinterpret_cast(m_reg_data.GetDataStart())), - m_reg_data.GetByteSize(), '\xcc') == m_reg_data.GetByteSize()) - SetAllRegisterValid (true); + if (DataBufferSP buffer_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) + { + memcpy(const_cast(m_reg_data.GetDataStart()), buffer_sp->GetBytes(), + std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize())); + if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) + { + SetAllRegisterValid(true); + return true; + } + } + return false; } - else if (reg_info->value_regs) + if (reg_info->value_regs) { // Process this composite register request by delegating to the constituent // primordial registers. @@ -330,8 +336,7 @@ GDBRemoteRegisterContext::SetPrimordialRegister(const RegisterInfo *reg_info, return gdb_comm.WriteRegister( m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin], - llvm::StringRef(reinterpret_cast(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)), - reg_info->byte_size)); + {m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size), reg_info->byte_size}); } bool @@ -371,38 +376,18 @@ GDBRemoteRegisterContext::WriteRegisterBytes (const RegisterInfo *reg_info, Data GDBRemoteClientBase::Lock lock(gdb_comm, false); if (lock) { - const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); - ProcessSP process_sp (m_thread.GetProcess()); - if (thread_suffix_supported || static_cast(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID())) - { - StreamString packet; - StringExtractorGDBRemote response; - if (m_read_all_at_once) { - // Set all registers in one packet - packet.PutChar ('G'); - packet.PutBytesAsRawHex8 (m_reg_data.GetDataStart(), - m_reg_data.GetByteSize(), - endian::InlHostByteOrder(), - endian::InlHostByteOrder()); - - if (thread_suffix_supported) - packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID()); - // Invalidate all register values InvalidateIfNeeded (true); - if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), - packet.GetString().size(), - response, - false) == GDBRemoteCommunication::PacketResult::Success) + // Set all registers in one packet + if (gdb_comm.WriteAllRegisters(m_thread.GetProtocolID(), + {m_reg_data.GetDataStart(), m_reg_data.GetByteSize()})) + { SetAllRegisterValid (false); - if (response.IsOKResponse()) - { - return true; - } + return true; } } else @@ -451,7 +436,6 @@ GDBRemoteRegisterContext::WriteRegisterBytes (const RegisterInfo *reg_info, Data return success; } - } } else { @@ -533,8 +517,6 @@ GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); - StringExtractorGDBRemote response; - const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false; GDBRemoteClientBase::Lock lock(gdb_comm, false); @@ -543,40 +525,22 @@ GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) if (gdb_comm.SyncThreadState(m_thread.GetProtocolID())) InvalidateAllRegisters(); - if (use_g_packet && gdb_comm.ReadAllRegisters(m_thread.GetProtocolID(), response)) - { - if (response.IsErrorResponse()) - return false; - - std::string &response_str = response.GetStringRef(); - if (!isxdigit(response_str[0])) - return false; - - data_sp.reset(new DataBufferHeap(response_str.c_str(), response_str.size())); + if (use_g_packet && (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID()))) return true; - } - else - { - // For the use_g_packet == false case, we're going to read each register - // individually and store them as binary data in a buffer instead of as ascii - // characters. - const RegisterInfo *reg_info; - - // data_sp will take ownership of this DataBufferHeap pointer soon. - DataBufferSP reg_ctx(new DataBufferHeap(m_reg_info.GetRegisterDataByteSize(), 0)); - for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++) - { - if (reg_info->value_regs) // skip registers that are slices of real registers - continue; - ReadRegisterBytes(reg_info, m_reg_data); - // ReadRegisterBytes saves the contents of the register in to the m_reg_data buffer - } - memcpy(reg_ctx->GetBytes(), m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize()); + // We're going to read each register + // individually and store them as binary data in a buffer. + const RegisterInfo *reg_info; - data_sp = reg_ctx; - return true; + for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++) + { + if (reg_info->value_regs) // skip registers that are slices of real registers + continue; + ReadRegisterBytes(reg_info, m_reg_data); + // ReadRegisterBytes saves the contents of the register in to the m_reg_data buffer } + data_sp.reset(new DataBufferHeap(m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize())); + return true; } else { @@ -616,31 +580,19 @@ GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false; - StringExtractorGDBRemote response; GDBRemoteClientBase::Lock lock(gdb_comm, false); if (lock) { // The data_sp contains the G response packet. - llvm::StringRef data(reinterpret_cast(data_sp->GetBytes()), data_sp->GetByteSize()); if (use_g_packet) { - if (gdb_comm.WriteAllRegisters(m_thread.GetProtocolID(), data)) + if (gdb_comm.WriteAllRegisters(m_thread.GetProtocolID(), {data_sp->GetBytes(), data_sp->GetByteSize()})) return true; uint32_t num_restored = 0; // We need to manually go through all of the registers and // restore them manually - - response.GetStringRef() = data; - DataBufferHeap buffer(data.size() / 2, 0); - - const uint32_t bytes_extracted = response.GetHexBytes(buffer.GetBytes(), buffer.GetByteSize(), '\xcc'); - - DataExtractor restore_data(buffer.GetBytes(), buffer.GetByteSize(), m_reg_data.GetByteOrder(), - m_reg_data.GetAddressByteSize()); - - if (bytes_extracted < restore_data.GetByteSize()) - restore_data.SetData(restore_data.GetDataStart(), bytes_extracted, m_reg_data.GetByteOrder()); + DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(), m_reg_data.GetAddressByteSize()); const RegisterInfo *reg_info; @@ -716,12 +668,12 @@ GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data const uint32_t reg_byte_size = reg_info->byte_size; - const char *restore_src = (const char *)restore_data.PeekData(register_offset, reg_byte_size); + const uint8_t *restore_src = restore_data.PeekData(register_offset, reg_byte_size); if (restore_src) { SetRegisterIsValid(reg, false); if (gdb_comm.WriteRegister(m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin], - llvm::StringRef(restore_src, reg_byte_size))) + {restore_src, reg_byte_size})) ++num_restored; } } @@ -759,13 +711,9 @@ GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data } SetRegisterIsValid(reg_info, false); - if (gdb_comm.WriteRegister( - m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin], - llvm::StringRef(reinterpret_cast(data_sp->GetBytes() + reg_info->byte_offset), - reg_info->byte_size))) - { + if (gdb_comm.WriteRegister(m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin], + {data_sp->GetBytes() + reg_info->byte_offset, reg_info->byte_size})) ++num_restored; - } } return num_restored > 0; } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index 0021b5e..c1d8249 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -107,8 +107,8 @@ protected: uint32_t data_offset); bool - PrivateSetRegisterValue (uint32_t reg, StringExtractor &response); - + PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef data); + bool PrivateSetRegisterValue (uint32_t reg, uint64_t val); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index be5c3b5..67fa0ee 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1991,7 +1991,10 @@ ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid, { StringExtractor reg_value_extractor; reg_value_extractor.GetStringRef() = pair.second; - gdb_thread->PrivateSetRegisterValue (pair.first, reg_value_extractor); + DataBufferSP buffer_sp(new DataBufferHeap(reg_value_extractor.GetStringRef().size() / 2, 0)); + reg_value_extractor.GetHexBytes(buffer_sp->GetBytes(), buffer_sp->GetByteSize(), '\xcc'); + gdb_thread->PrivateSetRegisterValue( + pair.first, llvm::ArrayRef(buffer_sp->GetBytes(), buffer_sp->GetByteSize())); } thread_sp->SetName (thread_name.empty() ? NULL : thread_name.c_str()); diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index a4af12c..02a617b 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -380,11 +380,11 @@ ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame) } bool -ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response) +ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef data) { GDBRemoteRegisterContext *gdb_reg_ctx = static_cast(GetRegisterContext ().get()); assert (gdb_reg_ctx); - return gdb_reg_ctx->PrivateSetRegisterValue (reg, response); + return gdb_reg_ctx->PrivateSetRegisterValue(reg, data); } bool diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h index d7619f4..d452042 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h @@ -130,8 +130,7 @@ protected: lldb_private::LazyBool m_associated_with_libdispatch_queue; bool - PrivateSetRegisterValue (uint32_t reg, - StringExtractor &response); + PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef data); bool PrivateSetRegisterValue (uint32_t reg, diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp index 702052d..0b1f60d 100644 --- a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp +++ b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp @@ -18,6 +18,9 @@ #include "gtest/gtest.h" #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "lldb/Core/DataBuffer.h" + +#include "llvm/ADT/ArrayRef.h" using namespace lldb_private::process_gdb_remote; using namespace lldb_private; @@ -54,7 +57,10 @@ HandlePacket(MockServer &server, llvm::StringRef expected, llvm::StringRef respo ASSERT_EQ(PacketResult::Success, server.SendPacket(response)); } -const char all_registers[] = "404142434445464748494a4b4c4d4e4f"; +uint8_t all_registers[] = {'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'}; +std::string all_registers_hex = "404142434445464748494a4b4c4d4e4f"; +uint8_t one_register[] = {'A', 'B', 'C', 'D'}; +std::string one_register_hex = "41424344"; } // end anonymous namespace @@ -73,16 +79,16 @@ TEST_F(GDBRemoteCommunicationClientTest, WriteRegister) const lldb::tid_t tid = 0x47; const uint32_t reg_num = 4; std::future write_result = - std::async(std::launch::async, [&] { return client.WriteRegister(tid, reg_num, "ABCD"); }); + std::async(std::launch::async, [&] { return client.WriteRegister(tid, reg_num, one_register); }); Handle_QThreadSuffixSupported(server, true); - HandlePacket(server, "P4=41424344;thread:0047;", "OK"); + HandlePacket(server, "P4=" + one_register_hex + ";thread:0047;", "OK"); ASSERT_TRUE(write_result.get()); write_result = std::async(std::launch::async, [&] { return client.WriteAllRegisters(tid, all_registers); }); - HandlePacket(server, std::string("G") + all_registers + ";thread:0047;", "OK"); + HandlePacket(server, "G" + all_registers_hex + ";thread:0047;", "OK"); ASSERT_TRUE(write_result.get()); } @@ -97,16 +103,16 @@ TEST_F(GDBRemoteCommunicationClientTest, WriteRegisterNoSuffix) const lldb::tid_t tid = 0x47; const uint32_t reg_num = 4; std::future write_result = - std::async(std::launch::async, [&] { return client.WriteRegister(tid, reg_num, "ABCD"); }); + std::async(std::launch::async, [&] { return client.WriteRegister(tid, reg_num, one_register); }); Handle_QThreadSuffixSupported(server, false); HandlePacket(server, "Hg47", "OK"); - HandlePacket(server, "P4=41424344", "OK"); + HandlePacket(server, "P4=" + one_register_hex, "OK"); ASSERT_TRUE(write_result.get()); write_result = std::async(std::launch::async, [&] { return client.WriteAllRegisters(tid, all_registers); }); - HandlePacket(server, std::string("G") + all_registers, "OK"); + HandlePacket(server, "G" + all_registers_hex, "OK"); ASSERT_TRUE(write_result.get()); } @@ -122,19 +128,21 @@ TEST_F(GDBRemoteCommunicationClientTest, ReadRegister) const uint32_t reg_num = 4; std::future async_result = std::async(std::launch::async, [&] { return client.GetpPacketSupported(tid); }); Handle_QThreadSuffixSupported(server, true); - HandlePacket(server, "p0;thread:0047;", "41424344"); + HandlePacket(server, "p0;thread:0047;", one_register_hex); ASSERT_TRUE(async_result.get()); - StringExtractorGDBRemote response; - async_result = std::async(std::launch::async, [&] { return client.ReadRegister(tid, reg_num, response); }); + std::future read_result = + std::async(std::launch::async, [&] { return client.ReadRegister(tid, reg_num); }); HandlePacket(server, "p4;thread:0047;", "41424344"); - ASSERT_TRUE(async_result.get()); - ASSERT_EQ("41424344", response.GetStringRef()); - - async_result = std::async(std::launch::async, [&] { return client.ReadAllRegisters(tid, response); }); - HandlePacket(server, "g;thread:0047;", all_registers); - ASSERT_TRUE(async_result.get()); - ASSERT_EQ(all_registers, response.GetStringRef()); + auto buffer_sp = read_result.get(); + ASSERT_TRUE(bool(buffer_sp)); + ASSERT_EQ(0, memcmp(buffer_sp->GetBytes(), one_register, sizeof one_register)); + + read_result = std::async(std::launch::async, [&] { return client.ReadAllRegisters(tid); }); + HandlePacket(server, "g;thread:0047;", all_registers_hex); + buffer_sp = read_result.get(); + ASSERT_TRUE(bool(buffer_sp)); + ASSERT_EQ(0, memcmp(buffer_sp->GetBytes(), all_registers, sizeof all_registers)); } TEST_F(GDBRemoteCommunicationClientTest, SaveRestoreRegistersNoSuffix) -- 2.7.4