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