From b2df30d6521069cb2f655213a1b31040f82ee7c3 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Wed, 8 Oct 2014 20:38:41 +0000 Subject: Fix deadlock in Python one-line execution. Python one-line execution was using ConnectionFileDescriptor to do a non-blocking read against a pipe. This won't work on Windows, as CFD is implemented using select(), and select() only works with sockets on Windows. The solution is to use ConnectionGenericFile on Windows, which uses the native API to do overlapped I/O on the pipe. This in turn requires re-implementing Host::Pipe on Windows using native OS handles instead of the more portable _pipe CRT api. Reviewed by: Greg Clayton Differential Revision: http://reviews.llvm.org/D5679 llvm-svn: 219339 --- lldb/source/Interpreter/ScriptInterpreterPython.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'lldb/source/Interpreter/ScriptInterpreterPython.cpp') diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp index 987a168079a4..8e03e7b631e7 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 conn_ap(new ConnectionGenericFile(read_file, true)); +#else if (pipe.Open()) { std::unique_ptr conn_ap(new ConnectionFileDescriptor(pipe.ReleaseReadFileDescriptor(), true)); +#endif if (conn_ap->IsConnected()) { output_comm.SetConnection(conn_ap.release()); -- cgit v1.2.3