Skip to content

Commit b55005e

Browse files
committed
Revert "Add an "interrupt timeout" to Process, and pipe that through the"
This reverts commit d82650f. This interrupt timeout seems to cause us to every so often miss a stop reply packet. Revert till I can figure out how that could happen.
1 parent 5ac1e20 commit b55005e

File tree

13 files changed

+266
-337
lines changed

13 files changed

+266
-337
lines changed

lldb/include/lldb/Target/Process.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ class ProcessProperties : public Properties {
9393
bool GetWarningsUnsupportedLanguage() const;
9494
bool GetStopOnExec() const;
9595
std::chrono::seconds GetUtilityExpressionTimeout() const;
96-
std::chrono::seconds GetInterruptTimeout() const;
9796
bool GetOSPluginReportsAllThreads() const;
9897
void SetOSPluginReportsAllThreads(bool does_report);
9998
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 =
740-
m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo", response);
739+
auto result = m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo",
740+
response, false);
741741

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

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

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

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);
23+
static const seconds kInterruptTimeout(5);
2724

2825
/////////////////////////
2926
// GDBRemoteClientBase //
@@ -38,8 +35,7 @@ GDBRemoteClientBase::GDBRemoteClientBase(const char *comm_name,
3835

3936
StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
4037
ContinueDelegate &delegate, const UnixSignals &signals,
41-
llvm::StringRef payload, std::chrono::seconds interrupt_timeout,
42-
StringExtractorGDBRemote &response) {
38+
llvm::StringRef payload, StringExtractorGDBRemote &response) {
4339
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
4440
response.Clear();
4541

@@ -52,34 +48,16 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
5248
if (!cont_lock)
5349
return eStateInvalid;
5450
OnRunPacketSent(true);
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);
51+
6252
for (;;) {
63-
PacketResult read_result = ReadPacket(response, computed_timeout, false);
53+
PacketResult read_result = ReadPacket(response, kInterruptTimeout, false);
6454
switch (read_result) {
6555
case PacketResult::ErrorReplyTimeout: {
6656
std::lock_guard<std::mutex> lock(m_mutex);
67-
if (m_async_count == 0) {
57+
if (m_async_count == 0)
6858
continue;
69-
}
70-
auto cur_time = steady_clock::now();
71-
if (cur_time >= m_interrupt_endpoint)
59+
if (steady_clock::now() >= m_interrupt_time + kInterruptTimeout)
7260
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-
}
8361
break;
8462
}
8563
case PacketResult::Success:
@@ -155,9 +133,8 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
155133
}
156134
}
157135

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

@@ -167,26 +144,25 @@ bool GDBRemoteClientBase::SendAsyncSignal(
167144
return true;
168145
}
169146

170-
bool GDBRemoteClientBase::Interrupt(std::chrono::seconds interrupt_timeout) {
171-
Lock lock(*this, interrupt_timeout);
147+
bool GDBRemoteClientBase::Interrupt() {
148+
Lock lock(*this, true);
172149
if (!lock.DidInterrupt())
173150
return false;
174151
m_should_stop = true;
175152
return true;
176153
}
177-
178154
GDBRemoteCommunication::PacketResult
179155
GDBRemoteClientBase::SendPacketAndWaitForResponse(
180156
llvm::StringRef payload, StringExtractorGDBRemote &response,
181-
std::chrono::seconds interrupt_timeout) {
182-
Lock lock(*this, interrupt_timeout);
157+
bool send_async) {
158+
Lock lock(*this, send_async);
183159
if (!lock) {
184160
if (Log *log =
185161
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
186162
LLDB_LOGF(log,
187163
"GDBRemoteClientBase::%s failed to get mutex, not sending "
188-
"packet '%.*s'",
189-
__FUNCTION__, int(payload.size()), payload.data());
164+
"packet '%.*s' (send_async=%d)",
165+
__FUNCTION__, int(payload.size()), payload.data(), send_async);
190166
return PacketResult::ErrorSendFailed;
191167
}
192168

@@ -196,16 +172,16 @@ GDBRemoteClientBase::SendPacketAndWaitForResponse(
196172
GDBRemoteCommunication::PacketResult
197173
GDBRemoteClientBase::SendPacketAndReceiveResponseWithOutputSupport(
198174
llvm::StringRef payload, StringExtractorGDBRemote &response,
199-
std::chrono::seconds interrupt_timeout,
175+
bool send_async,
200176
llvm::function_ref<void(llvm::StringRef)> output_callback) {
201-
Lock lock(*this, interrupt_timeout);
177+
Lock lock(*this, send_async);
202178
if (!lock) {
203179
if (Log *log =
204180
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
205181
LLDB_LOGF(log,
206182
"GDBRemoteClientBase::%s failed to get mutex, not sending "
207-
"packet '%.*s'",
208-
__FUNCTION__, int(payload.size()), payload.data());
183+
"packet '%.*s' (send_async=%d)",
184+
__FUNCTION__, int(payload.size()), payload.data(), send_async);
209185
return PacketResult::ErrorSendFailed;
210186
}
211187

@@ -246,14 +222,13 @@ GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
246222
return packet_result;
247223
}
248224

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

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

258233
LLDB_LOGF(log,
259234
"GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
@@ -361,20 +336,18 @@ GDBRemoteClientBase::ContinueLock::lock() {
361336
// GDBRemoteClientBase::Lock //
362337
///////////////////////////////
363338

364-
GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm,
365-
std::chrono::seconds interrupt_timeout)
339+
GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, bool interrupt)
366340
: m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm),
367-
m_interrupt_timeout(interrupt_timeout), m_acquired(false),
368-
m_did_interrupt(false) {
369-
SyncWithContinueThread();
341+
m_acquired(false), m_did_interrupt(false) {
342+
SyncWithContinueThread(interrupt);
370343
if (m_acquired)
371344
m_async_lock.lock();
372345
}
373346

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

@@ -392,9 +365,9 @@ void GDBRemoteClientBase::Lock::SyncWithContinueThread() {
392365
"interrupt packet");
393366
return;
394367
}
395-
m_comm.m_interrupt_endpoint = steady_clock::now() + m_interrupt_timeout;
396368
if (log)
397369
log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03");
370+
m_comm.m_interrupt_time = steady_clock::now();
398371
}
399372
m_comm.m_cv.wait(lock, [this] { return !m_comm.m_is_running; });
400373
m_did_interrupt = true;

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

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

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

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

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

4040
lldb::StateType SendContinuePacketAndWaitForResponse(
4141
ContinueDelegate &delegate, const UnixSignals &signals,
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));
42+
llvm::StringRef payload, StringExtractorGDBRemote &response);
43+
44+
PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload,
45+
StringExtractorGDBRemote &response,
46+
bool send_async);
5647

5748
PacketResult SendPacketAndReceiveResponseWithOutputSupport(
5849
llvm::StringRef payload, StringExtractorGDBRemote &response,
59-
std::chrono::seconds interrupt_timeout,
50+
bool send_async,
6051
llvm::function_ref<void(llvm::StringRef)> output_callback);
6152

6253
bool SendvContPacket(llvm::StringRef payload,
63-
std::chrono::seconds interrupt_timeout,
6454
StringExtractorGDBRemote &response);
6555

6656
class Lock {
6757
public:
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));
58+
Lock(GDBRemoteClientBase &comm, bool interrupt);
7659
~Lock();
7760

7861
explicit operator bool() { return m_acquired; }
@@ -84,11 +67,10 @@ class GDBRemoteClientBase : public GDBRemoteCommunication {
8467
private:
8568
std::unique_lock<std::recursive_mutex> m_async_lock;
8669
GDBRemoteClientBase &m_comm;
87-
std::chrono::seconds m_interrupt_timeout;
8870
bool m_acquired;
8971
bool m_did_interrupt;
9072

91-
void SyncWithContinueThread();
73+
void SyncWithContinueThread(bool interrupt);
9274
};
9375

9476
protected:
@@ -127,7 +109,7 @@ class GDBRemoteClientBase : public GDBRemoteCommunication {
127109

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

132114
/// Number of threads interested in sending.
133115
uint32_t m_async_count;

0 commit comments

Comments
 (0)