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