Skip to content

Commit 7207597

Browse files
author
git apple-llvm automerger
committed
Merge commit '907947e499b1' from swift/release/5.5 into swift/main
2 parents 58eaedb + 907947e commit 7207597

File tree

17 files changed

+393
-267
lines changed

17 files changed

+393
-267
lines changed

lldb/include/lldb/Target/Process.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class ProcessProperties : public Properties {
9393
bool GetWarningsUnsupportedLanguage() const;
9494
bool GetStopOnExec() const;
9595
std::chrono::seconds GetUtilityExpressionTimeout() const;
96+
std::chrono::seconds GetInterruptTimeout() const;
9697
bool GetOSPluginReportsAllThreads() const;
9798
void SetOSPluginReportsAllThreads(bool does_report);
9899
bool GetSteppingRunsAllThreads() const;

lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,8 +736,8 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
736736
m_remote_signals_sp = UnixSignals::Create(GetRemoteSystemArchitecture());
737737

738738
StringExtractorGDBRemote response;
739-
auto result = m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo",
740-
response, false);
739+
auto result =
740+
m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo", response);
741741

742742
if (result != decltype(result)::Success ||
743743
response.GetResponseType() != response.eResponse)

lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ using namespace lldb_private;
2020
using namespace lldb_private::process_gdb_remote;
2121
using namespace std::chrono;
2222

23-
static const seconds kInterruptTimeout(5);
23+
// When we've sent a continue packet and are waiting for the target to stop,
24+
// we wake up the wait with this interval to make sure the stub hasn't gone
25+
// away while we were waiting.
26+
static const seconds kWakeupInterval(5);
2427

2528
/////////////////////////
2629
// GDBRemoteClientBase //
@@ -35,7 +38,8 @@ GDBRemoteClientBase::GDBRemoteClientBase(const char *comm_name,
3538

3639
StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
3740
ContinueDelegate &delegate, const UnixSignals &signals,
38-
llvm::StringRef payload, StringExtractorGDBRemote &response) {
41+
llvm::StringRef payload, std::chrono::seconds interrupt_timeout,
42+
StringExtractorGDBRemote &response) {
3943
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
4044
response.Clear();
4145

@@ -48,16 +52,34 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
4852
if (!cont_lock)
4953
return eStateInvalid;
5054
OnRunPacketSent(true);
51-
55+
// The main ReadPacket loop wakes up at computed_timeout intervals, just to
56+
// check that the connection hasn't dropped. When we wake up we also check
57+
// whether there is an interrupt request that has reached its endpoint.
58+
// If we want a shorter interrupt timeout that kWakeupInterval, we need to
59+
// choose the shorter interval for the wake up as well.
60+
std::chrono::seconds computed_timeout = std::min(interrupt_timeout,
61+
kWakeupInterval);
5262
for (;;) {
53-
PacketResult read_result = ReadPacket(response, kInterruptTimeout, false);
63+
PacketResult read_result = ReadPacket(response, computed_timeout, false);
5464
switch (read_result) {
5565
case PacketResult::ErrorReplyTimeout: {
5666
std::lock_guard<std::mutex> lock(m_mutex);
57-
if (m_async_count == 0)
67+
if (m_async_count == 0) {
5868
continue;
59-
if (steady_clock::now() >= m_interrupt_time + kInterruptTimeout)
69+
}
70+
auto cur_time = steady_clock::now();
71+
if (cur_time >= m_interrupt_endpoint)
6072
return eStateInvalid;
73+
else {
74+
// We woke up and found an interrupt is in flight, but we haven't
75+
// exceeded the interrupt wait time. So reset the wait time to the
76+
// time left till the interrupt timeout. But don't wait longer
77+
// than our wakeup timeout.
78+
auto new_wait = m_interrupt_endpoint - cur_time;
79+
computed_timeout = std::min(kWakeupInterval,
80+
std::chrono::duration_cast<std::chrono::seconds>(new_wait));
81+
continue;
82+
}
6183
break;
6284
}
6385
case PacketResult::Success:
@@ -133,8 +155,9 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
133155
}
134156
}
135157

136-
bool GDBRemoteClientBase::SendAsyncSignal(int signo) {
137-
Lock lock(*this, true);
158+
bool GDBRemoteClientBase::SendAsyncSignal(
159+
int signo, std::chrono::seconds interrupt_timeout) {
160+
Lock lock(*this, interrupt_timeout);
138161
if (!lock || !lock.DidInterrupt())
139162
return false;
140163

@@ -144,25 +167,26 @@ bool GDBRemoteClientBase::SendAsyncSignal(int signo) {
144167
return true;
145168
}
146169

147-
bool GDBRemoteClientBase::Interrupt() {
148-
Lock lock(*this, true);
170+
bool GDBRemoteClientBase::Interrupt(std::chrono::seconds interrupt_timeout) {
171+
Lock lock(*this, interrupt_timeout);
149172
if (!lock.DidInterrupt())
150173
return false;
151174
m_should_stop = true;
152175
return true;
153176
}
177+
154178
GDBRemoteCommunication::PacketResult
155179
GDBRemoteClientBase::SendPacketAndWaitForResponse(
156180
llvm::StringRef payload, StringExtractorGDBRemote &response,
157-
bool send_async) {
158-
Lock lock(*this, send_async);
181+
std::chrono::seconds interrupt_timeout) {
182+
Lock lock(*this, interrupt_timeout);
159183
if (!lock) {
160184
if (Log *log =
161185
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
162186
LLDB_LOGF(log,
163187
"GDBRemoteClientBase::%s failed to get mutex, not sending "
164-
"packet '%.*s' (send_async=%d)",
165-
__FUNCTION__, int(payload.size()), payload.data(), send_async);
188+
"packet '%.*s'",
189+
__FUNCTION__, int(payload.size()), payload.data());
166190
return PacketResult::ErrorSendFailed;
167191
}
168192

@@ -172,16 +196,16 @@ GDBRemoteClientBase::SendPacketAndWaitForResponse(
172196
GDBRemoteCommunication::PacketResult
173197
GDBRemoteClientBase::SendPacketAndReceiveResponseWithOutputSupport(
174198
llvm::StringRef payload, StringExtractorGDBRemote &response,
175-
bool send_async,
199+
std::chrono::seconds interrupt_timeout,
176200
llvm::function_ref<void(llvm::StringRef)> output_callback) {
177-
Lock lock(*this, send_async);
201+
Lock lock(*this, interrupt_timeout);
178202
if (!lock) {
179203
if (Log *log =
180204
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
181205
LLDB_LOGF(log,
182206
"GDBRemoteClientBase::%s failed to get mutex, not sending "
183-
"packet '%.*s' (send_async=%d)",
184-
__FUNCTION__, int(payload.size()), payload.data(), send_async);
207+
"packet '%.*s'",
208+
__FUNCTION__, int(payload.size()), payload.data());
185209
return PacketResult::ErrorSendFailed;
186210
}
187211

@@ -222,13 +246,14 @@ GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
222246
return packet_result;
223247
}
224248

225-
bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload,
226-
StringExtractorGDBRemote &response) {
249+
bool GDBRemoteClientBase::SendvContPacket(
250+
llvm::StringRef payload, std::chrono::seconds interrupt_timeout,
251+
StringExtractorGDBRemote &response) {
227252
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
228253
LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
229254

230255
// we want to lock down packet sending while we continue
231-
Lock lock(*this, true);
256+
Lock lock(*this, interrupt_timeout);
232257

233258
LLDB_LOGF(log,
234259
"GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
@@ -336,18 +361,20 @@ GDBRemoteClientBase::ContinueLock::lock() {
336361
// GDBRemoteClientBase::Lock //
337362
///////////////////////////////
338363

339-
GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, bool interrupt)
364+
GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm,
365+
std::chrono::seconds interrupt_timeout)
340366
: m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm),
341-
m_acquired(false), m_did_interrupt(false) {
342-
SyncWithContinueThread(interrupt);
367+
m_interrupt_timeout(interrupt_timeout), m_acquired(false),
368+
m_did_interrupt(false) {
369+
SyncWithContinueThread();
343370
if (m_acquired)
344371
m_async_lock.lock();
345372
}
346373

347-
void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
374+
void GDBRemoteClientBase::Lock::SyncWithContinueThread() {
348375
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
349376
std::unique_lock<std::mutex> lock(m_comm.m_mutex);
350-
if (m_comm.m_is_running && !interrupt)
377+
if (m_comm.m_is_running && m_interrupt_timeout == std::chrono::seconds(0))
351378
return; // We were asked to avoid interrupting the sender. Lock is not
352379
// acquired.
353380

@@ -365,9 +392,9 @@ void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
365392
"interrupt packet");
366393
return;
367394
}
395+
m_comm.m_interrupt_endpoint = steady_clock::now() + m_interrupt_timeout;
368396
if (log)
369397
log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03");
370-
m_comm.m_interrupt_time = steady_clock::now();
371398
}
372399
m_comm.m_cv.wait(lock, [this] { return !m_comm.m_is_running; });
373400
m_did_interrupt = true;

lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,29 +33,46 @@ class GDBRemoteClientBase : public GDBRemoteCommunication {
3333

3434
GDBRemoteClientBase(const char *comm_name, const char *listener_name);
3535

36-
bool SendAsyncSignal(int signo);
36+
bool SendAsyncSignal(int signo, std::chrono::seconds interrupt_timeout);
3737

38-
bool Interrupt();
38+
bool Interrupt(std::chrono::seconds interrupt_timeout);
3939

4040
lldb::StateType SendContinuePacketAndWaitForResponse(
4141
ContinueDelegate &delegate, const UnixSignals &signals,
42-
llvm::StringRef payload, StringExtractorGDBRemote &response);
43-
44-
PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload,
45-
StringExtractorGDBRemote &response,
46-
bool send_async);
42+
llvm::StringRef payload, std::chrono::seconds interrupt_timeout,
43+
StringExtractorGDBRemote &response);
44+
45+
// If interrupt_timeout == 0 seconds, don't interrupt the target.
46+
// Only send the packet if the target is stopped.
47+
// If you want to use this mode, use the fact that the timeout is defaulted
48+
// so it's clear from the call-site that you are using no-interrupt.
49+
// If it is non-zero, interrupt the target if it is running, and
50+
// send the packet.
51+
// It the target doesn't respond within the given timeout, it returns
52+
// ErrorReplyTimeout.
53+
PacketResult SendPacketAndWaitForResponse(
54+
llvm::StringRef payload, StringExtractorGDBRemote &response,
55+
std::chrono::seconds interrupt_timeout = std::chrono::seconds(0));
4756

4857
PacketResult SendPacketAndReceiveResponseWithOutputSupport(
4958
llvm::StringRef payload, StringExtractorGDBRemote &response,
50-
bool send_async,
59+
std::chrono::seconds interrupt_timeout,
5160
llvm::function_ref<void(llvm::StringRef)> output_callback);
5261

5362
bool SendvContPacket(llvm::StringRef payload,
63+
std::chrono::seconds interrupt_timeout,
5464
StringExtractorGDBRemote &response);
5565

5666
class Lock {
5767
public:
58-
Lock(GDBRemoteClientBase &comm, bool interrupt);
68+
// If interrupt_timeout == 0 seconds, only take the lock if the target is
69+
// not running. If using this option, use the fact that the
70+
// interrupt_timeout is defaulted so it will be obvious at the call site
71+
// that you are choosing this mode. If it is non-zero, interrupt the target
72+
// if it is running, waiting for the given timeout for the interrupt to
73+
// succeed.
74+
Lock(GDBRemoteClientBase &comm,
75+
std::chrono::seconds interrupt_timeout = std::chrono::seconds(0));
5976
~Lock();
6077

6178
explicit operator bool() { return m_acquired; }
@@ -67,10 +84,11 @@ class GDBRemoteClientBase : public GDBRemoteCommunication {
6784
private:
6885
std::unique_lock<std::recursive_mutex> m_async_lock;
6986
GDBRemoteClientBase &m_comm;
87+
std::chrono::seconds m_interrupt_timeout;
7088
bool m_acquired;
7189
bool m_did_interrupt;
7290

73-
void SyncWithContinueThread(bool interrupt);
91+
void SyncWithContinueThread();
7492
};
7593

7694
protected:
@@ -109,7 +127,7 @@ class GDBRemoteClientBase : public GDBRemoteCommunication {
109127

110128
/// When was the interrupt packet sent. Used to make sure we time out if the
111129
/// stub does not respond to interrupt requests.
112-
std::chrono::time_point<std::chrono::steady_clock> m_interrupt_time;
130+
std::chrono::time_point<std::chrono::steady_clock> m_interrupt_endpoint;
113131

114132
/// Number of threads interested in sending.
115133
uint32_t m_async_count;

0 commit comments

Comments
 (0)