[Lldb-commits] [lldb] [lldb] fix a bug in the "Socket::Read" method (PR #207426)

2026-07-20 Thread Matej Košík via lldb-commits

sedymrak wrote:

In the following method:

  ConnectionFileDescriptor::Read

(which is invoked also on Windows)
LLDB first waits until some bytes are available

  status = BytesAvailable(timeout, error_ptr);

and only then it tries to read them:

  error = m_io_sp->Read(dst, bytes_read);

So the situation where the `::recv` could fail with the `WSAEWOULDBLOCK`
error cannot happen.

That makes this pull-request pointless so I am closing it...

https://github.com/llvm/llvm-project/pull/207426
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] fix a bug in the "Socket::Read" method (PR #207426)

2026-07-20 Thread Matej Košík via lldb-commits

https://github.com/sedymrak closed 
https://github.com/llvm/llvm-project/pull/207426
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] fix a bug in the "Socket::Read" method (PR #207426)

2026-07-03 Thread Matej Košík via lldb-commits

sedymrak wrote:

[socket.zip](https://github.com/user-attachments/files/29642798/socket.zip)
This project shows that what is described in Win32 API documentation can happen 
in real life.
The `::recv` call in the TCP client can fail (i.e. return value `-1`) when the 
buffer is (accidentally) empty.
The binaries can be built on Windows as follows:
```
cmake -S . -B build
cmake --build build
```
Then they can be run (e.g. in `cmd.exe` as:
```
build\Debug\server.exe
```
in one `cmd.exe` terminal and:
```
build\Debug\client.exe
```
in the other `cmd.exe` terminal.

https://github.com/llvm/llvm-project/pull/207426
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] fix a bug in the "Socket::Read" method (PR #207426)

2026-07-03 Thread via lldb-commits

llvmorg-github-actions[bot] wrote:




@llvm/pr-subscribers-lldb

Author: Matej Košík (sedymrak)


Changes

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/207426.diff


1 Files Affected:

- (modified) lldb/source/Host/common/Socket.cpp (+9-1) 


``diff
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(buf), num_bytes, 0);
-  } while (bytes_received < 0 && IsInterrupted());
+  } while (bytes_received < 0 && (IsInterrupted() || WouldBlock()));
 
   if (bytes_received < 0) {
 SetLastError(error);

``




https://github.com/llvm/llvm-project/pull/207426
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] fix a bug in the "Socket::Read" method (PR #207426)

2026-07-03 Thread Matej Košík via lldb-commits

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?= 
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(buf), num_bytes, 0);
-  } while (bytes_received < 0 && IsInterrupted());
+  } while (bytes_received < 0 && (IsInterrupted() || WouldBlock()));
 
   if (bytes_received < 0) {
 SetLastError(error);

___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits