[Lldb-commits] [lldb] r118700 - in /lldb/trunk: include/lldb/Interpreter/ScriptInterpreterPython.h include/lldb/lldb-private-log.h source/Interpreter/ScriptInterpreterPython.cpp source/lldb-log.cpp

Caroline Tice ctice at apple.com
Wed Nov 10 11:18:14 PST 2010


Author: ctice
Date: Wed Nov 10 13:18:14 2010
New Revision: 118700

URL: http://llvm.org/viewvc/llvm-project?rev=118700&view=rev
Log:
Move the embedded Python interpreter onto a separate thread, to prevent
main thread from having to wait on it (which was causing some I/O 
hangs).


Modified:
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
    lldb/trunk/include/lldb/lldb-private-log.h
    lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
    lldb/trunk/source/lldb-log.cpp

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=118700&r1=118699&r2=118700&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Wed Nov 10 13:18:14 2010
@@ -11,6 +11,7 @@
 #ifndef liblldb_ScriptInterpreterPython_h_
 #define liblldb_ScriptInterpreterPython_h_
 
+#include "lldb/lldb-private.h"
 #include "lldb/Interpreter/ScriptInterpreter.h"
 #include "lldb/Core/InputReader.h"
 
@@ -68,6 +69,9 @@
 
     StringList
     ReadCommandInputFromUser (FILE *in_file);
+    
+    static lldb::thread_result_t
+    RunEmbeddedPythonInterpreter (lldb::thread_arg_t baton);
 
 private:
 
@@ -81,6 +85,8 @@
     void *m_compiled_module;
     struct termios m_termios;
     bool m_termios_valid;
+    lldb_utility::PseudoTerminal m_embedded_python_pty;
+    lldb::InputReaderSP m_embedded_thread_input_reader_sp;
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/lldb-private-log.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-log.h?rev=118700&r1=118699&r2=118700&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-private-log.h (original)
+++ lldb/trunk/include/lldb/lldb-private-log.h Wed Nov 10 13:18:14 2010
@@ -36,6 +36,7 @@
 #define LIBLLDB_LOG_HOST                (1u << 14)
 #define LIBLLDB_LOG_UNWIND              (1u << 15)
 #define LIBLLDB_LOG_API                 (1u << 16)
+#define LIBLLDB_LOG_SCRIPT              (1u << 17)
 #define LIBLLDB_LOG_ALL                 (UINT32_MAX)
 #define LIBLLDB_LOG_DEFAULT             (LIBLLDB_LOG_PROCESS              |\
                                          LIBLLDB_LOG_THREAD               |\

Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=118700&r1=118699&r2=118700&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Wed Nov 10 13:18:14 2010
@@ -161,7 +161,10 @@
 ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interpreter) :
     ScriptInterpreter (interpreter, eScriptLanguagePython),
     m_compiled_module (NULL),
-    m_termios_valid (false)
+    m_termios (),
+    m_termios_valid (false),
+    m_embedded_python_pty (),
+    m_embedded_thread_input_reader_sp ()
 {
 
     Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
@@ -342,6 +345,9 @@
     size_t bytes_len
 )
 {
+    lldb::thread_t embedded_interpreter_thread;
+    LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+
     if (baton == NULL)
         return 0;
 
@@ -366,6 +372,37 @@
                 tmp_termios.c_cc[VEOF] = _POSIX_VDISABLE;
                 ::tcsetattr (input_fd, TCSANOW, &tmp_termios);
             }
+            char error_str[1024];
+            if (script_interpreter->m_embedded_python_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, 
+                                                                                    sizeof(error_str)))
+            {
+                if (log)
+                    log->Printf ("ScriptInterpreterPython::InputReaderCallback, Activate, succeeded in opening master pty (fd = %d).",
+                                  script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor());
+                embedded_interpreter_thread = Host::ThreadCreate ("<lldb.script-interpreter.embedded-python-loop>",
+                                                                  ScriptInterpreterPython::RunEmbeddedPythonInterpreter,
+                                                                  script_interpreter, NULL);
+                if (embedded_interpreter_thread != LLDB_INVALID_HOST_THREAD)
+                {
+                    if (log)
+                        log->Printf ("ScriptInterpreterPython::InputReaderCallback, Activate, succeeded in creating thread (thread = %d)", embedded_interpreter_thread);
+                    Error detach_error;
+                    Host::ThreadDetach (embedded_interpreter_thread, &detach_error);
+                }
+                else
+                {
+                    if (log)
+                        log->Printf ("ScriptInterpreterPython::InputReaderCallback, Activate, failed in creating thread");
+                    reader.SetIsDone (true);
+                }
+            }
+            else
+            {
+                if (log)
+                    log->Printf ("ScriptInterpreterPython::InputReaderCallback, Activate, failed to open master pty ");
+                reader.SetIsDone (true);
+            }
+
         }
         break;
 
@@ -376,14 +413,29 @@
         break;
 
     case eInputReaderGotToken:
-        if (bytes && bytes_len)
+        if (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor() != -1)
         {
-            if ((int) bytes[0] == 4)
-                ::write (script_interpreter->GetMasterFileDescriptor(), "quit()", 6);
-            else
-                ::write (script_interpreter->GetMasterFileDescriptor(), bytes, bytes_len);
+            if (log)
+                log->Printf ("ScriptInterpreterPython::InputReaderCallback, GotToken, bytes='%s', byte_len = %d", bytes,
+                             bytes_len);
+            if (bytes && bytes_len)
+            {
+                if ((int) bytes[0] == 4)
+                    ::write (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor(), "quit()", 6);
+                else
+                    ::write (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor(), bytes, bytes_len);
+            }
+            ::write (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor(), "\n", 1);
+        }
+        else
+        {
+            if (log)
+                log->Printf ("ScriptInterpreterPython::InputReaderCallback, GotToken, bytes='%s', byte_len = %d, Master File Descriptor is bad.", 
+                             bytes,
+                             bytes_len);
+            reader.SetIsDone (true);
         }
-        ::write (script_interpreter->GetMasterFileDescriptor(), "\n", 1);
+
         break;
         
     case eInputReaderDone:
@@ -392,6 +444,8 @@
         // Write a newline out to the reader output
         //::fwrite ("\n", 1, 1, out_fh);
         // Restore terminal settings if they were validly saved
+        if (log)
+            log->Printf ("ScriptInterpreterPython::InputReaderCallback, Done, closing down input reader.");
         if (script_interpreter->m_termios_valid)
         {
             int input_fd;
@@ -403,6 +457,7 @@
             
             ::tcsetattr (input_fd, TCSANOW, &script_interpreter->m_termios);
         }
+        script_interpreter->m_embedded_python_pty.CloseMasterFileDescriptor();
         break;
     }
 
@@ -438,8 +493,7 @@
         if (error.Success())
         {
             debugger.PushInputReader (reader_sp);
-            ExecuteOneLine ("run_python_interpreter(ConsoleDict)", NULL);
-            debugger.PopInputReader (reader_sp);
+            m_embedded_thread_input_reader_sp = reader_sp;
         }
     }
 }
@@ -858,3 +912,58 @@
     // trying to call the script function
     return true;
 }
+
+lldb::thread_result_t
+ScriptInterpreterPython::RunEmbeddedPythonInterpreter (lldb::thread_arg_t baton)
+{
+    ScriptInterpreterPython *script_interpreter = (ScriptInterpreterPython *) baton;
+    
+    LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+    
+    if (log)
+        log->Printf ("%p ScriptInterpreterPython::RunEmbeddedPythonInterpreter () thread starting...", baton);
+    
+    char error_str[1024];
+    const char *pty_slave_name = script_interpreter->m_embedded_python_pty.GetSlaveName (error_str, sizeof (error_str));
+    if (pty_slave_name != NULL)
+    {
+        StreamString run_string;
+        PyRun_SimpleString ("save_stderr = sys.stderr");
+        PyRun_SimpleString ("sys.stderr = sys.stdout");
+        PyRun_SimpleString ("save_stdin = sys.stdin");
+        run_string.Printf ("sys.stdin = open ('%s', 'r')", pty_slave_name);
+        PyRun_SimpleString (run_string.GetData());
+        PyRun_SimpleString ("new_mode = tcgetattr(sys.stdin)");
+        PyRun_SimpleString ("new_mode[3] = new_mode[3] | ECHO | ICANON");
+        PyRun_SimpleString ("new_mode[6][VEOF] = 255");
+        PyRun_SimpleString ("tcsetattr (sys.stdin, TCSANOW, new_mode)");
+        
+	    // The following call drops into the embedded interpreter loop and stays there until the
+	    // user chooses to exit from the Python interpreter.
+        script_interpreter->ExecuteOneLine ("run_python_interpreter(ConsoleDict)", NULL);
+        
+        PyRun_SimpleString ("sys.stdin = save_stdin");
+        PyRun_SimpleString ("sys.stderr = save_stderr");
+    }
+    
+    if (script_interpreter->m_embedded_thread_input_reader_sp)
+        script_interpreter->m_embedded_thread_input_reader_sp->SetIsDone (true);
+    
+    script_interpreter->m_embedded_python_pty.CloseSlaveFileDescriptor();
+    
+    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT);
+    if (log)
+        log->Printf ("%p ScriptInterpreterPython::RunEmbeddedPythonInterpreter () thread exiting...", baton);
+    
+
+	// Clean up the input reader and make the debugger pop it off the stack.    
+    Debugger &debugger = script_interpreter->m_interpreter.GetDebugger();
+    const InputReaderSP reader_sp = script_interpreter->m_embedded_thread_input_reader_sp;
+    script_interpreter->m_embedded_thread_input_reader_sp.reset();
+    debugger.PopInputReader (reader_sp);
+        
+    return NULL;
+}
+
+
+

Modified: lldb/trunk/source/lldb-log.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb-log.cpp?rev=118700&r1=118699&r2=118700&view=diff
==============================================================================
--- lldb/trunk/source/lldb-log.cpp (original)
+++ lldb/trunk/source/lldb-log.cpp Wed Nov 10 13:18:14 2010
@@ -120,6 +120,7 @@
             else if (strcasestr(arg, "expr")    == arg) flag_bits &= ~LIBLLDB_LOG_EXPRESSIONS;
             else if (strcasestr(arg, "object")  == arg) flag_bits &= ~LIBLLDB_LOG_OBJECT;
             else if (strcasecmp(arg, "process") == 0  ) flag_bits &= ~LIBLLDB_LOG_PROCESS;
+            else if (strcasecmp(arg, "script") == 0)    flag_bits &= ~LIBLLDB_LOG_SCRIPT;
             else if (strcasecmp(arg, "state")   == 0  ) flag_bits &= ~LIBLLDB_LOG_STATE;
             else if (strcasecmp(arg, "step")    == 0  ) flag_bits &= ~LIBLLDB_LOG_STEP;
             else if (strcasecmp(arg, "thread")  == 0  ) flag_bits &= ~LIBLLDB_LOG_THREAD;
@@ -183,6 +184,7 @@
             else if (strcasestr(arg, "expr")    == arg) flag_bits |= LIBLLDB_LOG_EXPRESSIONS;
             else if (strcasestr(arg, "object")  == arg) flag_bits |= LIBLLDB_LOG_OBJECT;
             else if (strcasecmp(arg, "process") == 0  ) flag_bits |= LIBLLDB_LOG_PROCESS;
+            else if (strcasecmp(arg, "script") == 0)    flag_bits |= LIBLLDB_LOG_SCRIPT;
             else if (strcasecmp(arg, "state")   == 0  ) flag_bits |= LIBLLDB_LOG_STATE;
             else if (strcasecmp(arg, "step")    == 0  ) flag_bits |= LIBLLDB_LOG_STEP;
             else if (strcasecmp(arg, "thread")  == 0  ) flag_bits |= LIBLLDB_LOG_THREAD;
@@ -225,6 +227,7 @@
         "\tobject - log object construction/destruction for important objects\n"
         "\tprocess - log process events and activities\n"
         "\tthread - log thread events and activities\n"
+        "\tscript - log events about the script interpreter\n"
         "\tshlib - log shared library related activities\n"
         "\tstate - log private and public process state changes\n"
         "\tstep - log step related activities\n"





More information about the lldb-commits mailing list