xref: /llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp (revision e768c4b858bd32b814baf142dd2acfeae6022638)
1 //===-- GDBRemoteClientBase.cpp ---------------------------------*- 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 #include "GDBRemoteClientBase.h"
11 
12 #include "llvm/ADT/StringExtras.h"
13 
14 #include "lldb/Target/UnixSignals.h"
15 #include "lldb/Utility/LLDBAssert.h"
16 
17 #include "ProcessGDBRemoteLog.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 using namespace lldb_private::process_gdb_remote;
22 
23 static const std::chrono::seconds kInterruptTimeout(5);
24 
25 /////////////////////////
26 // GDBRemoteClientBase //
27 /////////////////////////
28 
29 GDBRemoteClientBase::ContinueDelegate::~ContinueDelegate() = default;
30 
31 GDBRemoteClientBase::GDBRemoteClientBase(const char *comm_name, const char *listener_name)
32     : GDBRemoteCommunication(comm_name, listener_name), m_async_count(0), m_is_running(false), m_should_stop(false)
33 {
34 }
35 
36 StateType
37 GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(ContinueDelegate &delegate, const UnixSignals &signals,
38                                                           llvm::StringRef payload, StringExtractorGDBRemote &response)
39 {
40     Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
41     response.Clear();
42 
43     m_continue_packet = payload;
44     ContinueLock cont_lock(*this);
45     if (!cont_lock)
46         return eStateInvalid;
47     OnRunPacketSent(true);
48 
49     for (;;)
50     {
51         PacketResult read_result = ReadPacket(
52             response, std::chrono::duration_cast<std::chrono::microseconds>(kInterruptTimeout).count(), false);
53         switch (read_result)
54         {
55             case PacketResult::ErrorReplyTimeout:
56             {
57                 std::lock_guard<std::mutex> lock(m_mutex);
58                 if (m_async_count == 0)
59                     continue;
60                 if (std::chrono::steady_clock::now() >= m_interrupt_time + kInterruptTimeout)
61                     return eStateInvalid;
62             }
63             case PacketResult::Success:
64                 break;
65             default:
66                 if (log)
67                     log->Printf("GDBRemoteClientBase::%s () ReadPacket(...) => false", __FUNCTION__);
68                 return eStateInvalid;
69         }
70         if (response.Empty())
71             return eStateInvalid;
72 
73         const char stop_type = response.GetChar();
74         if (log)
75             log->Printf("GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
76 
77         switch (stop_type)
78         {
79             case 'W':
80             case 'X':
81                 return eStateExited;
82             case 'E':
83                 // ERROR
84                 return eStateInvalid;
85             default:
86                 if (log)
87                     log->Printf("GDBRemoteClientBase::%s () unrecognized async packet", __FUNCTION__);
88                 return eStateInvalid;
89             case 'O':
90             {
91                 std::string inferior_stdout;
92                 response.GetHexByteString(inferior_stdout);
93                 delegate.HandleAsyncStdout(inferior_stdout);
94                 break;
95             }
96             case 'A':
97                 delegate.HandleAsyncMisc(llvm::StringRef(response.GetStringRef()).substr(1));
98                 break;
99             case 'T':
100             case 'S':
101                 // Do this with the continue lock held.
102                 const bool should_stop = ShouldStop(signals, response);
103                 response.SetFilePos(0);
104 
105                 // The packet we should resume with. In the future
106                 // we should check our thread list and "do the right thing"
107                 // for new threads that show up while we stop and run async
108                 // packets. Setting the packet to 'c' to continue all threads
109                 // is the right thing to do 99.99% of the time because if a
110                 // thread was single stepping, and we sent an interrupt, we
111                 // will notice above that we didn't stop due to an interrupt
112                 // but stopped due to stepping and we would _not_ continue.
113                 // This packet may get modified by the async actions (e.g. to send a signal).
114                 m_continue_packet = 'c';
115                 cont_lock.unlock();
116 
117                 delegate.HandleStopReply();
118                 if (should_stop)
119                     return eStateStopped;
120 
121                 switch (cont_lock.lock())
122                 {
123                     case ContinueLock::LockResult::Success:
124                         break;
125                     case ContinueLock::LockResult::Failed:
126                         return eStateInvalid;
127                     case ContinueLock::LockResult::Cancelled:
128                         return eStateStopped;
129                 }
130                 OnRunPacketSent(false);
131                 break;
132         }
133     }
134 }
135 
136 bool
137 GDBRemoteClientBase::SendAsyncSignal(int signo)
138 {
139     Lock lock(*this, true);
140     if (!lock || !lock.DidInterrupt())
141         return false;
142 
143     m_continue_packet = 'C';
144     m_continue_packet += llvm::hexdigit((signo / 16) % 16);
145     m_continue_packet += llvm::hexdigit(signo % 16);
146     return true;
147 }
148 
149 bool
150 GDBRemoteClientBase::Interrupt()
151 {
152     Lock lock(*this, true);
153     if (!lock.DidInterrupt())
154         return false;
155     m_should_stop = true;
156     return true;
157 }
158 GDBRemoteCommunication::PacketResult
159 GDBRemoteClientBase::SendPacketAndWaitForResponse(llvm::StringRef payload, StringExtractorGDBRemote &response,
160                                                   bool send_async)
161 {
162     Lock lock(*this, send_async);
163     if (!lock)
164     {
165         if (Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
166             log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending packet '%.*s' (send_async=%d)",
167                         __FUNCTION__, int(payload.size()), payload.data(), send_async);
168         return PacketResult::ErrorSendFailed;
169     }
170 
171     return SendPacketAndWaitForResponseNoLock(payload, response);
172 }
173 
174 GDBRemoteCommunication::PacketResult
175 GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(llvm::StringRef payload, StringExtractorGDBRemote &response)
176 {
177     PacketResult packet_result = SendPacketNoLock(payload.data(), payload.size());
178     if (packet_result != PacketResult::Success)
179         return packet_result;
180 
181     const size_t max_response_retries = 3;
182     for (size_t i = 0; i < max_response_retries; ++i)
183     {
184         packet_result = ReadPacket(response, GetPacketTimeoutInMicroSeconds(), true);
185         // Make sure we received a response
186         if (packet_result != PacketResult::Success)
187             return packet_result;
188         // Make sure our response is valid for the payload that was sent
189         if (response.ValidateResponse())
190             return packet_result;
191         // Response says it wasn't valid
192         Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
193         if (log)
194             log->Printf("error: packet with payload \"%.*s\" got invalid response \"%s\": %s", int(payload.size()),
195                         payload.data(), response.GetStringRef().c_str(),
196                         (i == (max_response_retries - 1)) ? "using invalid response and giving up"
197                                                           : "ignoring response and waiting for another");
198     }
199     return packet_result;
200 }
201 
202 bool
203 GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload, StringExtractorGDBRemote &response)
204 {
205     Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
206     if (log)
207         log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
208 
209     // we want to lock down packet sending while we continue
210     Lock lock(*this, true);
211 
212     if (log)
213         log->Printf("GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s", __FUNCTION__, int(payload.size()),
214                     payload.data());
215 
216     if (SendPacketNoLock(payload.data(), payload.size()) != PacketResult::Success)
217         return false;
218 
219     OnRunPacketSent(true);
220 
221     // wait for the response to the vCont
222     if (ReadPacket(response, UINT32_MAX, false) == PacketResult::Success)
223     {
224         if (response.IsOKResponse())
225             return true;
226     }
227 
228     return false;
229 }
230 bool
231 GDBRemoteClientBase::ShouldStop(const UnixSignals &signals, StringExtractorGDBRemote &response)
232 {
233     std::lock_guard<std::mutex> lock(m_mutex);
234 
235     if (m_async_count == 0)
236         return true; // We were not interrupted. The process stopped on its own.
237 
238     // Older debugserver stubs (before April 2016) can return two
239     // stop-reply packets in response to a ^C packet.
240     // Additionally, all debugservers still return two stop replies if
241     // the inferior stops due to some other reason before the remote
242     // stub manages to interrupt it. We need to wait for this
243     // additional packet to make sure the packet sequence does not get
244     // skewed.
245     StringExtractorGDBRemote extra_stop_reply_packet;
246     uint32_t timeout_usec = 100000; // 100ms
247     ReadPacket(extra_stop_reply_packet, timeout_usec, false);
248 
249     // Interrupting is typically done using SIGSTOP or SIGINT, so if
250     // the process stops with some other signal, we definitely want to
251     // stop.
252     const uint8_t signo = response.GetHexU8(UINT8_MAX);
253     if (signo != signals.GetSignalNumberFromName("SIGSTOP") && signo != signals.GetSignalNumberFromName("SIGINT"))
254         return true;
255 
256     // We probably only stopped to perform some async processing, so continue after that is done.
257     // TODO: This is not 100% correct, as the process may have been stopped with SIGINT or SIGSTOP
258     // that was not caused by us (e.g. raise(SIGINT)). This will normally cause a stop, but if it's
259     // done concurrently with a async interrupt, that stop will get eaten (llvm.org/pr20231).
260     return false;
261 }
262 
263 void
264 GDBRemoteClientBase::OnRunPacketSent(bool first)
265 {
266     if (first)
267         BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
268 }
269 
270 ///////////////////////////////////////
271 // GDBRemoteClientBase::ContinueLock //
272 ///////////////////////////////////////
273 
274 GDBRemoteClientBase::ContinueLock::ContinueLock(GDBRemoteClientBase &comm) : m_comm(comm), m_acquired(false)
275 {
276     lock();
277 }
278 
279 GDBRemoteClientBase::ContinueLock::~ContinueLock()
280 {
281     if (m_acquired)
282         unlock();
283 }
284 
285 void
286 GDBRemoteClientBase::ContinueLock::unlock()
287 {
288     lldbassert(m_acquired);
289     {
290         std::unique_lock<std::mutex> lock(m_comm.m_mutex);
291         m_comm.m_is_running = false;
292     }
293     m_comm.m_cv.notify_all();
294     m_acquired = false;
295 }
296 
297 GDBRemoteClientBase::ContinueLock::LockResult
298 GDBRemoteClientBase::ContinueLock::lock()
299 {
300     Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
301     if (log)
302         log->Printf("GDBRemoteClientBase::ContinueLock::%s() resuming with %s", __FUNCTION__,
303                     m_comm.m_continue_packet.c_str());
304 
305     lldbassert(!m_acquired);
306     std::unique_lock<std::mutex> lock(m_comm.m_mutex);
307     m_comm.m_cv.wait(lock, [this] { return m_comm.m_async_count == 0; });
308     if (m_comm.m_should_stop)
309     {
310         m_comm.m_should_stop = false;
311         return LockResult::Cancelled;
312     }
313     if (m_comm.SendPacketNoLock(m_comm.m_continue_packet.data(), m_comm.m_continue_packet.size()) !=
314         PacketResult::Success)
315         return LockResult::Failed;
316 
317     lldbassert(!m_comm.m_is_running);
318     m_comm.m_is_running = true;
319     m_acquired = true;
320     return LockResult::Success;
321 }
322 
323 ///////////////////////////////
324 // GDBRemoteClientBase::Lock //
325 ///////////////////////////////
326 
327 GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, bool interrupt)
328     : m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm), m_acquired(false), m_did_interrupt(false)
329 {
330     SyncWithContinueThread(interrupt);
331     if (m_acquired)
332         m_async_lock.lock();
333 }
334 
335 void
336 GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt)
337 {
338     Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
339     std::unique_lock<std::mutex> lock(m_comm.m_mutex);
340     if (m_comm.m_is_running && !interrupt)
341         return; // We were asked to avoid interrupting the sender. Lock is not acquired.
342 
343     ++m_comm.m_async_count;
344     if (m_comm.m_is_running)
345     {
346         if (m_comm.m_async_count == 1)
347         {
348             // The sender has sent the continue packet and we are the first async packet. Let's interrupt it.
349             const char ctrl_c = '\x03';
350             ConnectionStatus status = eConnectionStatusSuccess;
351             size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, NULL);
352             if (bytes_written == 0)
353             {
354                 --m_comm.m_async_count;
355                 if (log)
356                     log->Printf("GDBRemoteClientBase::Lock::Lock failed to send interrupt packet");
357                 return;
358             }
359             if (log)
360                 log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03");
361             m_comm.m_interrupt_time = std::chrono::steady_clock::now();
362         }
363         m_comm.m_cv.wait(lock, [this] { return m_comm.m_is_running == false; });
364         m_did_interrupt = true;
365     }
366     m_acquired = true;
367 }
368 
369 GDBRemoteClientBase::Lock::~Lock()
370 {
371     if (!m_acquired)
372         return;
373     {
374         std::unique_lock<std::mutex> lock(m_comm.m_mutex);
375         --m_comm.m_async_count;
376     }
377     m_comm.m_cv.notify_one();
378 }
379