LLDB  mainline
GDBRemoteClientBase.h
Go to the documentation of this file.
1 //===-- GDBRemoteClientBase.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 liblldb_GDBRemoteClientBase_h_
10 #define liblldb_GDBRemoteClientBase_h_
11 
12 #include "GDBRemoteCommunication.h"
13 
14 #include <condition_variable>
15 
16 namespace lldb_private {
17 namespace process_gdb_remote {
18 
20 public:
22  virtual ~ContinueDelegate();
23  virtual void HandleAsyncStdout(llvm::StringRef out) = 0;
24  virtual void HandleAsyncMisc(llvm::StringRef data) = 0;
25  virtual void HandleStopReply() = 0;
26 
27  // =========================================================================
28  /// Process asynchronously-received structured data.
29  ///
30  /// \param[in] data
31  /// The complete data packet, expected to start with JSON-async.
32  // =========================================================================
33  virtual void HandleAsyncStructuredDataPacket(llvm::StringRef data) = 0;
34  };
35 
36  GDBRemoteClientBase(const char *comm_name, const char *listener_name);
37 
38  bool SendAsyncSignal(int signo);
39 
40  bool Interrupt();
41 
43  ContinueDelegate &delegate, const UnixSignals &signals,
44  llvm::StringRef payload, StringExtractorGDBRemote &response);
45 
46  PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload,
47  StringExtractorGDBRemote &response,
48  bool send_async);
49 
51  llvm::StringRef payload, StringExtractorGDBRemote &response,
52  bool send_async,
53  llvm::function_ref<void(llvm::StringRef)> output_callback);
54 
55  bool SendvContPacket(llvm::StringRef payload,
56  StringExtractorGDBRemote &response);
57 
58  class Lock {
59  public:
60  Lock(GDBRemoteClientBase &comm, bool interrupt);
61  ~Lock();
62 
63  explicit operator bool() { return m_acquired; }
64 
65  // Whether we had to interrupt the continue thread to acquire the
66  // connection.
67  bool DidInterrupt() const { return m_did_interrupt; }
68 
69  private:
70  std::unique_lock<std::recursive_mutex> m_async_lock;
71  GDBRemoteClientBase &m_comm;
72  bool m_acquired;
73  bool m_did_interrupt;
74 
75  void SyncWithContinueThread(bool interrupt);
76  };
77 
78 protected:
80  SendPacketAndWaitForResponseNoLock(llvm::StringRef payload,
81  StringExtractorGDBRemote &response);
82 
83  virtual void OnRunPacketSent(bool first);
84 
85 private:
86  // Variables handling synchronization between the Continue thread and any
87  // other threads
88  // wishing to send packets over the connection. Either the continue thread has
89  // control over
90  // the connection (m_is_running == true) or the connection is free for an
91  // arbitrary number of
92  // other senders to take which indicate their interest by incrementing
93  // m_async_count.
94  // Semantics of individual states:
95  // - m_continue_packet == false, m_async_count == 0: connection is free
96  // - m_continue_packet == true, m_async_count == 0: only continue thread is
97  // present
98  // - m_continue_packet == true, m_async_count > 0: continue thread has
99  // control, async threads
100  // should interrupt it and wait for it to set m_continue_packet to false
101  // - m_continue_packet == false, m_async_count > 0: async threads have
102  // control, continue
103  // thread needs to wait for them to finish (m_async_count goes down to 0).
104  std::mutex m_mutex;
105  std::condition_variable m_cv;
106  // Packet with which to resume after an async interrupt. Can be changed by an
107  // async thread
108  // e.g. to inject a signal.
109  std::string m_continue_packet;
110  // When was the interrupt packet sent. Used to make sure we time out if the
111  // stub does not
112  // respond to interrupt requests.
113  std::chrono::time_point<std::chrono::steady_clock> m_interrupt_time;
114  uint32_t m_async_count;
115  bool m_is_running;
116  bool m_should_stop; // Whether we should resume after a stop.
117  // end of continue thread synchronization block
118 
119  // This handles the synchronization between individual async threads. For now
120  // they just use a
121  // simple mutex.
122  std::recursive_mutex m_async_mutex;
123 
124  bool ShouldStop(const UnixSignals &signals,
125  StringExtractorGDBRemote &response);
126 
127  class ContinueLock {
128  public:
129  enum class LockResult { Success, Cancelled, Failed };
130 
131  explicit ContinueLock(GDBRemoteClientBase &comm);
132  ~ContinueLock();
133  explicit operator bool() { return m_acquired; }
134 
135  LockResult lock();
136 
137  void unlock();
138 
139  private:
140  GDBRemoteClientBase &m_comm;
141  bool m_acquired;
142  };
143 };
144 
145 } // namespace process_gdb_remote
146 } // namespace lldb_private
147 
148 #endif // liblldb_GDBRemoteCommunicationClient_h_
PacketResult SendPacketAndWaitForResponseNoLock(llvm::StringRef payload, StringExtractorGDBRemote &response)
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
bool SendvContPacket(llvm::StringRef payload, StringExtractorGDBRemote &response)
PacketResult SendPacketAndReceiveResponseWithOutputSupport(llvm::StringRef payload, StringExtractorGDBRemote &response, bool send_async, llvm::function_ref< void(llvm::StringRef)> output_callback)
GDBRemoteClientBase(const char *comm_name, const char *listener_name)
virtual void HandleAsyncStructuredDataPacket(llvm::StringRef data)=0
Process asynchronously-received structured data.
lldb::StateType SendContinuePacketAndWaitForResponse(ContinueDelegate &delegate, const UnixSignals &signals, llvm::StringRef payload, StringExtractorGDBRemote &response)
PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload, StringExtractorGDBRemote &response, bool send_async)