1 //===-- GDBRemoteCommunicationReplayServer.h --------------------*- 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 #ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H
10 #define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H
11 
12 // Other libraries and framework includes
13 #include "GDBRemoteCommunication.h"
14 #include "GDBRemoteCommunicationClient.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   Status Connect(process_gdb_remote::GDBRemoteCommunicationClient &client);
56 
57 protected:
58   enum {
59     eBroadcastBitAsyncContinue = (1 << 0),
60     eBroadcastBitAsyncThreadShouldExit = (1 << 1),
61   };
62 
63   static void ReceivePacket(GDBRemoteCommunicationReplayServer &server,
64                             bool &done);
65   static lldb::thread_result_t AsyncThread(void *arg);
66 
67   /// Replay history with the oldest packet at the end.
68   std::vector<GDBRemotePacket> m_packet_history;
69 
70   /// Server thread.
71   Broadcaster m_async_broadcaster;
72   lldb::ListenerSP m_async_listener_sp;
73   HostThread m_async_thread;
74   std::recursive_mutex m_async_thread_state_mutex;
75 
76   bool m_skip_acks;
77 
78 private:
79   GDBRemoteCommunicationReplayServer(
80       const GDBRemoteCommunicationReplayServer &) = delete;
81   const GDBRemoteCommunicationReplayServer &
82   operator=(const GDBRemoteCommunicationReplayServer &) = delete;
83 };
84 
85 } // namespace process_gdb_remote
86 } // namespace lldb_private
87 
88 #endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTECOMMUNICATIONREPLAYSERVER_H
89