1 //===-- GDBRemoteCommunicationHistory.cpp -----------------------*- C++ -*-===// 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(), m_curr_idx(0), m_total_packet_count(0), 23 m_dumped_to_log(false) { 24 if (size) 25 m_packets.resize(size); 26 } 27 28 GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {} 29 30 void GDBRemoteCommunicationHistory::AddPacket(char packet_char, 31 GDBRemotePacket::Type type, 32 uint32_t bytes_transmitted) { 33 const size_t size = m_packets.size(); 34 if (size == 0) 35 return; 36 37 const uint32_t idx = GetNextIndex(); 38 m_packets[idx].packet.data.assign(1, packet_char); 39 m_packets[idx].type = type; 40 m_packets[idx].bytes_transmitted = bytes_transmitted; 41 m_packets[idx].packet_idx = m_total_packet_count; 42 m_packets[idx].tid = llvm::get_threadid(); 43 if (m_recorder) 44 m_recorder->Record(m_packets[idx]); 45 } 46 47 void GDBRemoteCommunicationHistory::AddPacket(const std::string &src, 48 uint32_t src_len, 49 GDBRemotePacket::Type type, 50 uint32_t bytes_transmitted) { 51 const size_t size = m_packets.size(); 52 if (size == 0) 53 return; 54 55 const uint32_t idx = GetNextIndex(); 56 m_packets[idx].packet.data.assign(src, 0, src_len); 57 m_packets[idx].type = type; 58 m_packets[idx].bytes_transmitted = bytes_transmitted; 59 m_packets[idx].packet_idx = m_total_packet_count; 60 m_packets[idx].tid = llvm::get_threadid(); 61 if (m_recorder) 62 m_recorder->Record(m_packets[idx]); 63 } 64 65 void GDBRemoteCommunicationHistory::Dump(Stream &strm) const { 66 const uint32_t size = GetNumPacketsInHistory(); 67 const uint32_t first_idx = GetFirstSavedPacketIndex(); 68 const uint32_t stop_idx = m_curr_idx + size; 69 for (uint32_t i = first_idx; i < stop_idx; ++i) { 70 const uint32_t idx = NormalizeIndex(i); 71 const GDBRemotePacket &entry = m_packets[idx]; 72 if (entry.type == GDBRemotePacket::ePacketTypeInvalid || 73 entry.packet.data.empty()) 74 break; 75 strm.Printf("history[%u] ", entry.packet_idx); 76 entry.Dump(strm); 77 } 78 } 79 80 void GDBRemoteCommunicationHistory::Dump(Log *log) const { 81 if (!log || m_dumped_to_log) 82 return; 83 84 m_dumped_to_log = true; 85 const uint32_t size = GetNumPacketsInHistory(); 86 const uint32_t first_idx = GetFirstSavedPacketIndex(); 87 const uint32_t stop_idx = m_curr_idx + size; 88 for (uint32_t i = first_idx; i < stop_idx; ++i) { 89 const uint32_t idx = NormalizeIndex(i); 90 const GDBRemotePacket &entry = m_packets[idx]; 91 if (entry.type == GDBRemotePacket::ePacketTypeInvalid || 92 entry.packet.data.empty()) 93 break; 94 LLDB_LOGF(log, "history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s", 95 entry.packet_idx, entry.tid, entry.bytes_transmitted, 96 (entry.type == GDBRemotePacket::ePacketTypeSend) ? "send" 97 : "read", 98 entry.packet.data.c_str()); 99 } 100 } 101 102