Re: [Lldb-commits] [PATCH] D13836: Fix write-after-close of file descriptor in ScriptInterpreterPython

2015-10-20 Thread Enrico Granata via lldb-commits
granata.enrico accepted this revision.
granata.enrico added a comment.

Looks reasonable


http://reviews.llvm.org/D13836



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


Re: [Lldb-commits] [PATCH] D13836: Fix write-after-close of file descriptor in ScriptInterpreterPython

2015-10-20 Thread Greg Clayton via lldb-commits
clayborg accepted this revision.
clayborg added a comment.
This revision is now accepted and ready to land.

Looks good to me. Wait for Enrico to OK as well.


http://reviews.llvm.org/D13836



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


Re: [Lldb-commits] [PATCH] D13836: Fix write-after-close of file descriptor in ScriptInterpreterPython

2015-10-20 Thread Zachary Turner via lldb-commits
zturner added a comment.

Greg, Enrico, anyone have a chance to take a look at this?  I think it's 
probably just a rubber stamp but rather err on the side of caution.


http://reviews.llvm.org/D13836



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D13836: Fix write-after-close of file descriptor in ScriptInterpreterPython

2015-10-16 Thread Zachary Turner via lldb-commits
zturner created this revision.
zturner added reviewers: clayborg, granata.enrico.
zturner added a subscriber: lldb-commits.

When we acquire the GIL with `Locker`, we save off the current stdio handles, 
redirect them, and when we release the GIL we put the old handles back.  This 
triggers a potential write-after-close, as follows:

In `ScriptInterpreterPython::ExecuteOneLine`, we set up a pipe, lock the gil, 
kick off a thread to do some work, then close the write end of the pipe.  
However, the write end of the pipe in this case is the same thing that we set 
Python's stdout and stderr handles to, and we haven't yet restored them until 
`ExecuteOneLine` ends, due to the scope in which the RAII object is declared.

This has always been fine, but only as a coincidence.  In Python 3 it seems 
that when you set `stderr` to a new file, it writes to the *original* file 
first (probably to flush it).  In the case of `ExecuteOneLine`, that file 
descriptor has been intentionally closed by caller as a means to break the pipe 
and join the other thread it was communicating with, so we get an error.

The fix here is simple: Just acquire the GIL in a tighter scope so that stdin, 
stdout, and stderr are reset to their original values before trying to join the 
read thread.

It doesn't *seem* like we need to hold the GIL any longer than this since no 
Python calls are happening outside of the new smaller scope I've introduced, 
but let me know if you can think of anything wrong with this.

http://reviews.llvm.org/D13836

Files:
  source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
  source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
  source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
  source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h

Index: source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
===
--- source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
+++ source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
@@ -570,9 +570,9 @@
 bool
 GetEmbeddedInterpreterModuleObjects ();
 
-PythonObject m_saved_stdin;
-PythonObject m_saved_stdout;
-PythonObject m_saved_stderr;
+PythonFile m_saved_stdin;
+PythonFile m_saved_stdout;
+PythonFile m_saved_stderr;
 PythonObject m_main_module;
 PythonObject m_lldb_module;
 PythonDictionary m_session_dict;
Index: source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
===
--- source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -612,7 +612,7 @@
 // Flush the file before giving it to python to avoid interleaved output.
 in_file.Flush();
 
-m_saved_stdin = sys_module_dict.GetItemForKey(PythonString("stdin"));
+m_saved_stdin = sys_module_dict.GetItemForKey(PythonString("stdin")).AsType();
 // This call can deadlock your process if the file is locked
 PythonFile new_file(in_file, "r");
 sys_module_dict.SetItemForKey (PythonString("stdin"), new_file);
@@ -626,7 +626,7 @@
 // Flush the file before giving it to python to avoid interleaved output.
 out_file.Flush();
 
-m_saved_stdout = sys_module_dict.GetItemForKey(PythonString("stdout"));
+m_saved_stdout = sys_module_dict.GetItemForKey(PythonString("stdout")).AsType();
 
 PythonFile new_file(out_file, "w");
 sys_module_dict.SetItemForKey (PythonString("stdout"), new_file);
@@ -641,7 +641,7 @@
 // Flush the file before giving it to python to avoid interleaved output.
 err_file.Flush();
 
-m_saved_stderr = sys_module_dict.GetItemForKey(PythonString("stderr"));
+m_saved_stderr = sys_module_dict.GetItemForKey(PythonString("stderr")).AsType();
 
 PythonFile new_file(err_file, "w");
 sys_module_dict.SetItemForKey (PythonString("stderr"), new_file);
@@ -812,48 +812,49 @@
 FILE *in_file = input_file_sp->GetFile().GetStream();
 FILE *out_file = output_file_sp->GetFile().GetStream();
 FILE *err_file = error_file_sp->GetFile().GetStream();
-Locker locker(this,
-  ScriptInterpreterPython::Locker::AcquireLock |
-  ScriptInterpreterPython::Locker::InitSession |
-  (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0) |
-  ((result && result->GetInteractive()) ? 0: Locker::NoSTDIN),
-  ScriptInterpreterPython::Locker::FreeAcquiredLock |
-  ScriptInterpreterPython::Locker::TearDownSession,
-  in_file,
-  out_file,
-