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