Index: include/lldb/Host/PipeBase.h =================================================================== --- include/lldb/Host/PipeBase.h +++ include/lldb/Host/PipeBase.h @@ -25,6 +25,7 @@ virtual Error CreateNew(bool child_process_inherit) = 0; virtual Error CreateNew(llvm::StringRef name, bool child_process_inherit) = 0; + virtual Error CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit) = 0; virtual Error OpenAsReader(llvm::StringRef name, bool child_process_inherit) = 0; @@ -33,6 +34,7 @@ virtual bool CanRead() const = 0; virtual bool CanWrite() const = 0; + virtual llvm::StringRef GetName() const = 0; virtual int GetReadFileDescriptor() const = 0; virtual int GetWriteFileDescriptor() const = 0; Index: include/lldb/Host/posix/PipePosix.h =================================================================== --- include/lldb/Host/posix/PipePosix.h +++ include/lldb/Host/posix/PipePosix.h @@ -11,7 +11,10 @@ #define liblldb_Host_posix_PipePosix_h_ #if defined(__cplusplus) +#include + #include "lldb/Host/PipeBase.h" +#include "llvm/ADT/SmallString.h" namespace lldb_private { @@ -36,6 +39,8 @@ Error CreateNew(llvm::StringRef name, bool child_process_inherit) override; Error + CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit) override; + Error OpenAsReader(llvm::StringRef name, bool child_process_inherit) override; Error OpenAsWriterWithTimeout(llvm::StringRef name, bool child_process_inherit, const std::chrono::microseconds &timeout) override; @@ -44,6 +49,8 @@ CanRead() const override; bool CanWrite() const override; + llvm::StringRef + GetName() const override; int GetReadFileDescriptor() const override; @@ -73,6 +80,7 @@ CloseWriteFileDescriptor(); int m_fds[2]; + llvm::SmallString m_name; }; } // namespace lldb_private Index: include/lldb/Host/windows/PipeWindows.h =================================================================== --- include/lldb/Host/windows/PipeWindows.h +++ include/lldb/Host/windows/PipeWindows.h @@ -31,11 +31,13 @@ Error CreateNew(bool child_process_inherit) override; Error CreateNew(llvm::StringRef name, bool child_process_inherit) override; + Error CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit) override; Error OpenAsReader(llvm::StringRef name, bool child_process_inherit) override; Error OpenAsWriterWithTimeout(llvm::StringRef name, bool child_process_inherit, const std::chrono::microseconds &timeout) override; bool CanRead() const override; bool CanWrite() const override; + llvm::StringRef GetName() const override; int GetReadFileDescriptor() const override; int GetWriteFileDescriptor() const override; @@ -64,6 +66,7 @@ int m_read_fd; int m_write_fd; + llvm::SmallString<128> m_name; OVERLAPPED m_read_overlapped; OVERLAPPED m_write_overlapped; Index: source/Host/posix/PipePosix.cpp =================================================================== --- source/Host/posix/PipePosix.cpp +++ source/Host/posix/PipePosix.cpp @@ -9,6 +9,8 @@ #include "lldb/Host/posix/PipePosix.h" #include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "llvm/Support/FileSystem.h" #include #include @@ -128,6 +130,7 @@ { m_fds[READ] = PipePosix::kInvalidDescriptor; m_fds[WRITE] = PipePosix::kInvalidDescriptor; + m_name = ""; } PipePosix::~PipePosix() @@ -179,6 +182,39 @@ if (::mkfifo(name.data(), 0660) != 0) error.SetErrorToErrno(); + if (error.Success()) + m_name = name; + + return error; +} + +Error +PipePosix::CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit) +{ + llvm::SmallString named_pipe_path; + llvm::SmallString pipe_spec; + pipe_spec = prefix; + pipe_spec += ".%%%%%%"; + FileSpec tmpdir_file_spec; + tmpdir_file_spec.Clear(); + if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) + { + tmpdir_file_spec.AppendPathComponent(pipe_spec.c_str()); + } + else + { + tmpdir_file_spec.AppendPathComponent("/tmp"); + tmpdir_file_spec.AppendPathComponent(pipe_spec.c_str()); + } + + // It's possible that another process creates the target path after we've + // verified it's available but before we create it, in which case we + // should try again. + Error error; + do { + llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath().c_str(), named_pipe_path); + error = CreateNew(named_pipe_path, child_process_inherit); + } while (error.GetError() == EEXIST); return error; } @@ -195,9 +231,14 @@ Error error; int fd = ::open(name.data(), flags); if (fd != -1) + { + m_name = name; m_fds[READ] = fd; + } else + { error.SetErrorToErrno(); + } return error; } @@ -297,6 +338,12 @@ return m_fds[WRITE] != PipePosix::kInvalidDescriptor; } +llvm::StringRef +PipePosix::GetName() const +{ + return m_name; +} + void PipePosix::CloseReadFileDescriptor() { Index: source/Host/windows/PipeWindows.cpp =================================================================== --- source/Host/windows/PipeWindows.cpp +++ source/Host/windows/PipeWindows.cpp @@ -9,6 +9,7 @@ #include "lldb/Host/windows/PipeWindows.h" +#include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" #include @@ -29,6 +30,7 @@ { m_read = INVALID_HANDLE_VALUE; m_write = INVALID_HANDLE_VALUE; + m_name = ""; m_read_fd = -1; m_write_fd = -1; @@ -90,6 +92,22 @@ } Error +PipeWindows::CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit) +{ + llvm::SmallString<128> name; + Error error; + do { + name = prefix; + name += "-"; + for (unsigned i = 0; i < 6; ++i) { + name += "0123456789abcdef"[llvm::sys::Process::GetRandomNumber() & 15]; + } + Error error = CreateNew(name, child_process_inherit); + } while (error.GetError() == ERROR_ALREADY_EXISTS); + return error; +} + +Error PipeWindows::OpenAsReader(llvm::StringRef name, bool child_process_inherit) { if (CanRead() || CanWrite()) @@ -143,6 +161,7 @@ ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped)); } + m_name = name; return Error(); } @@ -235,6 +254,12 @@ return (m_write != INVALID_HANDLE_VALUE); } +llvm::StringRef +PipeWindows::GetName() +{ + return m_name; +} + HANDLE PipeWindows::GetReadNativeHandle() { Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -779,25 +779,12 @@ { // Binding to port zero, we need to figure out what port it ends up // using using a named pipe... - FileSpec tmpdir_file_spec; - if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) - { - tmpdir_file_spec.AppendPathComponent("debugserver-named-pipe.XXXXXX"); - strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path)); - } - else - { - strncpy(named_pipe_path, "/tmp/debugserver-named-pipe.XXXXXX", sizeof(named_pipe_path)); - } - - if (::mktemp (named_pipe_path)) - { - error = port_named_pipe.CreateNew(named_pipe_path, false); - if (error.Fail()) - return error; - debugserver_args.AppendArgument("--named-pipe"); - debugserver_args.AppendArgument(named_pipe_path); - } + error = port_named_pipe.CreateWithUniqueName("debugserver-named-pipe", false); + if (error.Fail()) + return error; + strncpy(named_pipe_path, port_named_pipe.GetName().str().c_str(), PATH_MAX); + debugserver_args.AppendArgument("--named-pipe"); + debugserver_args.AppendArgument(named_pipe_path); } else {