1 //===-- GDBRemoteCommunicationHistory.cpp -----------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "GDBRemoteCommunicationHistory.h"
12 // Other libraries and framework includes
13 #include "lldb/Core/StreamFile.h"
14 #include "lldb/Utility/ConstString.h"
15 #include "lldb/Utility/Log.h"
19 using namespace lldb_private;
20 using namespace lldb_private::process_gdb_remote;
22 void GDBRemoteCommunicationHistory::Entry::Serialize(raw_ostream &strm) const {
23 yaml::Output yout(strm);
24 yout << const_cast<GDBRemoteCommunicationHistory::Entry &>(*this);
28 GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
29 : m_packets(), m_curr_idx(0), m_total_packet_count(0),
30 m_dumped_to_log(false) {
32 m_packets.resize(size);
35 GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {}
37 void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type,
38 uint32_t bytes_transmitted) {
39 const size_t size = m_packets.size();
43 const uint32_t idx = GetNextIndex();
44 m_packets[idx].packet.data.assign(1, packet_char);
45 m_packets[idx].type = type;
46 m_packets[idx].bytes_transmitted = bytes_transmitted;
47 m_packets[idx].packet_idx = m_total_packet_count;
48 m_packets[idx].tid = llvm::get_threadid();
49 if (m_stream && type == ePacketTypeRecv)
50 m_packets[idx].Serialize(*m_stream);
53 void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
54 uint32_t src_len, PacketType type,
55 uint32_t bytes_transmitted) {
56 const size_t size = m_packets.size();
60 const uint32_t idx = GetNextIndex();
61 m_packets[idx].packet.data.assign(src, 0, src_len);
62 m_packets[idx].type = type;
63 m_packets[idx].bytes_transmitted = bytes_transmitted;
64 m_packets[idx].packet_idx = m_total_packet_count;
65 m_packets[idx].tid = llvm::get_threadid();
66 if (m_stream && type == ePacketTypeRecv)
67 m_packets[idx].Serialize(*m_stream);
70 void GDBRemoteCommunicationHistory::Dump(Stream &strm) const {
71 const uint32_t size = GetNumPacketsInHistory();
72 const uint32_t first_idx = GetFirstSavedPacketIndex();
73 const uint32_t stop_idx = m_curr_idx + size;
74 for (uint32_t i = first_idx; i < stop_idx; ++i) {
75 const uint32_t idx = NormalizeIndex(i);
76 const Entry &entry = m_packets[idx];
77 if (entry.type == ePacketTypeInvalid || entry.packet.data.empty())
79 strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
80 entry.packet_idx, entry.tid, entry.bytes_transmitted,
81 (entry.type == ePacketTypeSend) ? "send" : "read",
82 entry.packet.data.c_str());
86 void GDBRemoteCommunicationHistory::Dump(Log *log) const {
87 if (!log || m_dumped_to_log)
90 m_dumped_to_log = true;
91 const uint32_t size = GetNumPacketsInHistory();
92 const uint32_t first_idx = GetFirstSavedPacketIndex();
93 const uint32_t stop_idx = m_curr_idx + size;
94 for (uint32_t i = first_idx; i < stop_idx; ++i) {
95 const uint32_t idx = NormalizeIndex(i);
96 const Entry &entry = m_packets[idx];
97 if (entry.type == ePacketTypeInvalid || entry.packet.data.empty())
99 log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
100 entry.packet_idx, entry.tid, entry.bytes_transmitted,
101 (entry.type == ePacketTypeSend) ? "send" : "read",
102 entry.packet.data.c_str());
106 void yaml::ScalarEnumerationTraits<GDBRemoteCommunicationHistory::PacketType>::
107 enumeration(IO &io, GDBRemoteCommunicationHistory::PacketType &value) {
108 io.enumCase(value, "Invalid",
109 GDBRemoteCommunicationHistory::ePacketTypeInvalid);
110 io.enumCase(value, "Send", GDBRemoteCommunicationHistory::ePacketTypeSend);
111 io.enumCase(value, "Recv", GDBRemoteCommunicationHistory::ePacketTypeRecv);
114 void yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::
115 output(const GDBRemoteCommunicationHistory::Entry::BinaryData &Val, void *,
117 Out << toHex(Val.data);
121 yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::input(
122 StringRef Scalar, void *,
123 GDBRemoteCommunicationHistory::Entry::BinaryData &Val) {
124 Val.data = fromHex(Scalar);
128 void yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::mapping(
129 IO &io, GDBRemoteCommunicationHistory::Entry &Entry) {
130 io.mapRequired("packet", Entry.packet);
131 io.mapRequired("type", Entry.type);
132 io.mapRequired("bytes", Entry.bytes_transmitted);
133 io.mapRequired("index", Entry.packet_idx);
134 io.mapRequired("tid", Entry.tid);
137 StringRef yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::validate(
138 IO &io, GDBRemoteCommunicationHistory::Entry &Entry) {
139 if (Entry.bytes_transmitted != Entry.packet.data.size())
140 return "BinaryData size doesn't match bytes transmitted";