summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Host/Pipe.h80
-rw-r--r--lldb/include/lldb/Host/posix/PipePosix.h84
-rw-r--r--lldb/include/lldb/Host/windows/PipeWindows.h78
-rw-r--r--lldb/source/Host/CMakeLists.txt3
-rw-r--r--lldb/source/Host/posix/PipePosix.cpp (renamed from lldb/source/Host/common/Pipe.cpp)32
-rw-r--r--lldb/source/Host/windows/ConnectionGenericFileWindows.cpp13
-rw-r--r--lldb/source/Host/windows/PipeWindows.cpp231
-rw-r--r--lldb/source/Interpreter/ScriptInterpreterPython.cpp15
8 files changed, 431 insertions, 105 deletions
diff --git a/lldb/include/lldb/Host/Pipe.h b/lldb/include/lldb/Host/Pipe.h
index b36c85cfbe8..b748788c5ee 100644
--- a/lldb/include/lldb/Host/Pipe.h
+++ b/lldb/include/lldb/Host/Pipe.h
@@ -7,77 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Pipe_h_
-#define liblldb_Pipe_h_
-#if defined(__cplusplus)
+#ifndef liblldb_Host_Pipe_h_
+#define liblldb_Host_Pipe_h_
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
+#if defined(_WIN32)
+#include "lldb/Host/windows/PipeWindows.h"
+#else
+#include "lldb/Host/windows/PipePosix.h"
+#endif
-#include "lldb/lldb-private.h"
-
-namespace lldb_private {
-
-//----------------------------------------------------------------------
-/// @class Pipe Pipe.h "lldb/Host/Pipe.h"
-/// @brief A class that abtracts unix style pipes.
-///
-/// A class that abstracts the LLDB core from host pipe functionality.
-//----------------------------------------------------------------------
-class Pipe
-{
-public:
- static int kInvalidDescriptor;
-
- Pipe();
-
- ~Pipe();
-
- bool
- Open();
-
- bool
- IsValid() const;
-
- bool
- ReadDescriptorIsValid() const;
-
- bool
- WriteDescriptorIsValid() const;
-
- int
- GetReadFileDescriptor() const;
-
- int
- GetWriteFileDescriptor() const;
-
- // Close both descriptors
- void
- Close();
-
- bool
- CloseReadFileDescriptor();
-
- bool
- CloseWriteFileDescriptor();
-
- int
- ReleaseReadFileDescriptor();
-
- int
- ReleaseWriteFileDescriptor();
-
- size_t
- Read (void *buf, size_t size);
-
- size_t
- Write (const void *buf, size_t size);
-private:
- int m_fds[2];
-};
-
-} // namespace lldb_private
-
-#endif // #if defined(__cplusplus)
-#endif // liblldb_Pipe_h_
+#endif // liblldb_Host_Pipe_h_
diff --git a/lldb/include/lldb/Host/posix/PipePosix.h b/lldb/include/lldb/Host/posix/PipePosix.h
new file mode 100644
index 00000000000..0102124d947
--- /dev/null
+++ b/lldb/include/lldb/Host/posix/PipePosix.h
@@ -0,0 +1,84 @@
+//===-- PipePosix.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Host_posix_PipePosix_h_
+#define liblldb_Host_posix_PipePosix_h_
+#if defined(__cplusplus)
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Pipe Pipe.h "lldb/Host/posix/PipePosix.h"
+/// @brief A posix-based implementation of Pipe, a class that abtracts
+/// unix style pipes.
+///
+/// A class that abstracts the LLDB core from host pipe functionality.
+//----------------------------------------------------------------------
+class Pipe
+{
+public:
+ static int kInvalidDescriptor;
+
+ Pipe();
+
+ ~Pipe();
+
+ bool
+ Open();
+
+ bool
+ IsValid() const;
+
+ bool
+ ReadDescriptorIsValid() const;
+
+ bool
+ WriteDescriptorIsValid() const;
+
+ int
+ GetReadFileDescriptor() const;
+
+ int
+ GetWriteFileDescriptor() const;
+
+ // Close both descriptors
+ void
+ Close();
+
+ bool
+ CloseReadFileDescriptor();
+
+ bool
+ CloseWriteFileDescriptor();
+
+ int
+ ReleaseReadFileDescriptor();
+
+ int
+ ReleaseWriteFileDescriptor();
+
+ size_t
+ Read (void *buf, size_t size);
+
+ size_t
+ Write (const void *buf, size_t size);
+private:
+ int m_fds[2];
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_Host_posix_PipePosix_h_
diff --git a/lldb/include/lldb/Host/windows/PipeWindows.h b/lldb/include/lldb/Host/windows/PipeWindows.h
new file mode 100644
index 00000000000..1a22a3ca9c6
--- /dev/null
+++ b/lldb/include/lldb/Host/windows/PipeWindows.h
@@ -0,0 +1,78 @@
+//===-- PipePosix.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Host_windows_PipeWindows_h_
+#define liblldb_Host_windows_PipeWindows_h_
+
+#include "lldb/Host/windows/windows.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class Pipe PipeWindows.h "lldb/Host/windows/PipeWindows.h"
+/// @brief A windows-based implementation of Pipe, a class that abtracts
+/// unix style pipes.
+///
+/// A class that abstracts the LLDB core from host pipe functionality.
+//----------------------------------------------------------------------
+class Pipe
+{
+ public:
+ Pipe();
+
+ ~Pipe();
+
+ bool Open(bool read_overlapped = false, bool write_overlapped = false);
+
+ bool IsValid() const;
+
+ bool ReadDescriptorIsValid() const;
+
+ bool WriteDescriptorIsValid() const;
+
+ int GetReadFileDescriptor() const;
+
+ int GetWriteFileDescriptor() const;
+
+ // Close both descriptors
+ void Close();
+
+ bool CloseReadFileDescriptor();
+
+ bool CloseWriteFileDescriptor();
+
+ int ReleaseReadFileDescriptor();
+
+ int ReleaseWriteFileDescriptor();
+
+ HANDLE
+ GetReadNativeHandle();
+
+ HANDLE
+ GetWriteNativeHandle();
+
+ size_t Read(void *buf, size_t size);
+
+ size_t Write(const void *buf, size_t size);
+
+ private:
+ HANDLE m_read;
+ HANDLE m_write;
+
+ int m_read_fd;
+ int m_write_fd;
+
+ OVERLAPPED *m_read_overlapped;
+ OVERLAPPED *m_write_overlapped;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Host_posix_PipePosix_h_
diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt
index a2adb8a1ea4..73da2a890af 100644
--- a/lldb/source/Host/CMakeLists.txt
+++ b/lldb/source/Host/CMakeLists.txt
@@ -21,7 +21,6 @@ add_host_subdirectory(common
common/NativeProcessProtocol.cpp
common/NativeThreadProtocol.cpp
common/OptionParser.cpp
- common/Pipe.cpp
common/ProcessRunLock.cpp
common/Socket.cpp
common/SocketAddress.cpp
@@ -48,6 +47,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "Windows")
windows/HostProcessWindows.cpp
windows/HostThreadWindows.cpp
windows/Mutex.cpp
+ windows/PipeWindows.cpp
windows/ProcessRunLock.cpp
windows/ThisThread.cpp
windows/Windows.cpp
@@ -58,6 +58,7 @@ else()
posix/HostInfoPosix.cpp
posix/HostProcessPosix.cpp
posix/HostThreadPosix.cpp
+ posix/PipePosix.cpp
)
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
diff --git a/lldb/source/Host/common/Pipe.cpp b/lldb/source/Host/posix/PipePosix.cpp
index 4db0e32c93b..ebc2033268e 100644
--- a/lldb/source/Host/common/Pipe.cpp
+++ b/lldb/source/Host/posix/PipePosix.cpp
@@ -1,4 +1,4 @@
-//===-- Pipe.cpp ------------------------------------------------*- C++ -*-===//
+//===-- PipePosix.cpp -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,14 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Host/Pipe.h"
+#include "lldb/Host/posix/PipePosix.h"
-#if defined(_WIN32)
-#include <io.h>
-#include <fcntl.h>
-#else
#include <unistd.h>
-#endif
using namespace lldb_private;
@@ -39,13 +34,9 @@ Pipe::Open()
if (IsValid())
return true;
-#ifdef _WIN32
- if (::_pipe(m_fds, 256, O_BINARY) == 0)
- return true;
-#else
if (::pipe(m_fds) == 0)
return true;
-#endif
+
m_fds[READ] = Pipe::kInvalidDescriptor;
m_fds[WRITE] = Pipe::kInvalidDescriptor;
return false;
@@ -110,11 +101,7 @@ Pipe::CloseReadFileDescriptor()
if (ReadDescriptorIsValid())
{
int err;
-#ifdef _WIN32
- err = _close(m_fds[READ]);
-#else
err = close(m_fds[READ]);
-#endif
m_fds[READ] = Pipe::kInvalidDescriptor;
return err == 0;
}
@@ -127,11 +114,7 @@ Pipe::CloseWriteFileDescriptor()
if (WriteDescriptorIsValid())
{
int err;
-#ifdef _WIN32
- err = _close(m_fds[WRITE]);
-#else
err = close(m_fds[WRITE]);
-#endif
m_fds[WRITE] = Pipe::kInvalidDescriptor;
return err == 0;
}
@@ -145,11 +128,7 @@ Pipe::Read (void *buf, size_t num_bytes)
if (ReadDescriptorIsValid())
{
const int fd = GetReadFileDescriptor();
-#ifdef _WIN32
- return _read (fd, (char *)buf, num_bytes);
-#else
return read (fd, buf, num_bytes);
-#endif
}
return 0; // Return 0 since errno won't be set if we didn't call read
}
@@ -160,12 +139,7 @@ Pipe::Write (const void *buf, size_t num_bytes)
if (WriteDescriptorIsValid())
{
const int fd = GetWriteFileDescriptor();
-#ifdef _WIN32
- return _write (fd, (char *)buf, num_bytes);
-#else
return write (fd, buf, num_bytes);
-#endif
}
return 0; // Return 0 since errno won't be set if we didn't call write
}
-
diff --git a/lldb/source/Host/windows/ConnectionGenericFileWindows.cpp b/lldb/source/Host/windows/ConnectionGenericFileWindows.cpp
index 312cef62d65..93d37945992 100644
--- a/lldb/source/Host/windows/ConnectionGenericFileWindows.cpp
+++ b/lldb/source/Host/windows/ConnectionGenericFileWindows.cpp
@@ -241,9 +241,16 @@ ConnectionGenericFile::Read(void *dst, size_t dst_len, uint32_t timeout_usec, ll
goto finish;
}
-
- // An unknown error occured. Fail out.
- return_info.Set(0, eConnectionStatusError, ::GetLastError());
+ else if (::GetLastError() == ERROR_BROKEN_PIPE)
+ {
+ // The write end of a pipe was closed. This is equivalent to EOF.
+ return_info.Set(0, eConnectionStatusEndOfFile, 0);
+ }
+ else
+ {
+ // An unknown error occured. Fail out.
+ return_info.Set(0, eConnectionStatusError, ::GetLastError());
+ }
goto finish;
finish:
diff --git a/lldb/source/Host/windows/PipeWindows.cpp b/lldb/source/Host/windows/PipeWindows.cpp
new file mode 100644
index 00000000000..572be878409
--- /dev/null
+++ b/lldb/source/Host/windows/PipeWindows.cpp
@@ -0,0 +1,231 @@
+//===-- PipeWindows.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/windows/PipeWindows.h"
+
+#include "llvm/Support/raw_ostream.h"
+
+#include <fcntl.h>
+#include <io.h>
+
+#include <atomic>
+#include <string>
+
+using namespace lldb_private;
+
+namespace
+{
+std::atomic<uint32_t> g_pipe_serial(0);
+}
+
+Pipe::Pipe()
+{
+ m_read = INVALID_HANDLE_VALUE;
+ m_write = INVALID_HANDLE_VALUE;
+
+ m_read_fd = -1;
+ m_write_fd = -1;
+
+ m_read_overlapped = nullptr;
+ m_write_overlapped = nullptr;
+}
+
+Pipe::~Pipe()
+{
+ Close();
+}
+
+bool
+Pipe::Open(bool read_overlapped, bool write_overlapped)
+{
+ if (IsValid())
+ return true;
+
+ uint32_t serial = g_pipe_serial.fetch_add(1);
+ std::string pipe_name;
+ llvm::raw_string_ostream pipe_name_stream(pipe_name);
+ pipe_name_stream << "\\\\.\\Pipe\\lldb.pipe." << ::GetCurrentProcessId() << "." << serial;
+ pipe_name_stream.flush();
+
+ DWORD read_mode = 0;
+ DWORD write_mode = 0;
+ if (read_overlapped)
+ read_mode |= FILE_FLAG_OVERLAPPED;
+ if (write_overlapped)
+ write_mode |= FILE_FLAG_OVERLAPPED;
+ m_read =
+ ::CreateNamedPipe(pipe_name.c_str(), PIPE_ACCESS_INBOUND | read_mode, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);
+ if (INVALID_HANDLE_VALUE == m_read)
+ return false;
+ m_write = ::CreateFile(pipe_name.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, write_mode, NULL);
+ if (INVALID_HANDLE_VALUE == m_write)
+ {
+ ::CloseHandle(m_read);
+ m_read = INVALID_HANDLE_VALUE;
+ return false;
+ }
+
+ m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
+ m_write_fd = _open_osfhandle((intptr_t)m_write, _O_WRONLY);
+
+ if (read_overlapped)
+ {
+ m_read_overlapped = new OVERLAPPED;
+ ZeroMemory(m_read_overlapped, sizeof(OVERLAPPED));
+ }
+ if (write_overlapped)
+ {
+ m_write_overlapped = new OVERLAPPED;
+ ZeroMemory(m_write_overlapped, sizeof(OVERLAPPED));
+ }
+ return true;
+}
+
+int
+Pipe::GetReadFileDescriptor() const
+{
+ return m_read_fd;
+}
+
+int
+Pipe::GetWriteFileDescriptor() const
+{
+ return m_write_fd;
+}
+
+int
+Pipe::ReleaseReadFileDescriptor()
+{
+ int result = m_read_fd;
+ m_read_fd = -1;
+ m_read = INVALID_HANDLE_VALUE;
+ if (m_read_overlapped)
+ {
+ delete m_read_overlapped;
+ m_read_overlapped = nullptr;
+ }
+ return result;
+}
+
+int
+Pipe::ReleaseWriteFileDescriptor()
+{
+ int result = m_write_fd;
+ m_write_fd = -1;
+ m_write = INVALID_HANDLE_VALUE;
+ if (m_write_overlapped)
+ {
+ delete m_write_overlapped;
+ m_write_overlapped = nullptr;
+ }
+ return result;
+}
+
+void
+Pipe::Close()
+{
+ CloseReadFileDescriptor();
+ CloseWriteFileDescriptor();
+}
+
+bool
+Pipe::ReadDescriptorIsValid() const
+{
+ return m_read_fd != -1;
+}
+
+bool
+Pipe::WriteDescriptorIsValid() const
+{
+ return m_write_fd != -1;
+}
+
+bool
+Pipe::IsValid() const
+{
+ return ReadDescriptorIsValid() && WriteDescriptorIsValid();
+}
+
+bool
+Pipe::CloseReadFileDescriptor()
+{
+ if (ReadDescriptorIsValid())
+ {
+ int err;
+ err = _close(m_read_fd);
+ m_read_fd = -1;
+ m_read = INVALID_HANDLE_VALUE;
+ if (m_read_overlapped)
+ {
+ delete m_read_overlapped;
+ m_read_overlapped = nullptr;
+ }
+ return err == 0;
+ }
+ return true;
+}
+
+bool
+Pipe::CloseWriteFileDescriptor()
+{
+ if (WriteDescriptorIsValid())
+ {
+ int err;
+ err = _close(m_write_fd);
+ m_write_fd = -1;
+ m_write = INVALID_HANDLE_VALUE;
+ if (m_write_overlapped)
+ {
+ delete m_write_overlapped;
+ m_write_overlapped = nullptr;
+ }
+ return err == 0;
+ }
+ return true;
+}
+
+HANDLE
+Pipe::GetReadNativeHandle()
+{
+ return m_read;
+}
+
+HANDLE
+Pipe::GetWriteNativeHandle()
+{
+ return m_write;
+}
+
+size_t
+Pipe::Read(void *buf, size_t num_bytes)
+{
+ if (ReadDescriptorIsValid())
+ {
+ DWORD bytes_read = 0;
+ ::ReadFile(m_read, buf, num_bytes, &bytes_read, m_read_overlapped);
+ if (m_read_overlapped)
+ GetOverlappedResult(m_read, m_read_overlapped, &bytes_read, TRUE);
+ return bytes_read;
+ }
+ return 0; // Return 0 since errno won't be set if we didn't call read
+}
+
+size_t
+Pipe::Write(const void *buf, size_t num_bytes)
+{
+ if (WriteDescriptorIsValid())
+ {
+ DWORD bytes_written = 0;
+ ::WriteFile(m_write, buf, num_bytes, &bytes_written, m_read_overlapped);
+ if (m_write_overlapped)
+ GetOverlappedResult(m_write, m_write_overlapped, &bytes_written, TRUE);
+ return bytes_written;
+ }
+ return 0; // Return 0 since errno won't be set if we didn't call write
+}
diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
index 987a168079a..8e03e7b631e 100644
--- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
@@ -39,6 +39,10 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
+#if defined(_WIN32)
+#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
+#endif
+
using namespace lldb;
using namespace lldb_private;
@@ -598,9 +602,20 @@ ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObjec
// Set output to a temporary file so we can forward the results on to the result object
Pipe pipe;
+#if defined(_WIN32)
+ // By default Windows does not create a pipe object that can be used for a non-blocking read.
+ // We must explicitly request it. Furthermore, we can't use an fd for non-blocking read
+ // operations, and must use the native os HANDLE.
+ if (pipe.Open(true, false))
+ {
+ lldb::file_t read_file = pipe.GetReadNativeHandle();
+ pipe.ReleaseReadFileDescriptor();
+ std::unique_ptr<ConnectionGenericFile> conn_ap(new ConnectionGenericFile(read_file, true));
+#else
if (pipe.Open())
{
std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor(pipe.ReleaseReadFileDescriptor(), true));
+#endif
if (conn_ap->IsConnected())
{
output_comm.SetConnection(conn_ap.release());
OpenPOWER on IntegriCloud