llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: John Harrison (ashgti)

<details>
<summary>Changes</summary>

We need to use an unbuffered socket / pipe to the lldb-dap subprocess to make 
sure that when we perform a select, there is no partial messages in the file 
buffer. If there are partial messages in the file buffer we could end up doing 
a read that crosses the buffer size and results in a hang until a new message 
is sent, that may or may not occur.

As a result, when we perform a read we can get less than the requested number 
of bytes. We need to retry the read operation if this occurs.

I think this should resolve issue #<!-- -->165784

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


1 Files Affected:

- (modified) lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
(+13-2) 


``````````diff
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 
b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 8f3652172dfdf..5000a8ec0a0ce 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -220,6 +220,11 @@ def _read_packet(
         followed by the JSON bytes from self.recv. Returns None on EOF.
         """
 
+        # NOTE: We open the socket or pipe to the subprocess in an unbuffered
+        # mode to ensure we do not end up with a partial message in the buffer
+        # when we perform our select. Otherwise, we may run into a case where 
we
+        # attempt a read and the buffer is partially full but a new message is
+        # not sent to fill in the requested buffer size.
         ready = self.selector.select(timeout)
         if not ready:
             warnings.warn(
@@ -243,10 +248,16 @@ def _read_packet(
             if separator != "":
                 Exception("malformed DAP content header, unexpected line: " + 
separator)
             # Read JSON bytes
-            json_str = self.recv.read(length).decode()
+            # NOTE: Because the read channel is unbuffered we may receive less
+            # than the requested number of bytes. In, which case we need to
+            # perform a new read.
+            json_str = b""
+            while len(json_str) < length:
+                json_str += self.recv.read(length - len(json_str))
+
             if self.trace_file:
                 self.trace_file.write(
-                    "%s from adapter:\n%s\n" % (time.time(), json_str)
+                    "%s from adapter:\n%s\n" % (time.time(), json_str.decode())
                 )
             # Decode the JSON bytes into a python dictionary
             return json.loads(json_str)

``````````

</details>


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

Reply via email to