This revision was automatically updated to reflect the committed changes.
Closed by commit rG85f025e5b33d: [lldb/test] Test lldb-server named pipe 
functionality on windows (authored by labath).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D96260/new/

https://reviews.llvm.org/D96260

Files:
  lldb/test/API/tools/lldb-server/commandline/TestGdbRemoteConnection.py

Index: lldb/test/API/tools/lldb-server/commandline/TestGdbRemoteConnection.py
===================================================================
--- lldb/test/API/tools/lldb-server/commandline/TestGdbRemoteConnection.py
+++ lldb/test/API/tools/lldb-server/commandline/TestGdbRemoteConnection.py
@@ -5,6 +5,122 @@
 import socket
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbplatformutil
+import random
+
+if lldbplatformutil.getHostPlatform() == "windows":
+    import ctypes
+    import ctypes.wintypes
+    from ctypes.wintypes import (BOOL, DWORD, HANDLE, LPCWSTR, LPDWORD, LPVOID)
+
+    kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
+
+    PIPE_ACCESS_INBOUND = 1
+    FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000
+    FILE_FLAG_OVERLAPPED = 0x40000000
+    PIPE_TYPE_BYTE = 0
+    PIPE_REJECT_REMOTE_CLIENTS = 8
+    INVALID_HANDLE_VALUE = -1
+    ERROR_ACCESS_DENIED = 5
+    ERROR_IO_PENDING = 997
+
+
+    class OVERLAPPED(ctypes.Structure):
+        _fields_ = [("Internal", LPVOID), ("InternalHigh", LPVOID), ("Offset",
+            DWORD), ("OffsetHigh", DWORD), ("hEvent", HANDLE)]
+
+        def __init__(self):
+            super(OVERLAPPED, self).__init__(Internal=0, InternalHigh=0,
+                Offset=0, OffsetHigh=0, hEvent=None)
+    LPOVERLAPPED = ctypes.POINTER(OVERLAPPED)
+
+    CreateNamedPipe = kernel32.CreateNamedPipeW
+    CreateNamedPipe.restype = HANDLE
+    CreateNamedPipe.argtypes = (LPCWSTR, DWORD, DWORD, DWORD, DWORD, DWORD,
+            DWORD, LPVOID)
+
+    ConnectNamedPipe = kernel32.ConnectNamedPipe
+    ConnectNamedPipe.restype = BOOL
+    ConnectNamedPipe.argtypes = (HANDLE, LPOVERLAPPED)
+
+    CreateEvent = kernel32.CreateEventW
+    CreateEvent.restype = HANDLE
+    CreateEvent.argtypes = (LPVOID, BOOL, BOOL, LPCWSTR)
+
+    GetOverlappedResultEx = kernel32.GetOverlappedResultEx
+    GetOverlappedResultEx.restype = BOOL
+    GetOverlappedResultEx.argtypes = (HANDLE, LPOVERLAPPED, LPDWORD, DWORD,
+        BOOL)
+
+    ReadFile = kernel32.ReadFile
+    ReadFile.restype = BOOL
+    ReadFile.argtypes = (HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED)
+
+    CloseHandle = kernel32.CloseHandle
+    CloseHandle.restype = BOOL
+    CloseHandle.argtypes = (HANDLE,)
+
+    class Pipe(object):
+        def __init__(self, prefix):
+            while True:
+                self.name = "lldb-" + str(random.randrange(1e10))
+                full_name = "\\\\.\\pipe\\" + self.name
+                self._handle = CreateNamedPipe(full_name, PIPE_ACCESS_INBOUND |
+                        FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
+                        PIPE_TYPE_BYTE | PIPE_REJECT_REMOTE_CLIENTS, 1, 4096,
+                        4096, 0, None)
+                if self._handle != INVALID_HANDLE_VALUE:
+                    break
+                if ctypes.get_last_error() != ERROR_ACCESS_DENIED:
+                    raise ctypes.WinError(ctypes.get_last_error())
+
+            self._overlapped = OVERLAPPED()
+            self._overlapped.hEvent = CreateEvent(None, True, False, None)
+            result = ConnectNamedPipe(self._handle, self._overlapped)
+            assert result == 0
+            if ctypes.get_last_error() != ERROR_IO_PENDING:
+                raise ctypes.WinError(ctypes.get_last_error())
+
+        def finish_connection(self, timeout):
+            if not GetOverlappedResultEx(self._handle, self._overlapped,
+                    ctypes.byref(DWORD(0)), timeout*1000, True):
+                raise ctypes.WinError(ctypes.get_last_error())
+
+        def read(self, size, timeout):
+            buf = ctypes.create_string_buffer(size)
+            if not ReadFile(self._handle, ctypes.byref(buf), size, None,
+                    self._overlapped):
+                if ctypes.get_last_error() != ERROR_IO_PENDING:
+                    raise ctypes.WinError(ctypes.get_last_error())
+            read = DWORD(0)
+            if not GetOverlappedResultEx(self._handle, self._overlapped,
+                    ctypes.byref(read), timeout*1000, True):
+                raise ctypes.WinError(ctypes.get_last_error())
+            return buf.raw[0:read.value]
+
+        def close(self):
+            CloseHandle(self._overlapped.hEvent)
+            CloseHandle(self._handle)
+
+
+else:
+    class Pipe(object):
+        def __init__(self, prefix):
+            self.name = os.path.join(prefix, "stub_port_number")
+            os.mkfifo(self.name)
+            self._fd = os.open(self.name, os.O_RDONLY | os.O_NONBLOCK)
+
+        def finish_connection(self, timeout):
+            pass
+
+        def read(self, size, timeout):
+            (readers, _, _) = select.select([self._fd], [], [], timeout)
+            if self._fd not in readers:
+                raise TimeoutError
+            return os.read(self._fd, size)
+
+        def close(self):
+            os.close(self._fd)
 
 
 class TestGdbRemoteConnection(gdbremote_testcase.GdbRemoteTestCaseBase):
@@ -19,7 +135,6 @@
         self.do_handshake(self.sock)
 
     @skipIfRemote
-    @skipIfWindows
     def test_named_pipe_llgs(self):
         family, type, proto, _, addr = socket.getaddrinfo(
             self.stub_hostname, 0, proto=socket.IPPROTO_TCP)[0]
@@ -28,16 +143,9 @@
 
         self.addTearDownHook(lambda: self.sock.close())
 
-        named_pipe_path = self.getBuildArtifact("stub_port_number")
+        pipe = Pipe(self.getBuildDir())
 
-        # Create the named pipe.
-        os.mkfifo(named_pipe_path)
-
-        # Open the read side of the pipe in non-blocking mode.  This will
-        # return right away, ready or not.
-        named_pipe_fd = os.open(named_pipe_path, os.O_RDONLY | os.O_NONBLOCK)
-
-        self.addTearDownHook(lambda: os.close(named_pipe_fd))
+        self.addTearDownHook(lambda: pipe.close())
 
         args = self.debug_monitor_extra_args
         if lldb.remote_platform:
@@ -45,19 +153,15 @@
         else:
             args += ["localhost:0"]
 
-        args += ["--named-pipe", named_pipe_path]
+        args += ["--named-pipe", pipe.name]
 
         server = self.spawnSubprocess(
             self.debug_monitor_exe,
             args,
             install_remote=False)
 
-        (ready_readers, _, _) = select.select(
-            [named_pipe_fd], [], [], self.DEFAULT_TIMEOUT)
-        self.assertIsNotNone(
-            ready_readers,
-            "write side of pipe has not written anything - stub isn't writing to pipe.")
-        port = os.read(named_pipe_fd, 10)
+        pipe.finish_connection(self.DEFAULT_TIMEOUT)
+        port = pipe.read(10, self.DEFAULT_TIMEOUT)
         # Trim null byte, convert to int
         addr = (addr[0], int(port[:-1]))
         self.sock.connect(addr)
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to