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