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