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