[lldb] Fix qEcho message handling. (#145675)

This fixes issues found in e066f35c69, which
was later reverted. The problem was with "k" message which was sent with
sync_on_timeout flag set to true, so lldb was waiting for response,
which is currently not being sent by lldb-server. Not waiting for
response at all seems to be not a solution, because on MAC OS X lldb
waits for response from "k" to gracefully kill inferior.
This commit is contained in:
eleviant
2025-06-25 13:38:37 +02:00
committed by GitHub
parent 97fdc237dd
commit c941bee75d
7 changed files with 98 additions and 9 deletions

View File

@@ -180,7 +180,7 @@ bool GDBRemoteClientBase::Interrupt(std::chrono::seconds interrupt_timeout) {
GDBRemoteCommunication::PacketResult
GDBRemoteClientBase::SendPacketAndWaitForResponse(
llvm::StringRef payload, StringExtractorGDBRemote &response,
std::chrono::seconds interrupt_timeout) {
std::chrono::seconds interrupt_timeout, bool sync_on_timeout) {
Lock lock(*this, interrupt_timeout);
if (!lock) {
if (Log *log = GetLog(GDBRLog::Process))
@@ -191,7 +191,7 @@ GDBRemoteClientBase::SendPacketAndWaitForResponse(
return PacketResult::ErrorSendFailed;
}
return SendPacketAndWaitForResponseNoLock(payload, response);
return SendPacketAndWaitForResponseNoLock(payload, response, sync_on_timeout);
}
GDBRemoteCommunication::PacketResult
@@ -236,14 +236,15 @@ GDBRemoteClientBase::SendPacketAndReceiveResponseWithOutputSupport(
GDBRemoteCommunication::PacketResult
GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
llvm::StringRef payload, StringExtractorGDBRemote &response) {
llvm::StringRef payload, StringExtractorGDBRemote &response,
bool sync_on_timeout) {
PacketResult packet_result = SendPacketNoLock(payload);
if (packet_result != PacketResult::Success)
return packet_result;
const size_t max_response_retries = 3;
for (size_t i = 0; i < max_response_retries; ++i) {
packet_result = ReadPacket(response, GetPacketTimeout(), true);
packet_result = ReadPacket(response, GetPacketTimeout(), sync_on_timeout);
// Make sure we received a response
if (packet_result != PacketResult::Success)
return packet_result;

View File

@@ -61,7 +61,8 @@ public:
// ErrorReplyTimeout.
PacketResult SendPacketAndWaitForResponse(
llvm::StringRef payload, StringExtractorGDBRemote &response,
std::chrono::seconds interrupt_timeout = std::chrono::seconds(0));
std::chrono::seconds interrupt_timeout = std::chrono::seconds(0),
bool sync_on_timeout = true);
PacketResult ReadPacketWithOutputSupport(
StringExtractorGDBRemote &response, Timeout<std::micro> timeout,
@@ -104,7 +105,8 @@ public:
protected:
PacketResult
SendPacketAndWaitForResponseNoLock(llvm::StringRef payload,
StringExtractorGDBRemote &response);
StringExtractorGDBRemote &response,
bool sync_on_timeout = true);
virtual void OnRunPacketSent(bool first);

View File

@@ -355,8 +355,9 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet,
disconnected = true;
Disconnect();
}
} else {
timed_out = true;
}
timed_out = true;
break;
case eConnectionStatusSuccess:
// printf ("status = success but error = %s\n",

View File

@@ -406,7 +406,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
m_supports_qXfer_memory_map_read = eLazyBoolYes;
else if (x == "qXfer:siginfo:read+")
m_supports_qXfer_siginfo_read = eLazyBoolYes;
else if (x == "qEcho")
else if (x == "qEcho+")
m_supports_qEcho = eLazyBoolYes;
else if (x == "QPassSignals+")
m_supports_QPassSignals = eLazyBoolYes;
@@ -4358,7 +4358,9 @@ llvm::Expected<int> GDBRemoteCommunicationClient::KillProcess(lldb::pid_t pid) {
StringExtractorGDBRemote response;
GDBRemoteCommunication::ScopedTimeout(*this, seconds(3));
if (SendPacketAndWaitForResponse("k", response, GetPacketTimeout()) !=
// LLDB server typically sends no response for "k", so we shouldn't try
// to sync on timeout.
if (SendPacketAndWaitForResponse("k", response, GetPacketTimeout(), false) !=
PacketResult::Success)
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"failed to send k packet");