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