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