Index: include/lldb/Target/Process.h =================================================================== --- include/lldb/Target/Process.h +++ include/lldb/Target/Process.h @@ -3180,7 +3180,7 @@ lldb::IOHandlerSP m_process_input_reader; Communication m_stdio_communication; Mutex m_stdio_communication_mutex; - bool m_stdio_disable; /// Remember process launch setting + bool m_stdin_forward; /// Remember if stdin must be forwarded to remote debug server std::string m_stdout_data; std::string m_stderr_data; Mutex m_profile_data_comm_mutex; Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -793,6 +793,18 @@ log->Printf ("ProcessGDBRemote::%s no STDIO paths given via launch_info", __FUNCTION__); } + const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0; + if (stdin_path || disable_stdio) + { + // the inferior will be reading stdin from the specified file + // or stdio is completely disabled + m_stdin_forward = false; + } + else + { + m_stdin_forward = true; + } + // ::LogSetBitMask (GDBR_LOG_DEFAULT); // ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD); // ::LogSetLogFile ("/dev/stdout"); @@ -811,13 +823,23 @@ lldb_utility::PseudoTerminal pty; const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0; - // If the debugserver is local and we aren't disabling STDIO, lets use - // a pseudo terminal to instead of relying on the 'O' packets for stdio - // since 'O' packets can really slow down debugging if the inferior - // does a lot of output. PlatformSP platform_sp (m_target.GetPlatform()); - if (platform_sp && platform_sp->IsHost() && !disable_stdio) + if (disable_stdio) { + // set to /dev/null unless redirected to a file above + if (!stdin_path) + stdin_path = "/dev/null"; + if (!stdout_path) + stdout_path = "/dev/null"; + if (!stderr_path) + stderr_path = "/dev/null"; + } + else if (platform_sp && platform_sp->IsHost()) + { + // If the debugserver is local and we aren't disabling STDIO, lets use + // a pseudo terminal to instead of relying on the 'O' packets for stdio + // since 'O' packets can really slow down debugging if the inferior + // does a lot of output. const char *slave_name = NULL; if (stdin_path == NULL || stdout_path == NULL || stderr_path == NULL) { @@ -841,21 +863,6 @@ stderr_path ? stderr_path : ""); } - // Set STDIN to /dev/null if we want STDIO disabled or if either - // STDOUT or STDERR have been set to something and STDIN hasn't - if (disable_stdio || (stdin_path == NULL && (stdout_path || stderr_path))) - stdin_path = "/dev/null"; - - // Set STDOUT to /dev/null if we want STDIO disabled or if either - // STDIN or STDERR have been set to something and STDOUT hasn't - if (disable_stdio || (stdout_path == NULL && (stdin_path || stderr_path))) - stdout_path = "/dev/null"; - - // Set STDERR to /dev/null if we want STDIO disabled or if either - // STDIN or STDOUT have been set to something and STDERR hasn't - if (disable_stdio || (stderr_path == NULL && (stdin_path || stdout_path))) - stderr_path = "/dev/null"; - if (log) log->Printf ("ProcessGDBRemote::%s final STDIO paths after all adjustments: stdin=%s, stdout=%s, stdout=%s", __FUNCTION__, @@ -942,7 +949,6 @@ SetPrivateState (SetThreadStopInfo (m_last_stop_packet)); - m_stdio_disable = disable_stdio; if (!disable_stdio) { if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd) @@ -2478,7 +2484,7 @@ ConnectionStatus status; m_stdio_communication.Write(src, src_len, status, NULL); } - else if (!m_stdio_disable) + else if (m_stdin_forward) { m_gdb_comm.SendStdinNotification(src, src_len); } Index: source/Target/Process.cpp =================================================================== --- source/Target/Process.cpp +++ source/Target/Process.cpp @@ -720,7 +720,7 @@ m_process_input_reader (), m_stdio_communication ("process.stdio"), m_stdio_communication_mutex (Mutex::eMutexTypeRecursive), - m_stdio_disable(true), + m_stdin_forward (false), m_stdout_data (), m_stderr_data (), m_profile_data_comm_mutex (Mutex::eMutexTypeRecursive), @@ -3907,7 +3907,7 @@ } m_stdio_communication.StopReadThread(); m_stdio_communication.Disconnect(); - m_stdio_disable = true; + m_stdin_forward = false; if (m_process_input_reader) { Index: test/python_api/process/io/TestProcessIO.py =================================================================== --- test/python_api/process/io/TestProcessIO.py +++ test/python_api/process/io/TestProcessIO.py @@ -95,9 +95,13 @@ TestBase.setUp(self) # Get the full path to our executable to be debugged. self.exe = os.path.join(os.getcwd(), "process_io") - self.input_file = os.path.join(os.getcwd(), "input.txt") - self.output_file = os.path.join(os.getcwd(), "output.txt") - self.error_file = os.path.join(os.getcwd(), "error.txt") + self.local_input_file = os.path.join(os.getcwd(), "input.txt") + self.local_output_file = os.path.join(os.getcwd(), "output.txt") + self.local_error_file = os.path.join(os.getcwd(), "error.txt") + + self.input_file = os.path.join(self.get_process_working_directory(), "input.txt") + self.output_file = os.path.join(self.get_process_working_directory(), "output.txt") + self.error_file = os.path.join(self.get_process_working_directory(), "error.txt") self.lines = ["Line 1", "Line 2", "Line 3"] def read_output_file_and_delete (self): @@ -128,15 +132,24 @@ Make the input.txt file to use when redirecting STDIN, setup a cleanup action to delete the input.txt at the end of the test in case exceptions are thrown, and redirect STDIN in the launch info.''' - f = open(self.input_file, 'w') + f = open(self.local_input_file, 'w') for line in self.lines: f.write(line + "\n") f.close() + + if lldb.remote_platform: + self.runCmd('platform put-file "{local}" "{remote}"'.format( + local=self.local_input_file, remote=self.input_file)) + # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): - os.unlink(self.input_file) - + os.unlink(self.local_input_file) + # if lldb.remote_platform: + # TODO: add delete file command + # self.runCmd('platform delete-file "{local}" "{remote}"'.format( + # local=self.local_input_file, remote=self.input_file))''' + # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.launch_info.AddOpenFileAction(0, self.input_file, True, False);