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