1 //===-- GDBRemoteCommunicationReplayServer.h --------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_GDBRemoteCommunicationReplayServer_h_
11 #define liblldb_GDBRemoteCommunicationReplayServer_h_
12 
13 // Other libraries and framework includes
14 #include "GDBRemoteCommunication.h"
15 #include "GDBRemoteCommunicationHistory.h"
16 
17 // Project includes
18 #include "lldb/Host/HostThread.h"
19 #include "lldb/Utility/Broadcaster.h"
20 #include "lldb/lldb-private-forward.h"
21 #include "llvm/Support/Error.h"
22 
23 // C Includes
24 // C++ Includes
25 #include <functional>
26 #include <map>
27 #include <thread>
28 
29 class StringExtractorGDBRemote;
30 
31 namespace lldb_private {
32 namespace process_gdb_remote {
33 
34 class ProcessGDBRemote;
35 
36 /// Dummy GDB server that replays packets from the GDB Remote Communication
37 /// history. This is used to replay GDB packets.
38 class GDBRemoteCommunicationReplayServer : public GDBRemoteCommunication {
39 public:
40   GDBRemoteCommunicationReplayServer();
41 
42   ~GDBRemoteCommunicationReplayServer() override;
43 
44   PacketResult GetPacketAndSendResponse(Timeout<std::micro> timeout,
45                                         Status &error, bool &interrupt,
46                                         bool &quit);
47 
HandshakeWithClient()48   bool HandshakeWithClient() { return GetAck() == PacketResult::Success; }
49 
50   llvm::Error LoadReplayHistory(const FileSpec &path);
51 
52   bool StartAsyncThread();
53   void StopAsyncThread();
54 
55 protected:
56   enum {
57     eBroadcastBitAsyncContinue = (1 << 0),
58     eBroadcastBitAsyncThreadShouldExit = (1 << 1),
59   };
60 
61   static void ReceivePacket(GDBRemoteCommunicationReplayServer &server,
62                             bool &done);
63   static lldb::thread_result_t AsyncThread(void *arg);
64 
65   /// Replay history with the oldest packet at the end.
66   std::vector<GDBRemoteCommunicationHistory::Entry> m_packet_history;
67 
68   /// Server thread.
69   Broadcaster m_async_broadcaster;
70   lldb::ListenerSP m_async_listener_sp;
71   HostThread m_async_thread;
72   std::recursive_mutex m_async_thread_state_mutex;
73 
74   bool m_skip_acks;
75 
76 private:
77   DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationReplayServer);
78 };
79 
80 } // namespace process_gdb_remote
81 } // namespace lldb_private
82 
83 #endif // liblldb_GDBRemoteCommunicationReplayServer_h_
84