diff options
author | Aaron Smith <aaron.smith@microsoft.com> | 2019-01-10 00:46:09 +0000 |
---|---|---|
committer | Aaron Smith <aaron.smith@microsoft.com> | 2019-01-10 00:46:09 +0000 |
commit | e55850be23a09969a3a619c4767d86cd532b1006 (patch) | |
tree | 56a23416bde02de94c18d9a0fcf0af130d74d715 /lldb/source/Host/windows/PipeWindows.cpp | |
parent | b236d7e7a915fa1ddf536d069003b5181a354492 (diff) | |
download | bcm5719-llvm-e55850be23a09969a3a619c4767d86cd532b1006.tar.gz bcm5719-llvm-e55850be23a09969a3a619c4767d86cd532b1006.zip |
[lldb-server] Add unnamed pipe support to PipeWindows
Summary:
This adds unnamed pipe support in PipeWindows to support communication between a debug server and child process.
Modify PipeWindows::CreateNew to support the creation of an unnamed pipe.
Rename the previous method that created a named pipe to PipeWindows::CreateNewNamed.
Reviewers: zturner, llvm-commits
Reviewed By: zturner
Subscribers: Hui, labath, lldb-commits
Differential Revision: https://reviews.llvm.org/D56234
llvm-svn: 350784
Diffstat (limited to 'lldb/source/Host/windows/PipeWindows.cpp')
-rw-r--r-- | lldb/source/Host/windows/PipeWindows.cpp | 79 |
1 files changed, 63 insertions, 16 deletions
diff --git a/lldb/source/Host/windows/PipeWindows.cpp b/lldb/source/Host/windows/PipeWindows.cpp index 1951c9ca193..57221a72899 100644 --- a/lldb/source/Host/windows/PipeWindows.cpp +++ b/lldb/source/Host/windows/PipeWindows.cpp @@ -25,14 +25,41 @@ using namespace lldb_private; namespace { std::atomic<uint32_t> g_pipe_serial(0); +constexpr llvm::StringLiteral g_pipe_name_prefix = "\\\\.\\Pipe\\"; +} // namespace + +PipeWindows::PipeWindows() + : m_read(INVALID_HANDLE_VALUE), m_write(INVALID_HANDLE_VALUE), + m_read_fd(PipeWindows::kInvalidDescriptor), + m_write_fd(PipeWindows::kInvalidDescriptor) { + ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped)); + ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped)); } -PipeWindows::PipeWindows() { - m_read = INVALID_HANDLE_VALUE; - m_write = INVALID_HANDLE_VALUE; +PipeWindows::PipeWindows(pipe_t read, pipe_t write) + : m_read((HANDLE)read), m_write((HANDLE)write), + m_read_fd(PipeWindows::kInvalidDescriptor), + m_write_fd(PipeWindows::kInvalidDescriptor) { + assert(read != LLDB_INVALID_PIPE || write != LLDB_INVALID_PIPE); + + // Don't risk in passing file descriptors and getting handles from them by + // _get_osfhandle since the retrieved handles are highly likely unrecognized + // in the current process and usually crashes the program. Pass handles + // instead since the handle can be inherited. + + if (read != LLDB_INVALID_PIPE) { + m_read_fd = _open_osfhandle((intptr_t)read, _O_RDONLY); + // Make sure the fd and native handle are consistent. + if (m_read_fd < 0) + m_read = INVALID_HANDLE_VALUE; + } + + if (write != LLDB_INVALID_PIPE) { + m_write_fd = _open_osfhandle((intptr_t)write, _O_WRONLY); + if (m_write_fd < 0) + m_write = INVALID_HANDLE_VALUE; + } - m_read_fd = -1; - m_write_fd = -1; ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped)); ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped)); } @@ -40,6 +67,24 @@ PipeWindows::PipeWindows() { PipeWindows::~PipeWindows() { Close(); } Status PipeWindows::CreateNew(bool child_process_inherit) { + // Create an anonymous pipe with the specified inheritance. + SECURITY_ATTRIBUTES sa{sizeof(SECURITY_ATTRIBUTES), 0, + child_process_inherit ? TRUE : FALSE}; + BOOL result = ::CreatePipe(&m_read, &m_write, &sa, 1024); + if (result == FALSE) + return Status(::GetLastError(), eErrorTypeWin32); + + m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY); + ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped)); + m_read_overlapped.hEvent = ::CreateEventA(nullptr, TRUE, FALSE, nullptr); + + m_write_fd = _open_osfhandle((intptr_t)m_write, _O_WRONLY); + ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped)); + + return Status(); +} + +Status PipeWindows::CreateNewNamed(bool child_process_inherit) { // Even for anonymous pipes, we open a named pipe. This is because you // cannot get overlapped i/o on Windows without using a named pipe. So we // synthesize a unique name. @@ -60,7 +105,7 @@ Status PipeWindows::CreateNew(llvm::StringRef name, if (CanRead() || CanWrite()) return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32); - std::string pipe_path = "\\\\.\\Pipe\\"; + std::string pipe_path = g_pipe_name_prefix; pipe_path.append(name); // Always open for overlapped i/o. We implement blocking manually in Read @@ -75,7 +120,8 @@ Status PipeWindows::CreateNew(llvm::StringRef name, ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped)); m_read_overlapped.hEvent = ::CreateEvent(nullptr, TRUE, FALSE, nullptr); - // Open the write end of the pipe. + // Open the write end of the pipe. Note that closing either the read or + // write end of the pipe could directly close the pipe itself. Status result = OpenNamedPipe(name, child_process_inherit, false); if (!result.Success()) { CloseReadFileDescriptor(); @@ -111,7 +157,7 @@ Status PipeWindows::CreateWithUniqueName(llvm::StringRef prefix, Status PipeWindows::OpenAsReader(llvm::StringRef name, bool child_process_inherit) { - if (CanRead() || CanWrite()) + if (CanRead()) return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32); return OpenNamedPipe(name, child_process_inherit, true); @@ -121,7 +167,7 @@ Status PipeWindows::OpenAsWriterWithTimeout(llvm::StringRef name, bool child_process_inherit, const std::chrono::microseconds &timeout) { - if (CanRead() || CanWrite()) + if (CanWrite()) return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32); return OpenNamedPipe(name, child_process_inherit, false); @@ -137,7 +183,7 @@ Status PipeWindows::OpenNamedPipe(llvm::StringRef name, SECURITY_ATTRIBUTES attributes = {}; attributes.bInheritHandle = child_process_inherit; - std::string pipe_path = "\\\\.\\Pipe\\"; + std::string pipe_path = g_pipe_name_prefix; pipe_path.append(name); if (is_read) { @@ -170,9 +216,9 @@ int PipeWindows::GetWriteFileDescriptor() const { return m_write_fd; } int PipeWindows::ReleaseReadFileDescriptor() { if (!CanRead()) - return -1; + return PipeWindows::kInvalidDescriptor; int result = m_read_fd; - m_read_fd = -1; + m_read_fd = PipeWindows::kInvalidDescriptor; if (m_read_overlapped.hEvent) ::CloseHandle(m_read_overlapped.hEvent); m_read = INVALID_HANDLE_VALUE; @@ -182,9 +228,9 @@ int PipeWindows::ReleaseReadFileDescriptor() { int PipeWindows::ReleaseWriteFileDescriptor() { if (!CanWrite()) - return -1; + return PipeWindows::kInvalidDescriptor; int result = m_write_fd; - m_write_fd = -1; + m_write_fd = PipeWindows::kInvalidDescriptor; m_write = INVALID_HANDLE_VALUE; ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped)); return result; @@ -196,9 +242,10 @@ void PipeWindows::CloseReadFileDescriptor() { if (m_read_overlapped.hEvent) ::CloseHandle(m_read_overlapped.hEvent); + _close(m_read_fd); m_read = INVALID_HANDLE_VALUE; - m_read_fd = -1; + m_read_fd = PipeWindows::kInvalidDescriptor; ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped)); } @@ -208,7 +255,7 @@ void PipeWindows::CloseWriteFileDescriptor() { _close(m_write_fd); m_write = INVALID_HANDLE_VALUE; - m_write_fd = -1; + m_write_fd = PipeWindows::kInvalidDescriptor; ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped)); } |