1 //===-- GDBRemoteCommunicationHistory.h--------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef liblldb_GDBRemoteCommunicationHistory_h_
10 #define liblldb_GDBRemoteCommunicationHistory_h_
15 #include "lldb/lldb-public.h"
16 #include "llvm/Support/YAMLTraits.h"
17 #include "llvm/Support/raw_ostream.h"
19 namespace lldb_private {
20 namespace process_gdb_remote {
22 /// The history keeps a circular buffer of GDB remote packets. The history is
23 /// used for logging and replaying GDB remote packets.
24 class GDBRemoteCommunicationHistory {
26 friend llvm::yaml::MappingTraits<GDBRemoteCommunicationHistory>;
28 enum PacketType { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv };
30 /// Entry in the ring buffer containing the packet data, its type, size and
31 /// index. Entries can be serialized to file.
34 : packet(), type(ePacketTypeInvalid), bytes_transmitted(0),
35 packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {}
39 type = ePacketTypeInvalid;
40 bytes_transmitted = 0;
42 tid = LLDB_INVALID_THREAD_ID;
49 void Serialize(llvm::raw_ostream &strm) const;
53 uint32_t bytes_transmitted;
58 GDBRemoteCommunicationHistory(uint32_t size = 0);
60 ~GDBRemoteCommunicationHistory();
62 // For single char packets for ack, nack and /x03
63 void AddPacket(char packet_char, PacketType type, uint32_t bytes_transmitted);
65 void AddPacket(const std::string &src, uint32_t src_len, PacketType type,
66 uint32_t bytes_transmitted);
68 void Dump(Stream &strm) const;
69 void Dump(Log *log) const;
70 bool DidDumpToLog() const { return m_dumped_to_log; }
72 void SetStream(llvm::raw_ostream *strm) { m_stream = strm; }
75 uint32_t GetFirstSavedPacketIndex() const {
76 if (m_total_packet_count < m_packets.size())
79 return m_curr_idx + 1;
82 uint32_t GetNumPacketsInHistory() const {
83 if (m_total_packet_count < m_packets.size())
84 return m_total_packet_count;
86 return (uint32_t)m_packets.size();
89 uint32_t GetNextIndex() {
90 ++m_total_packet_count;
91 const uint32_t idx = m_curr_idx;
92 m_curr_idx = NormalizeIndex(idx + 1);
96 uint32_t NormalizeIndex(uint32_t i) const {
97 return m_packets.empty() ? 0 : i % m_packets.size();
100 std::vector<Entry> m_packets;
102 uint32_t m_total_packet_count;
103 mutable bool m_dumped_to_log;
104 llvm::raw_ostream *m_stream = nullptr;
107 } // namespace process_gdb_remote
108 } // namespace lldb_private
110 LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(
111 lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry)
117 struct ScalarEnumerationTraits<lldb_private::process_gdb_remote::
118 GDBRemoteCommunicationHistory::PacketType> {
119 static void enumeration(IO &io,
120 lldb_private::process_gdb_remote::
121 GDBRemoteCommunicationHistory::PacketType &value);
125 struct ScalarTraits<lldb_private::process_gdb_remote::
126 GDBRemoteCommunicationHistory::Entry::BinaryData> {
127 static void output(const lldb_private::process_gdb_remote::
128 GDBRemoteCommunicationHistory::Entry::BinaryData &,
129 void *, raw_ostream &);
132 input(StringRef, void *,
133 lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry::
136 static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
140 struct MappingTraits<
141 lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry> {
144 lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry
147 static StringRef validate(
149 lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry &);
155 #endif // liblldb_GDBRemoteCommunicationHistory_h_