blob: 1e20a090161d8929497b9fd334550efc7c80bbd5 [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;
Pavel Labath1eff73c2016-11-24 10:54:49 +000023using namespace std::chrono;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000024
Pavel Labath1eff73c2016-11-24 10:54:49 +000025static const seconds kInterruptTimeout(5);
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000026
27/////////////////////////
28// GDBRemoteClientBase //
29/////////////////////////
30
31GDBRemoteClientBase::ContinueDelegate::~ContinueDelegate() = default;
32
Kate Stoneb9c1b512016-09-06 20:57:50 +000033GDBRemoteClientBase::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) {}
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000037
Kate Stoneb9c1b512016-09-06 20:57:50 +000038StateType 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();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000043
Kate Stoneb9c1b512016-09-06 20:57:50 +000044 {
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000045 std::lock_guard<std::mutex> lock(m_mutex);
Kate Stoneb9c1b512016-09-06 20:57:50 +000046 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);
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000053
Kate Stoneb9c1b512016-09-06 20:57:50 +000054 for (;;) {
Pavel Labath1eff73c2016-11-24 10:54:49 +000055 PacketResult read_result = ReadPacket(response, kInterruptTimeout, false);
Kate Stoneb9c1b512016-09-06 20:57:50 +000056 switch (read_result) {
57 case PacketResult::ErrorReplyTimeout: {
58 std::lock_guard<std::mutex> lock(m_mutex);
59 if (m_async_count == 0)
60 continue;
Pavel Labath1eff73c2016-11-24 10:54:49 +000061 if (steady_clock::now() >= m_interrupt_time + kInterruptTimeout)
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 return eStateInvalid;
63 }
64 case PacketResult::Success:
65 break;
66 default:
67 if (log)
68 log->Printf("GDBRemoteClientBase::%s () ReadPacket(...) => false",
69 __FUNCTION__);
70 return eStateInvalid;
71 }
72 if (response.Empty())
73 return eStateInvalid;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000074
Kate Stoneb9c1b512016-09-06 20:57:50 +000075 const char stop_type = response.GetChar();
76 if (log)
77 log->Printf("GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__,
78 response.GetStringRef().c_str());
Pavel Labath8c1b6bd2016-08-09 12:04:46 +000079
Kate Stoneb9c1b512016-09-06 20:57:50 +000080 switch (stop_type) {
81 case 'W':
82 case 'X':
83 return eStateExited;
84 case 'E':
85 // ERROR
86 return eStateInvalid;
87 default:
88 if (log)
89 log->Printf("GDBRemoteClientBase::%s () unrecognized async packet",
90 __FUNCTION__);
91 return eStateInvalid;
92 case 'O': {
93 std::string inferior_stdout;
94 response.GetHexByteString(inferior_stdout);
95 delegate.HandleAsyncStdout(inferior_stdout);
96 break;
97 }
98 case 'A':
99 delegate.HandleAsyncMisc(
100 llvm::StringRef(response.GetStringRef()).substr(1));
101 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000102 case 'J':
Todd Fialafcdb1af2016-09-10 00:06:29 +0000103 delegate.HandleAsyncStructuredDataPacket(response.GetStringRef());
104 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105 case 'T':
106 case 'S':
107 // Do this with the continue lock held.
108 const bool should_stop = ShouldStop(signals, response);
109 response.SetFilePos(0);
110
111 // The packet we should resume with. In the future
112 // we should check our thread list and "do the right thing"
113 // for new threads that show up while we stop and run async
114 // packets. Setting the packet to 'c' to continue all threads
115 // is the right thing to do 99.99% of the time because if a
116 // thread was single stepping, and we sent an interrupt, we
117 // will notice above that we didn't stop due to an interrupt
118 // but stopped due to stepping and we would _not_ continue.
119 // This packet may get modified by the async actions (e.g. to send a
120 // signal).
121 m_continue_packet = 'c';
122 cont_lock.unlock();
123
124 delegate.HandleStopReply();
125 if (should_stop)
126 return eStateStopped;
127
128 switch (cont_lock.lock()) {
129 case ContinueLock::LockResult::Success:
130 break;
131 case ContinueLock::LockResult::Failed:
132 return eStateInvalid;
133 case ContinueLock::LockResult::Cancelled:
134 return eStateStopped;
135 }
136 OnRunPacketSent(false);
137 break;
138 }
139 }
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000140}
141
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142bool GDBRemoteClientBase::SendAsyncSignal(int signo) {
143 Lock lock(*this, true);
144 if (!lock || !lock.DidInterrupt())
145 return false;
146
147 m_continue_packet = 'C';
148 m_continue_packet += llvm::hexdigit((signo / 16) % 16);
149 m_continue_packet += llvm::hexdigit(signo % 16);
150 return true;
151}
152
153bool GDBRemoteClientBase::Interrupt() {
154 Lock lock(*this, true);
155 if (!lock.DidInterrupt())
156 return false;
157 m_should_stop = true;
158 return true;
159}
160GDBRemoteCommunication::PacketResult
161GDBRemoteClientBase::SendPacketAndWaitForResponse(
162 llvm::StringRef payload, StringExtractorGDBRemote &response,
163 bool send_async) {
164 Lock lock(*this, send_async);
165 if (!lock) {
166 if (Log *log =
167 ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
168 log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending "
169 "packet '%.*s' (send_async=%d)",
170 __FUNCTION__, int(payload.size()), payload.data(),
171 send_async);
172 return PacketResult::ErrorSendFailed;
173 }
174
175 return SendPacketAndWaitForResponseNoLock(payload, response);
176}
177
178GDBRemoteCommunication::PacketResult
179GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
180 llvm::StringRef payload, StringExtractorGDBRemote &response) {
181 PacketResult packet_result = SendPacketNoLock(payload);
182 if (packet_result != PacketResult::Success)
183 return packet_result;
184
185 const size_t max_response_retries = 3;
186 for (size_t i = 0; i < max_response_retries; ++i) {
Pavel Labath1eff73c2016-11-24 10:54:49 +0000187 packet_result = ReadPacket(response, GetPacketTimeout(), true);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 // Make sure we received a response
189 if (packet_result != PacketResult::Success)
190 return packet_result;
191 // Make sure our response is valid for the payload that was sent
192 if (response.ValidateResponse())
193 return packet_result;
194 // Response says it wasn't valid
195 Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
196 if (log)
197 log->Printf(
198 "error: packet with payload \"%.*s\" got invalid response \"%s\": %s",
199 int(payload.size()), payload.data(), response.GetStringRef().c_str(),
200 (i == (max_response_retries - 1))
201 ? "using invalid response and giving up"
202 : "ignoring response and waiting for another");
203 }
204 return packet_result;
205}
206
207bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload,
208 StringExtractorGDBRemote &response) {
209 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
210 if (log)
211 log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
212
213 // we want to lock down packet sending while we continue
214 Lock lock(*this, true);
215
216 if (log)
217 log->Printf(
218 "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
219 __FUNCTION__, int(payload.size()), payload.data());
220
221 if (SendPacketNoLock(payload) != PacketResult::Success)
222 return false;
223
224 OnRunPacketSent(true);
225
226 // wait for the response to the vCont
Pavel Labath1eff73c2016-11-24 10:54:49 +0000227 if (ReadPacket(response, llvm::None, false) == PacketResult::Success) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000228 if (response.IsOKResponse())
229 return true;
230 }
231
232 return false;
233}
234bool GDBRemoteClientBase::ShouldStop(const UnixSignals &signals,
235 StringExtractorGDBRemote &response) {
236 std::lock_guard<std::mutex> lock(m_mutex);
237
238 if (m_async_count == 0)
239 return true; // We were not interrupted. The process stopped on its own.
240
241 // Older debugserver stubs (before April 2016) can return two
242 // stop-reply packets in response to a ^C packet.
243 // Additionally, all debugservers still return two stop replies if
244 // the inferior stops due to some other reason before the remote
245 // stub manages to interrupt it. We need to wait for this
246 // additional packet to make sure the packet sequence does not get
247 // skewed.
248 StringExtractorGDBRemote extra_stop_reply_packet;
Pavel Labath1eff73c2016-11-24 10:54:49 +0000249 ReadPacket(extra_stop_reply_packet, milliseconds(100), false);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000250
251 // Interrupting is typically done using SIGSTOP or SIGINT, so if
252 // the process stops with some other signal, we definitely want to
253 // stop.
254 const uint8_t signo = response.GetHexU8(UINT8_MAX);
255 if (signo != signals.GetSignalNumberFromName("SIGSTOP") &&
256 signo != signals.GetSignalNumberFromName("SIGINT"))
257 return true;
258
259 // We probably only stopped to perform some async processing, so continue
260 // after that is done.
261 // TODO: This is not 100% correct, as the process may have been stopped with
Pavel Labath1eff73c2016-11-24 10:54:49 +0000262 // SIGINT or SIGSTOP that was not caused by us (e.g. raise(SIGINT)). This will
263 // normally cause a stop, but if it's done concurrently with a async
264 // interrupt, that stop will get eaten (llvm.org/pr20231).
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265 return false;
266}
267
268void GDBRemoteClientBase::OnRunPacketSent(bool first) {
269 if (first)
270 BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000271}
272
273///////////////////////////////////////
274// GDBRemoteClientBase::ContinueLock //
275///////////////////////////////////////
276
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277GDBRemoteClientBase::ContinueLock::ContinueLock(GDBRemoteClientBase &comm)
278 : m_comm(comm), m_acquired(false) {
279 lock();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000280}
281
Kate Stoneb9c1b512016-09-06 20:57:50 +0000282GDBRemoteClientBase::ContinueLock::~ContinueLock() {
283 if (m_acquired)
284 unlock();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000285}
286
Kate Stoneb9c1b512016-09-06 20:57:50 +0000287void GDBRemoteClientBase::ContinueLock::unlock() {
288 lldbassert(m_acquired);
289 {
290 std::unique_lock<std::mutex> lock(m_comm.m_mutex);
291 m_comm.m_is_running = false;
292 }
293 m_comm.m_cv.notify_all();
294 m_acquired = false;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000295}
296
297GDBRemoteClientBase::ContinueLock::LockResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000298GDBRemoteClientBase::ContinueLock::lock() {
299 Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
300 if (log)
301 log->Printf("GDBRemoteClientBase::ContinueLock::%s() resuming with %s",
302 __FUNCTION__, m_comm.m_continue_packet.c_str());
303
304 lldbassert(!m_acquired);
305 std::unique_lock<std::mutex> lock(m_comm.m_mutex);
306 m_comm.m_cv.wait(lock, [this] { return m_comm.m_async_count == 0; });
307 if (m_comm.m_should_stop) {
308 m_comm.m_should_stop = false;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000309 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000310 log->Printf("GDBRemoteClientBase::ContinueLock::%s() cancelled",
311 __FUNCTION__);
312 return LockResult::Cancelled;
313 }
314 if (m_comm.SendPacketNoLock(m_comm.m_continue_packet) !=
315 PacketResult::Success)
316 return LockResult::Failed;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000317
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318 lldbassert(!m_comm.m_is_running);
319 m_comm.m_is_running = true;
320 m_acquired = true;
321 return LockResult::Success;
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000322}
323
324///////////////////////////////
325// GDBRemoteClientBase::Lock //
326///////////////////////////////
327
328GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, bool interrupt)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000329 : m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm),
330 m_acquired(false), m_did_interrupt(false) {
331 SyncWithContinueThread(interrupt);
332 if (m_acquired)
333 m_async_lock.lock();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000334}
335
Kate Stoneb9c1b512016-09-06 20:57:50 +0000336void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
337 Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
338 std::unique_lock<std::mutex> lock(m_comm.m_mutex);
339 if (m_comm.m_is_running && !interrupt)
340 return; // We were asked to avoid interrupting the sender. Lock is not
341 // acquired.
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000342
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343 ++m_comm.m_async_count;
344 if (m_comm.m_is_running) {
345 if (m_comm.m_async_count == 1) {
346 // The sender has sent the continue packet and we are the first async
347 // packet. Let's interrupt it.
348 const char ctrl_c = '\x03';
349 ConnectionStatus status = eConnectionStatusSuccess;
350 size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, NULL);
351 if (bytes_written == 0) {
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000352 --m_comm.m_async_count;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353 if (log)
354 log->Printf("GDBRemoteClientBase::Lock::Lock failed to send "
355 "interrupt packet");
356 return;
357 }
358 if (log)
359 log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03");
Pavel Labath1eff73c2016-11-24 10:54:49 +0000360 m_comm.m_interrupt_time = steady_clock::now();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000361 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000362 m_comm.m_cv.wait(lock, [this] { return m_comm.m_is_running == false; });
363 m_did_interrupt = true;
364 }
365 m_acquired = true;
366}
367
368GDBRemoteClientBase::Lock::~Lock() {
369 if (!m_acquired)
370 return;
371 {
372 std::unique_lock<std::mutex> lock(m_comm.m_mutex);
373 --m_comm.m_async_count;
374 }
375 m_comm.m_cv.notify_one();
Pavel Labath8c1b6bd2016-08-09 12:04:46 +0000376}