blob: 853e201249bb65cf8d3cc90a064ba46572ba0408 [file] [log] [blame]
Pavel Labath8c1b6bd2016-08-09 12:04:46 +00001//===-- 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
Todd Fiala75930012016-08-19 04:21:48 +000014#include "lldb/Target/Process.h"
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000015#include "lldb/Target/UnixSignals.h"
16#include "lldb/Utility/LLDBAssert.h"
17
18#include "ProcessGDBRemoteLog.h"
19
20using namespace lldb;
21using namespace lldb_private;
22using namespace lldb_private::process_gdb_remote;
23
24static const std::chrono::seconds kInterruptTimeout(5);
25
26/////////////////////////
27// GDBRemoteClientBase //
28/////////////////////////
29
30GDBRemoteClientBase::ContinueDelegate::~ContinueDelegate() = default;
31
Kate Stoneb9c1b512016-09-06 20:57:50 +000032GDBRemoteClientBase::GDBRemoteClientBase(const char *comm_name,
33 const char *listener_name)
34 : GDBRemoteCommunication(comm_name, listener_name), m_async_count(0),
35 m_is_running(false), m_should_stop(false) {}
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000036
Kate Stoneb9c1b512016-09-06 20:57:50 +000037StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
38 ContinueDelegate &delegate, const UnixSignals &signals,
39 llvm::StringRef payload, StringExtractorGDBRemote &response) {
40 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
41 response.Clear();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000042
Kate Stoneb9c1b512016-09-06 20:57:50 +000043 {
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000044 std::lock_guard<std::mutex> lock(m_mutex);
Kate Stoneb9c1b512016-09-06 20:57:50 +000045 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);
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000052
Kate Stoneb9c1b512016-09-06 20:57:50 +000053 for (;;) {
54 PacketResult read_result = ReadPacket(
55 response,
56 std::chrono::duration_cast<std::chrono::microseconds>(kInterruptTimeout)
57 .count(),
58 false);
59 switch (read_result) {
60 case PacketResult::ErrorReplyTimeout: {
61 std::lock_guard<std::mutex> lock(m_mutex);
62 if (m_async_count == 0)
63 continue;
64 if (std::chrono::steady_clock::now() >=
65 m_interrupt_time + kInterruptTimeout)
66 return eStateInvalid;
67 }
68 case PacketResult::Success:
69 break;
70 default:
71 if (log)
72 log->Printf("GDBRemoteClientBase::%s () ReadPacket(...) => false",
73 __FUNCTION__);
74 return eStateInvalid;
75 }
76 if (response.Empty())
77 return eStateInvalid;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000078
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 const char stop_type = response.GetChar();
80 if (log)
81 log->Printf("GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__,
82 response.GetStringRef().c_str());
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000083
Kate Stoneb9c1b512016-09-06 20:57:50 +000084 switch (stop_type) {
85 case 'W':
86 case 'X':
87 return eStateExited;
88 case 'E':
89 // ERROR
90 return eStateInvalid;
91 default:
92 if (log)
93 log->Printf("GDBRemoteClientBase::%s () unrecognized async packet",
94 __FUNCTION__);
95 return eStateInvalid;
96 case 'O': {
97 std::string inferior_stdout;
98 response.GetHexByteString(inferior_stdout);
99 delegate.HandleAsyncStdout(inferior_stdout);
100 break;
101 }
102 case 'A':
103 delegate.HandleAsyncMisc(
104 llvm::StringRef(response.GetStringRef()).substr(1));
105 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106 case 'J':
Todd Fialafcdb1af2016-09-10 00:06:29 +0000107 delegate.HandleAsyncStructuredDataPacket(response.GetStringRef());
108 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 case 'T':
110 case 'S':
111 // Do this with the continue lock held.
112 const bool should_stop = ShouldStop(signals, response);
113 response.SetFilePos(0);
114
115 // The packet we should resume with. In the future
116 // we should check our thread list and "do the right thing"
117 // for new threads that show up while we stop and run async
118 // packets. Setting the packet to 'c' to continue all threads
119 // is the right thing to do 99.99% of the time because if a
120 // thread was single stepping, and we sent an interrupt, we
121 // will notice above that we didn't stop due to an interrupt
122 // but stopped due to stepping and we would _not_ continue.
123 // This packet may get modified by the async actions (e.g. to send a
124 // signal).
125 m_continue_packet = 'c';
126 cont_lock.unlock();
127
128 delegate.HandleStopReply();
129 if (should_stop)
130 return eStateStopped;
131
132 switch (cont_lock.lock()) {
133 case ContinueLock::LockResult::Success:
134 break;
135 case ContinueLock::LockResult::Failed:
136 return eStateInvalid;
137 case ContinueLock::LockResult::Cancelled:
138 return eStateStopped;
139 }
140 OnRunPacketSent(false);
141 break;
142 }
143 }
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000144}
145
Kate Stoneb9c1b512016-09-06 20:57:50 +0000146bool GDBRemoteClientBase::SendAsyncSignal(int signo) {
147 Lock lock(*this, true);
148 if (!lock || !lock.DidInterrupt())
149 return false;
150
151 m_continue_packet = 'C';
152 m_continue_packet += llvm::hexdigit((signo / 16) % 16);
153 m_continue_packet += llvm::hexdigit(signo % 16);
154 return true;
155}
156
157bool GDBRemoteClientBase::Interrupt() {
158 Lock lock(*this, true);
159 if (!lock.DidInterrupt())
160 return false;
161 m_should_stop = true;
162 return true;
163}
164GDBRemoteCommunication::PacketResult
165GDBRemoteClientBase::SendPacketAndWaitForResponse(
166 llvm::StringRef payload, StringExtractorGDBRemote &response,
167 bool send_async) {
168 Lock lock(*this, send_async);
169 if (!lock) {
170 if (Log *log =
171 ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
172 log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending "
173 "packet '%.*s' (send_async=%d)",
174 __FUNCTION__, int(payload.size()), payload.data(),
175 send_async);
176 return PacketResult::ErrorSendFailed;
177 }
178
179 return SendPacketAndWaitForResponseNoLock(payload, response);
180}
181
182GDBRemoteCommunication::PacketResult
183GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
184 llvm::StringRef payload, StringExtractorGDBRemote &response) {
185 PacketResult packet_result = SendPacketNoLock(payload);
186 if (packet_result != PacketResult::Success)
187 return packet_result;
188
189 const size_t max_response_retries = 3;
190 for (size_t i = 0; i < max_response_retries; ++i) {
191 packet_result =
192 ReadPacket(response, GetPacketTimeoutInMicroSeconds(), true);
193 // Make sure we received a response
194 if (packet_result != PacketResult::Success)
195 return packet_result;
196 // Make sure our response is valid for the payload that was sent
197 if (response.ValidateResponse())
198 return packet_result;
199 // Response says it wasn't valid
200 Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
201 if (log)
202 log->Printf(
203 "error: packet with payload \"%.*s\" got invalid response \"%s\": %s",
204 int(payload.size()), payload.data(), response.GetStringRef().c_str(),
205 (i == (max_response_retries - 1))
206 ? "using invalid response and giving up"
207 : "ignoring response and waiting for another");
208 }
209 return packet_result;
210}
211
212bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload,
213 StringExtractorGDBRemote &response) {
214 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
215 if (log)
216 log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
217
218 // we want to lock down packet sending while we continue
219 Lock lock(*this, true);
220
221 if (log)
222 log->Printf(
223 "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
224 __FUNCTION__, int(payload.size()), payload.data());
225
226 if (SendPacketNoLock(payload) != PacketResult::Success)
227 return false;
228
229 OnRunPacketSent(true);
230
231 // wait for the response to the vCont
232 if (ReadPacket(response, UINT32_MAX, false) == PacketResult::Success) {
233 if (response.IsOKResponse())
234 return true;
235 }
236
237 return false;
238}
239bool GDBRemoteClientBase::ShouldStop(const UnixSignals &signals,
240 StringExtractorGDBRemote &response) {
241 std::lock_guard<std::mutex> lock(m_mutex);
242
243 if (m_async_count == 0)
244 return true; // We were not interrupted. The process stopped on its own.
245
246 // Older debugserver stubs (before April 2016) can return two
247 // stop-reply packets in response to a ^C packet.
248 // Additionally, all debugservers still return two stop replies if
249 // the inferior stops due to some other reason before the remote
250 // stub manages to interrupt it. We need to wait for this
251 // additional packet to make sure the packet sequence does not get
252 // skewed.
253 StringExtractorGDBRemote extra_stop_reply_packet;
254 uint32_t timeout_usec = 100000; // 100ms
255 ReadPacket(extra_stop_reply_packet, timeout_usec, false);
256
257 // Interrupting is typically done using SIGSTOP or SIGINT, so if
258 // the process stops with some other signal, we definitely want to
259 // stop.
260 const uint8_t signo = response.GetHexU8(UINT8_MAX);
261 if (signo != signals.GetSignalNumberFromName("SIGSTOP") &&
262 signo != signals.GetSignalNumberFromName("SIGINT"))
263 return true;
264
265 // We probably only stopped to perform some async processing, so continue
266 // after that is done.
267 // TODO: This is not 100% correct, as the process may have been stopped with
268 // SIGINT or SIGSTOP
269 // that was not caused by us (e.g. raise(SIGINT)). This will normally cause a
270 // stop, but if it's
271 // done concurrently with a async interrupt, that stop will get eaten
272 // (llvm.org/pr20231).
273 return false;
274}
275
276void GDBRemoteClientBase::OnRunPacketSent(bool first) {
277 if (first)
278 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000279}
280
281///////////////////////////////////////
282// GDBRemoteClientBase::ContinueLock //
283///////////////////////////////////////
284
Kate Stoneb9c1b512016-09-06 20:57:50 +0000285GDBRemoteClientBase::ContinueLock::ContinueLock(GDBRemoteClientBase &comm)
286 : m_comm(comm), m_acquired(false) {
287 lock();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000288}
289
Kate Stoneb9c1b512016-09-06 20:57:50 +0000290GDBRemoteClientBase::ContinueLock::~ContinueLock() {
291 if (m_acquired)
292 unlock();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000293}
294
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295void GDBRemoteClientBase::ContinueLock::unlock() {
296 lldbassert(m_acquired);
297 {
298 std::unique_lock<std::mutex> lock(m_comm.m_mutex);
299 m_comm.m_is_running = false;
300 }
301 m_comm.m_cv.notify_all();
302 m_acquired = false;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000303}
304
305GDBRemoteClientBase::ContinueLock::LockResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000306GDBRemoteClientBase::ContinueLock::lock() {
307 Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
308 if (log)
309 log->Printf("GDBRemoteClientBase::ContinueLock::%s() resuming with %s",
310 __FUNCTION__, m_comm.m_continue_packet.c_str());
311
312 lldbassert(!m_acquired);
313 std::unique_lock<std::mutex> lock(m_comm.m_mutex);
314 m_comm.m_cv.wait(lock, [this] { return m_comm.m_async_count == 0; });
315 if (m_comm.m_should_stop) {
316 m_comm.m_should_stop = false;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000317 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318 log->Printf("GDBRemoteClientBase::ContinueLock::%s() cancelled",
319 __FUNCTION__);
320 return LockResult::Cancelled;
321 }
322 if (m_comm.SendPacketNoLock(m_comm.m_continue_packet) !=
323 PacketResult::Success)
324 return LockResult::Failed;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000325
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326 lldbassert(!m_comm.m_is_running);
327 m_comm.m_is_running = true;
328 m_acquired = true;
329 return LockResult::Success;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000330}
331
332///////////////////////////////
333// GDBRemoteClientBase::Lock //
334///////////////////////////////
335
336GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, bool interrupt)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000337 : m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm),
338 m_acquired(false), m_did_interrupt(false) {
339 SyncWithContinueThread(interrupt);
340 if (m_acquired)
341 m_async_lock.lock();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000342}
343
Kate Stoneb9c1b512016-09-06 20:57:50 +0000344void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
345 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
346 std::unique_lock<std::mutex> lock(m_comm.m_mutex);
347 if (m_comm.m_is_running && !interrupt)
348 return; // We were asked to avoid interrupting the sender. Lock is not
349 // acquired.
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000350
Kate Stoneb9c1b512016-09-06 20:57:50 +0000351 ++m_comm.m_async_count;
352 if (m_comm.m_is_running) {
353 if (m_comm.m_async_count == 1) {
354 // The sender has sent the continue packet and we are the first async
355 // packet. Let's interrupt it.
356 const char ctrl_c = '\x03';
357 ConnectionStatus status = eConnectionStatusSuccess;
358 size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, NULL);
359 if (bytes_written == 0) {
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000360 --m_comm.m_async_count;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361 if (log)
362 log->Printf("GDBRemoteClientBase::Lock::Lock failed to send "
363 "interrupt packet");
364 return;
365 }
366 if (log)
367 log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03");
368 m_comm.m_interrupt_time = std::chrono::steady_clock::now();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000369 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000370 m_comm.m_cv.wait(lock, [this] { return m_comm.m_is_running == false; });
371 m_did_interrupt = true;
372 }
373 m_acquired = true;
374}
375
376GDBRemoteClientBase::Lock::~Lock() {
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();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000384}