1 //===-- GDBRemoteCommunicationHistory.cpp ---------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "GDBRemoteCommunicationHistory.h" 10 11 // Other libraries and framework includes 12 #include "lldb/Core/StreamFile.h" 13 #include "lldb/Utility/ConstString.h" 14 #include "lldb/Utility/Log.h" 15 16 using namespace llvm; 17 using namespace lldb; 18 using namespace lldb_private; 19 using namespace lldb_private::process_gdb_remote; 20 21 GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size) 22 : m_packets() { 23 if (size) 24 m_packets.resize(size); 25 } 26 27 GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() = default; 28 29 void GDBRemoteCommunicationHistory::AddPacket(char packet_char, 30 GDBRemotePacket::Type type, 31 uint32_t bytes_transmitted) { 32 const size_t size = m_packets.size(); 33 if (size == 0) 34 return; 35 36 const uint32_t idx = GetNextIndex(); 37 m_packets[idx].packet.data.assign(1, packet_char); 38 m_packets[idx].type = type; 39 m_packets[idx].bytes_transmitted = bytes_transmitted; 40 m_packets[idx].packet_idx = m_total_packet_count; 41 m_packets[idx].tid = llvm::get_threadid(); 42 if (m_recorder) 43 m_recorder->Record(m_packets[idx]); 44 } 45 46 void GDBRemoteCommunicationHistory::AddPacket(const std::string &src, 47 uint32_t src_len, 48 GDBRemotePacket::Type type, 49 uint32_t bytes_transmitted) { 50 const size_t size = m_packets.size(); 51 if (size == 0) 52 return; 53 54 const uint32_t idx = GetNextIndex(); 55 m_packets[idx].packet.data.assign(src, 0, src_len); 56 m_packets[idx].type = type; 57 m_packets[idx].bytes_transmitted = bytes_transmitted; 58 m_packets[idx].packet_idx = m_total_packet_count; 59 m_packets[idx].tid = llvm::get_threadid(); 60 if (m_recorder) 61 m_recorder->Record(m_packets[idx]); 62 } 63 64 void GDBRemoteCommunicationHistory::Dump(Stream &strm) const { 65 const uint32_t size = GetNumPacketsInHistory(); 66 const uint32_t first_idx = GetFirstSavedPacketIndex(); 67 const uint32_t stop_idx = m_curr_idx + size; 68 for (uint32_t i = first_idx; i < stop_idx; ++i) { 69 const uint32_t idx = NormalizeIndex(i); 70 const GDBRemotePacket &entry = m_packets[idx]; 71 if (entry.type == GDBRemotePacket::ePacketTypeInvalid || 72 entry.packet.data.empty()) 73 break; 74 strm.Printf("history[%u] ", entry.packet_idx); 75 entry.Dump(strm); 76 } 77 } 78 79 void GDBRemoteCommunicationHistory::Dump(Log *log) const { 80 if (!log || m_dumped_to_log) 81 return; 82 83 m_dumped_to_log = true; 84 const uint32_t size = GetNumPacketsInHistory(); 85 const uint32_t first_idx = GetFirstSavedPacketIndex(); 86 const uint32_t stop_idx = m_curr_idx + size; 87 for (uint32_t i = first_idx; i < stop_idx; ++i) { 88 const uint32_t idx = NormalizeIndex(i); 89 const GDBRemotePacket &entry = m_packets[idx]; 90 if (entry.type == GDBRemotePacket::ePacketTypeInvalid || 91 entry.packet.data.empty()) 92 break; 93 LLDB_LOGF(log, "history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s", 94 entry.packet_idx, entry.tid, entry.bytes_transmitted, 95 (entry.type == GDBRemotePacket::ePacketTypeSend) ? "send" 96 : "read", 97 entry.packet.data.c_str()); 98 } 99 } 100 101