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