[Lldb-commits] [lldb] [lldb] fix a bug in the "Socket::Read" method (PR #207426)
Matej Košík via lldb-commits
lldb-commits at lists.llvm.org
Fri Jul 3 09:33:54 PDT 2026
https://github.com/sedymrak created https://github.com/llvm/llvm-project/pull/207426
On Windows, the "Socket::Read" method contains a hidden bug. The original condition
} while (bytes_received < 0 && IsInterrupted());
for retrying the "::recv" call is too strict.
The "::recv" call may return value "-1" even if the buffer is (accidentally) empty. If the buffer is empty, that should not be regarded as an error. Instead "::recv" should be called again
(similarly to the situation when we have realized that the "::recv" call was interrupted).
See:
https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recv
and
https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2
WSAEWOULDBLOCK
--------------
Resource temporarily unavailable.
This error is returned from operations on nonblocking sockets that cannot be completed immediately,
for example recv when no data is queued to be read from the socket.
It is a nonfatal error, and the operation should be retried later.
>From f59930a3b67e113baa4d664edb7b65cb5eb65181 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ko=C5=A1=C3=ADk?= <matej.kosik at codasip.com>
Date: Fri, 3 Jul 2026 18:17:52 +0200
Subject: [PATCH] [lldb] fix a bug in the "Socket::Read" method
On Windows, the "Socket::Read" method contains a hidden bug.
The original condition
} while (bytes_received < 0 && IsInterrupted());
for retrying the "::recv" call is too strict.
The "::recv" call may return value "-1" even if the buffer is (accidentally) empty.
If the buffer is empty, that should not be regarded as an error.
Instead "::recv" should be called again
(similarly to the situation when we have realized that the "::recv" call was interrupted).
See:
https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recv
and
https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2
WSAEWOULDBLOCK
--------------
Resource temporarily unavailable.
This error is returned from operations on nonblocking sockets that cannot be completed immediately,
for example recv when no data is queued to be read from the socket.
It is a nonfatal error, and the operation should be retried later.
---
lldb/source/Host/common/Socket.cpp | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp
index c0247509df1c1..77ad5209934c9 100644
--- a/lldb/source/Host/common/Socket.cpp
+++ b/lldb/source/Host/common/Socket.cpp
@@ -63,6 +63,14 @@ static bool IsInterrupted() {
#endif
}
+static bool WouldBlock() {
+#if defined(_WIN32)
+ return ::WSAGetLastError() == WSAEWOULDBLOCK;
+#else
+ return false;
+#endif
+}
+
SharedSocket::SharedSocket(const Socket *socket, Status &error) {
#ifdef _WIN32
m_socket = socket->GetNativeSocket();
@@ -330,7 +338,7 @@ Status Socket::Read(void *buf, size_t &num_bytes) {
int bytes_received = 0;
do {
bytes_received = ::recv(m_socket, static_cast<char *>(buf), num_bytes, 0);
- } while (bytes_received < 0 && IsInterrupted());
+ } while (bytes_received < 0 && (IsInterrupted() || WouldBlock()));
if (bytes_received < 0) {
SetLastError(error);
More information about the lldb-commits
mailing list