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