[Lldb-commits] [lldb] r212111 - This creates a valid Python API for Windows, pending some issues. The changes included are -

Zachary Turner zturner at google.com
Tue Jul 1 17:53:19 PDT 2014


Here's a patch that fixes all the stuff I've found so far (except the CMake
warning, haven't looked at that).  Don't want to commit it yet without you
looking at it first though, so PTAL.


On Tue, Jul 1, 2014 at 5:34 PM, Zachary Turner <zturner at google.com> wrote:

>
>
>
> On Tue, Jul 1, 2014 at 10:57 AM, Deepak Panickal <deepak at codeplay.com>
> wrote:
>
>>
>> Modified: lldb/trunk/include/lldb/lldb-python.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-python.h?rev=212111&r1=212110&r2=212111&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/include/lldb/lldb-python.h (original)
>> +++ lldb/trunk/include/lldb/lldb-python.h Tue Jul  1 12:57:19 2014
>> @@ -13,22 +13,46 @@
>>  // Python.h needs to be included before any system headers in order to
>> avoid redefinition of macros
>>
>>  #ifdef LLDB_DISABLE_PYTHON
>> -
>>  // Python is disabled in this build
>> -
>>  #else
>> +       // If this is a visual studio build
>> +       #if defined( _MSC_VER )
>> +               // Special case for debug build since python unfortunately
>> +               // adds library to the linker path through a #pragma
>> directive
>> +               #if defined( _DEBUG )
>> +                       // Python forces a header link to python27_d.lib
>> when building debug.
>> +                       // To get around this (because most python
>> packages for Windows
>> +                       // don't come with debug python libraries), we
>> undefine _DEBUG, include
>> +                       // python.h and then restore _DEBUG.
>> +
>> +                       // The problem with this is that any system level
>> headers included from
>> +                       // python.h were also effectively included in
>> 'release' mode when we undefined
>> +                       // _DEBUG. To work around this we include headers
>> that python includes
>> +                       // before undefining _DEBUG.
>> +                       #           include <stdlib.h>
>> +                       // Undefine to force python to link against the
>> release distro
>> +                       #           undef _DEBUG
>> +                       #           include <Python.h>
>> +                       #           define _DEBUG
>> +
>> +               #else
>> +                       #include <Python.h>
>> +               #endif
>> +
>> +       #else
>> +               #if defined(__linux__)
>> +                       // features.h will define _POSIX_C_SOURCE if
>> _GNU_SOURCE is defined.  This value
>> +                       // may be different from the value that Python
>> defines it to be which results
>> +                       // in a warning.  Undefine _POSIX_C_SOURCE before
>> including Python.h  The same
>> +                       // holds for _XOPEN_SOURCE.
>> +                       #undef _POSIX_C_SOURCE
>> +                       #undef _XOPEN_SOURCE
>> +               #endif
>>
> What about specifying /NODEFAULTLIB:python27_d.lib and then manually link
> against python27.lib instead?  Seems like a better fix.
>
> Another problem with this header is that pymath.h on Windows does a check
> for HAVE_ROUND, and if it's not found it provides its own implementation of
> round().  VS2013 and above provide this function, however.  Could you add a
> line to the CMake along the lines of:
>
> if ((NOT MSVC) OR MSVC12)
>     add_definitions( -DHAVE_ROUND )
> endif()
>
>
>
>
>> Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=212111&r1=212110&r2=212111&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
>> +++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Tue Jul  1
>> 12:57:19 2014
>> @@ -589,7 +589,12 @@ ScriptInterpreterPython::ExecuteOneLine
>>                  input_file_sp = debugger.GetInputFile();
>>                  // Set output to a temporary file so we can forward the
>> results on to the result object
>>
>> +#ifdef _MSC_VER
>> +                // pipe is not supported on windows so default to a fail
>> condition
>> +                int err = 1;
>> +#else
>>                  int err = pipe(pipe_fds);
>> +#endif
>>                  if (err == 0)
>>                  {
>>                      std::unique_ptr<ConnectionFileDescriptor>
>> conn_ap(new ConnectionFileDescriptor(pipe_fds[0], true));
>>
> Windows actually does support pipe, it's just called _pipe and has a
> slightly different signature.  But I think you can make it work.
>
> http://msdn.microsoft.com/en-us/library/edze9h7e.aspx
>
> One more issue is that ScriptInterpreter::TerminateInterpreter() calls
> ScriptInterpreterPython::TerminateInterpreter(), which is not defined, so
> the function calls itself, leading to an infinite recursion warning.  Can
> we fix this warning?
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20140701/6ed33c93/attachment.html>
-------------- next part --------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 47f8771..b422330 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,322 +1,333 @@
 if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
   set(LLDB_DEFAULT_DISABLE_PYTHON 1)
   set(LLDB_DEFAULT_DISABLE_CURSES 1)
+  if (LLDB_DISABLE_PYTHON)
+    set(LLDB_DEFAULT_ENABLE_PYTHON_SCRIPTS_SWIG_API_GENERATION 0)
+  else()
+    set(LLDB_DEFAULT_ENABLE_PYTHON_SCRIPTS_SWIG_API_GENERATION 1)
+  endif()
 else()
   set(LLDB_DEFAULT_DISABLE_PYTHON 0)
   set(LLDB_DEFAULT_DISABLE_CURSES 0)
+  set(LLDB_DEFAULT_ENABLE_PYTHON_SCRIPTS_SWIG_API_GENERATION 0)
 endif()
 set(LLDB_DISABLE_PYTHON ${LLDB_DEFAULT_DISABLE_PYTHON} CACHE BOOL
   "Disables the Python scripting integration.")
 set(LLDB_DISABLE_CURSES ${LLDB_DEFAULT_DISABLE_CURSES} CACHE BOOL
   "Disables the Curses integration.")
-set(LLDB_ENABLE_PYTHON_SCRIPTS_SWIG_API_GENERATION 0 CACHE BOOL
+
+set(LLDB_ENABLE_PYTHON_SCRIPTS_SWIG_API_GENERATION ${LLDB_DEFAULT_ENABLE_PYTHON_SCRIPTS_SWIG_API_GENERATION} CACHE BOOL
   "Enables using new Python scripts for SWIG API generation .")  
 
 # If we are not building as a part of LLVM, build LLDB as an
 # standalone project, using LLVM as an external library:
 if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
   project(lldb)
   cmake_minimum_required(VERSION 2.8)
 
   set(LLDB_PATH_TO_LLVM_SOURCE "" CACHE PATH
     "Path to LLVM source code. Not necessary if using an installed LLVM.")
   set(LLDB_PATH_TO_LLVM_BUILD "" CACHE PATH
     "Path to the directory where LLVM was built or installed.")
 
   set(LLDB_PATH_TO_CLANG_SOURCE "" CACHE PATH
     "Path to Clang source code. Not necessary if using an installed Clang.")
   set(LLDB_PATH_TO_CLANG_BUILD "" CACHE PATH
     "Path to the directory where Clang was built or installed.")
 
   if (LLDB_PATH_TO_LLVM_SOURCE)
     if (NOT EXISTS "${LLDB_PATH_TO_LLVM_SOURCE}/cmake/config-ix.cmake")
       message(FATAL_ERROR "Please set LLDB_PATH_TO_LLVM_SOURCE to the root "
               "directory of LLVM source code.")
     else()
       get_filename_component(LLVM_MAIN_SRC_DIR ${LLDB_PATH_TO_LLVM_SOURCE}
                              ABSOLUTE)
       list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules")
     endif()
   endif()
 
   if (LLDB_PATH_TO_CLANG_SOURCE)
       get_filename_component(CLANG_MAIN_SRC_DIR ${LLDB_PATH_TO_CLANG_SOURCE}
                              ABSOLUTE)
   endif()
 
   list(APPEND CMAKE_MODULE_PATH "${LLDB_PATH_TO_LLVM_BUILD}/share/llvm/cmake")
 
   get_filename_component(PATH_TO_LLVM_BUILD ${LLDB_PATH_TO_LLVM_BUILD}
                          ABSOLUTE)
 
   get_filename_component(PATH_TO_CLANG_BUILD ${LLDB_PATH_TO_CLANG_BUILD}
                          ABSOLUTE)
 
   include(AddLLVM)
   include("${LLDB_PATH_TO_LLVM_BUILD}/share/llvm/cmake/LLVMConfig.cmake")
   include(HandleLLVMOptions)
 
   set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
 
   set(LLVM_MAIN_INCLUDE_DIR "${LLVM_MAIN_SRC_DIR}/include")
   set(LLVM_BINARY_DIR ${CMAKE_BINARY_DIR})
 
   set(CLANG_MAIN_INCLUDE_DIR "${CLANG_MAIN_SRC_DIR}/include")
 
   set(CMAKE_INCLUDE_CURRENT_DIR ON)
   include_directories("${PATH_TO_LLVM_BUILD}/include"
                       "${LLVM_MAIN_INCLUDE_DIR}"
                       "${PATH_TO_CLANG_BUILD}/include"
                       "${CLANG_MAIN_INCLUDE_DIR}"
                       "${CMAKE_CURRENT_SOURCE_DIR}/source")
   link_directories("${PATH_TO_LLVM_BUILD}/lib"
                    "${PATH_TO_CLANG_BUILD}/lib")
 
   set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
   set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
   set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
 
   set(LLDB_BUILT_STANDALONE 1)
 endif()
 
 set(LLDB_DISABLE_PYTHON 0 CACHE BOOL "Disables the Python scripting integration.")
 if (LLDB_DISABLE_PYTHON)
   add_definitions( -DLLDB_DISABLE_PYTHON )
 endif()
 
+if ((NOT MSVC) OR MSVC12)
+  add_definitions( -DHAVE_ROUND )
+endif()
+
 if (LLDB_DISABLE_CURSES)
   add_definitions( -DLLDB_DISABLE_CURSES )
 endif()
 
 macro(add_lldb_definitions)
   # We don't want no semicolons on LLDB_DEFINITIONS:
   foreach(arg ${ARGN})
     set(LLDB_DEFINITIONS "${LLVM_DEFINITIONS} ${arg}")
   endforeach(arg)
   add_definitions( ${ARGN} )
 endmacro(add_lldb_definitions)
 
 if (NOT LLDB_DISABLE_PYTHON)
     if (MSVC)
         # this definition will stop python from auto linking python27_d.lib when Python.h is included
         add_definitions( -DSWIG_PYTHON_INTERPRETER_NO_DEBUG )
     endif()
     find_package(PythonLibs REQUIRED)
     include_directories(${PYTHON_INCLUDE_DIRS})
 endif()
 
 include_directories(../clang/include)
 include_directories("${CMAKE_CURRENT_BINARY_DIR}/../clang/include")
 
 # lldb requires c++11 to build. Make sure that we have a compiler and standard
 # library combination that can do that.
 if (NOT MSVC)
   # gcc and clang require the -std=c++0x or -std=c++11 flag.
   if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR
       "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
     if (NOT ("${CMAKE_CXX_FLAGS}" MATCHES "-std=c\\+\\+0x" OR
              "${CMAKE_CXX_FLAGS}" MATCHES "-std=gnu\\+\\+0x" OR
              "${CMAKE_CXX_FLAGS}" MATCHES "-std=c\\+\\+11" OR
              "${CMAKE_CXX_FLAGS}" MATCHES "-std=gnu\\+\\+11"))
       if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
         if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7")
           set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
         else()
           set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
         endif()
       else()
         set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
       endif()
     endif()
   endif()
 elseif (MSVC_VERSION LESS 1700)
   message(FATAL_ERROR "The selected compiler does not support c++11 which is "
           "required to build lldb.")
 endif()
 
 # Disable GCC warnings
 check_cxx_compiler_flag("-Wno-deprecated-declarations"
                         CXX_SUPPORTS_NO_DEPRECATED_DECLARATIONS)
 if (CXX_SUPPORTS_NO_DEPRECATED_DECLARATIONS)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
 endif ()
 
 check_cxx_compiler_flag("-Wno-unknown-pragmas"
                         CXX_SUPPORTS_NO_UNKNOWN_PRAGMAS)
 if (CXX_SUPPORTS_NO_UNKNOWN_PRAGMAS)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas")
 endif ()
 
 # Disable Clang warnings
 check_cxx_compiler_flag("-Wno-deprecated-register"
                         CXX_SUPPORTS_NO_DEPRECATED_REGISTER)
 if (CXX_SUPPORTS_NO_DEPRECATED_REGISTER)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-register")
 endif ()
 
 # Disable MSVC warnings
 if( MSVC )
   add_lldb_definitions(
     -wd4018 # Suppress 'warning C4018: '>=' : signed/unsigned mismatch'
     -wd4068 # Suppress 'warning C4068: unknown pragma'
     -wd4150 # Suppress 'warning C4150: deletion of pointer to incomplete type'
     -wd4251 # Suppress 'warning C4251: T must have dll-interface to be used by clients of class U.'
     -wd4521 # Suppress 'warning C4521: 'type' : multiple copy constructors specified'
     -wd4530 # Suppress 'warning C4530: C++ exception handler used, but unwind semantics are not enabled.'
   )
 endif() 
 
 # If building on a 32-bit system, make sure off_t can store offsets > 2GB
 if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
   add_lldb_definitions(
     -D_LARGEFILE_SOURCE
     -D_FILE_OFFSET_BITS=64
     )
 endif()
 
 set(LLDB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 set(LLDB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
 
 if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
   message(FATAL_ERROR "In-source builds are not allowed. CMake would overwrite "
 "the makefiles distributed with LLDB. Please create a directory and run cmake "
 "from there, passing the path to this source directory as the last argument. "
 "This process created the file `CMakeCache.txt' and the directory "
 "`CMakeFiles'. Please delete them.")
 endif()
 
 # Compute the LLDB version from the LLVM version.
 string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" LLDB_VERSION
   ${PACKAGE_VERSION})
 message(STATUS "LLDB version: ${LLDB_VERSION}")
 
 macro(add_lldb_library name)
   llvm_process_sources(srcs ${ARGN})
   if (MSVC_IDE OR XCODE)
     string(REGEX MATCHALL "/[^/]+" split_path ${CMAKE_CURRENT_SOURCE_DIR})
     list(GET split_path -1 dir)
     file(GLOB_RECURSE headers
       ../../include/lldb${dir}/*.h)
     set(srcs ${srcs} ${headers})
   endif()
   if (MODULE)
     set(libkind MODULE)
   elseif (SHARED_LIBRARY)
     set(libkind SHARED)
   else()
     set(libkind STATIC)
   endif()
   #PIC not needed on Win
   if (NOT MSVC)
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
   endif()
   llvm_add_library(${name} ${libkind} ${srcs})
   #if (LLVM_COMMON_DEPENDS)
   ##add_dependencies(${name} ${LLVM_COMMON_DEPENDS})
   #endif()
 
   if (CMAKE_VERSION VERSION_LESS 2.8.12 OR NOT "${libkind}" STREQUAL "STATIC")
     set(cmake_2_8_12_INTERFACE)
     set(cmake_2_8_12_PRIVATE)
     set(cmake_2_8_12_PUBLIC)
   else ()
     set(cmake_2_8_12_INTERFACE INTERFACE)
     set(cmake_2_8_12_PRIVATE PRIVATE)
     set(cmake_2_8_12_PUBLIC PUBLIC)
   endif ()
 
   if(LLDB_USED_LIBS)
     # The Darwin linker doesn't understand --start-group/--end-group.
     if (LLVM_COMPILER_IS_GCC_COMPATIBLE AND NOT "${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
       target_link_libraries(${name} ${cmake_2_8_12_PUBLIC}
                             -Wl,--start-group ${LLDB_USED_LIBS} -Wl,--end-group)
     else()
       target_link_libraries(${name} ${cmake_2_8_12_PUBLIC} ${LLDB_USED_LIBS})
     endif()
   endif()
   target_link_libraries(${name} ${cmake_2_8_12_PUBLIC} ${CLANG_USED_LIBS})
   target_link_libraries(${name} ${LLVM_USED_LIBS})
   llvm_config(${name} ${LLVM_LINK_COMPONENTS})
   target_link_libraries(${name} ${LLVM_COMMON_LIBS})
   if (LLVM_COMMON_DEPENDS)
     add_dependencies(${name} ${LLVM_COMMON_DEPENDS})
   endif()
 
   # Hack: only some LLDB libraries depend on the clang autogenerated headers,
   # but it is simple enough to make all of LLDB depend on some of those
   # headers without negatively impacting much of anything.
   set (LLDB_DEPENDENCIES
     libclang
     )
   add_dependencies(${name} ${LLDB_DEPENDENCIES})
 
   install(TARGETS ${name}
     LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
     ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
   set_target_properties(${name} PROPERTIES FOLDER "lldb libraries")
 endmacro(add_lldb_library)
 
 macro(add_lldb_executable name)
   add_llvm_executable(${name} ${ARGN})
   set_target_properties(${name} PROPERTIES FOLDER "lldb executables")
 endmacro(add_lldb_executable)
 
 include_directories(BEFORE
   ${CMAKE_CURRENT_BINARY_DIR}/include
   ${CMAKE_CURRENT_SOURCE_DIR}/include
   )
 
 install(DIRECTORY include/
   DESTINATION include
   FILES_MATCHING
   PATTERN "*.h"
   PATTERN ".svn" EXCLUDE
   )
 
 
 # Find libraries or frameworks that may be needed
 if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
   find_library(CARBON_LIBRARY Carbon)
   find_library(FOUNDATION_LIBRARY Foundation)
   find_library(CORE_FOUNDATION_LIBRARY CoreFoundation)
   find_library(CORE_SERVICES_LIBRARY CoreServices)
   find_library(SECURITY_LIBRARY Security)
   find_library(DEBUG_SYMBOLS_LIBRARY DebugSymbols PATHS "/System/Library/PrivateFrameworks")
 
   if (NOT LIBXML2_FOUND)
     find_package(LibXml2)
   endif ()
   list(APPEND system_libs xml2 ncurses panel)
   list(APPEND system_libs ${CARBON_LIBRARY} ${FOUNDATION_LIBRARY}
   ${CORE_FOUNDATION_LIBRARY} ${CORE_SERVICES_LIBRARY} ${SECURITY_LIBRARY}
   ${DEBUG_SYMBOLS_LIBRARY})
 endif()
 
 if(LLDB_REQUIRES_EH)
   set(LLDB_REQUIRES_RTTI ON)
 else()
   if(LLVM_COMPILER_IS_GCC_COMPATIBLE)
     set(LLDB_COMPILE_FLAGS "${LLDB_COMPILE_FLAGS} -fno-exceptions")
   elseif(MSVC)
     add_definitions( -D_HAS_EXCEPTIONS=0 )
     set(LLDB_COMPILE_FLAGS "${LLDB_COMPILE_FLAGS} /EHs-c-")
   endif()
 endif()
 
 # Disable RTTI by default
 if(NOT LLDB_REQUIRES_RTTI)
   if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
     set(LLDB_COMPILE_FLAGS "${LLDB_COMPILE_FLAGS} -fno-rtti")
   elseif(MSVC)
     set(LLDB_COMPILE_FLAGS "${LLDB_COMPILE_FLAGS} /GR-")
   endif()
 endif()
 
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLDB_COMPILE_FLAGS}")
 
 #add_subdirectory(include)
 add_subdirectory(docs)
 add_subdirectory(scripts)
 add_subdirectory(source)
 add_subdirectory(test)
 add_subdirectory(tools)
diff --git a/include/lldb/Interpreter/ScriptInterpreter.h b/include/lldb/Interpreter/ScriptInterpreter.h
index 82b7f28..10f6a85 100644
--- a/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/include/lldb/Interpreter/ScriptInterpreter.h
@@ -1,583 +1,580 @@
 //===-- ScriptInterpreter.h -------------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef liblldb_ScriptInterpreter_h_
 #define liblldb_ScriptInterpreter_h_
 
 #include "lldb/lldb-private.h"
 
 #include "lldb/Core/Broadcaster.h"
 #include "lldb/Core/Error.h"
 
 #include "lldb/Utility/PseudoTerminal.h"
 
 
 namespace lldb_private {
 
 class ScriptInterpreterObject
 {
 public:
     ScriptInterpreterObject() :
     m_object(NULL)
     {}
     
     ScriptInterpreterObject(void* obj) :
     m_object(obj)
     {}
     
     ScriptInterpreterObject(const ScriptInterpreterObject& rhs)
     : m_object(rhs.m_object)
     {}
     
     virtual void*
     GetObject()
     {
         return m_object;
     }
     
     explicit operator bool ()
     {
         return m_object != NULL;
     }
     
     ScriptInterpreterObject&
     operator = (const ScriptInterpreterObject& rhs)
     {
         if (this != &rhs)
             m_object = rhs.m_object;
         return *this;
     }
         
     virtual
     ~ScriptInterpreterObject()
     {}
     
 protected:
     void* m_object;
 };
     
 class ScriptInterpreterLocker
 {
 public:
     
     ScriptInterpreterLocker ()
     {
     }
     
     virtual ~ScriptInterpreterLocker ()
     {
     }
 private:
     DISALLOW_COPY_AND_ASSIGN (ScriptInterpreterLocker);
 };
 
 
 class ScriptInterpreter
 {
 public:
 
     typedef void (*SWIGInitCallback) (void);
 
     typedef bool (*SWIGBreakpointCallbackFunction) (const char *python_function_name,
                                                     const char *session_dictionary_name,
                                                     const lldb::StackFrameSP& frame_sp,
                                                     const lldb::BreakpointLocationSP &bp_loc_sp);
     
     typedef bool (*SWIGWatchpointCallbackFunction) (const char *python_function_name,
                                                     const char *session_dictionary_name,
                                                     const lldb::StackFrameSP& frame_sp,
                                                     const lldb::WatchpointSP &wp_sp);
     
     typedef bool (*SWIGPythonTypeScriptCallbackFunction) (const char *python_function_name,
                                                           void *session_dictionary,
                                                           const lldb::ValueObjectSP& valobj_sp,
                                                           void** pyfunct_wrapper,
                                                           std::string& retval);
     
     typedef void* (*SWIGPythonCreateSyntheticProvider) (const char *python_class_name,
                                                         const char *session_dictionary_name,
                                                         const lldb::ValueObjectSP& valobj_sp);
 
     typedef void* (*SWIGPythonCreateOSPlugin) (const char *python_class_name,
                                                const char *session_dictionary_name,
                                                const lldb::ProcessSP& process_sp);
     
     typedef uint32_t        (*SWIGPythonCalculateNumChildren)                   (void *implementor);
     typedef void*           (*SWIGPythonGetChildAtIndex)                        (void *implementor, uint32_t idx);
     typedef int             (*SWIGPythonGetIndexOfChildWithName)                (void *implementor, const char* child_name);
     typedef void*           (*SWIGPythonCastPyObjectToSBValue)                  (void* data);
     typedef lldb::ValueObjectSP  (*SWIGPythonGetValueObjectSPFromSBValue)       (void* data);
     typedef bool            (*SWIGPythonUpdateSynthProviderInstance)            (void* data);
     typedef bool            (*SWIGPythonMightHaveChildrenSynthProviderInstance) (void* data);
 
     
     typedef bool            (*SWIGPythonCallCommand)            (const char *python_function_name,
                                                                  const char *session_dictionary_name,
                                                                  lldb::DebuggerSP& debugger,
                                                                  const char* args,
                                                                  lldb_private::CommandReturnObject& cmd_retobj);
     
     typedef bool            (*SWIGPythonCallModuleInit)         (const char *python_module_name,
                                                                  const char *session_dictionary_name,
                                                                  lldb::DebuggerSP& debugger);
     
     typedef bool            (*SWIGPythonScriptKeyword_Process)  (const char* python_function_name,
                                                                  const char* session_dictionary_name,
                                                                  lldb::ProcessSP& process,
                                                                  std::string& output);
     typedef bool            (*SWIGPythonScriptKeyword_Thread)   (const char* python_function_name,
                                                                  const char* session_dictionary_name,
                                                                  lldb::ThreadSP& thread,
                                                                  std::string& output);
     
     typedef bool            (*SWIGPythonScriptKeyword_Target)   (const char* python_function_name,
                                                                  const char* session_dictionary_name,
                                                                  lldb::TargetSP& target,
                                                                  std::string& output);
 
     typedef bool            (*SWIGPythonScriptKeyword_Frame)    (const char* python_function_name,
                                                                  const char* session_dictionary_name,
                                                                  lldb::StackFrameSP& frame,
                                                                  std::string& output);
     
     typedef void*           (*SWIGPython_GetDynamicSetting)     (void* module,
                                                                  const char* setting,
                                                                  const lldb::TargetSP& target_sp);
 
     typedef enum
     {
         eScriptReturnTypeCharPtr,
         eScriptReturnTypeBool,
         eScriptReturnTypeShortInt,
         eScriptReturnTypeShortIntUnsigned,
         eScriptReturnTypeInt,
         eScriptReturnTypeIntUnsigned,
         eScriptReturnTypeLongInt,
         eScriptReturnTypeLongIntUnsigned,
         eScriptReturnTypeLongLong,
         eScriptReturnTypeLongLongUnsigned,
         eScriptReturnTypeFloat,
         eScriptReturnTypeDouble,
         eScriptReturnTypeChar,
         eScriptReturnTypeCharStrOrNone,
         eScriptReturnTypeOpaqueObject
     } ScriptReturnType;
     
     ScriptInterpreter (CommandInterpreter &interpreter, lldb::ScriptLanguage script_lang);
 
     virtual ~ScriptInterpreter ();
 
     struct ExecuteScriptOptions
     {
     public:
         ExecuteScriptOptions () :
             m_enable_io(true),
             m_set_lldb_globals(true),
             m_maskout_errors(true)
         {
         }
         
         bool
         GetEnableIO () const
         {
             return m_enable_io;
         }
         
         bool
         GetSetLLDBGlobals () const
         {
             return m_set_lldb_globals;
         }
         
         bool
         GetMaskoutErrors () const
         {
             return m_maskout_errors;
         }
         
         ExecuteScriptOptions&
         SetEnableIO (bool enable)
         {
             m_enable_io = enable;
             return *this;
         }
 
         ExecuteScriptOptions&
         SetSetLLDBGlobals (bool set)
         {
             m_set_lldb_globals = set;
             return *this;
         }
 
         ExecuteScriptOptions&
         SetMaskoutErrors (bool maskout)
         {
             m_maskout_errors = maskout;
             return *this;
         }
         
     private:
         bool m_enable_io;
         bool m_set_lldb_globals;
         bool m_maskout_errors;
     };
     
     virtual bool
     ExecuteOneLine (const char *command,
                     CommandReturnObject *result,
                     const ExecuteScriptOptions &options = ExecuteScriptOptions()) = 0;
 
     virtual void
     ExecuteInterpreterLoop () = 0;
 
     virtual bool
     ExecuteOneLineWithReturn (const char *in_string,
                               ScriptReturnType return_type,
                               void *ret_value,
                               const ExecuteScriptOptions &options = ExecuteScriptOptions())
     {
         return true;
     }
 
     virtual Error
     ExecuteMultipleLines (const char *in_string,
                           const ExecuteScriptOptions &options = ExecuteScriptOptions())
     {
         Error error;
         error.SetErrorString("not implemented");
         return error;
     }
 
     virtual Error
     ExportFunctionDefinitionToInterpreter (StringList &function_def)
     {
         Error error;
         error.SetErrorString("not implemented");
         return error;
     }
 
     virtual Error
     GenerateBreakpointCommandCallbackData (StringList &input, std::string& output)
     {
         Error error;
         error.SetErrorString("not implemented");
         return error;
     }
     
     virtual bool
     GenerateWatchpointCommandCallbackData (StringList &input, std::string& output)
     {
         return false;
     }
     
     virtual bool
     GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token = NULL)
     {
         return false;
     }
     
     virtual bool
     GenerateTypeScriptFunction (StringList &input, std::string& output, void* name_token = NULL)
     {
         return false;
     }
     
     virtual bool
     GenerateScriptAliasFunction (StringList &input, std::string& output)
     {
         return false;
     }
     
     virtual bool
     GenerateTypeSynthClass (StringList &input, std::string& output, void* name_token = NULL)
     {
         return false;
     }
     
     virtual bool
     GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token = NULL)
     {
         return false;
     }
     
     virtual lldb::ScriptInterpreterObjectSP
     CreateSyntheticScriptedProvider (const char *class_name,
                                      lldb::ValueObjectSP valobj)
     {
         return lldb::ScriptInterpreterObjectSP();
     }
     
     virtual lldb::ScriptInterpreterObjectSP
     OSPlugin_CreatePluginObject (const char *class_name,
                                  lldb::ProcessSP process_sp)
     {
         return lldb::ScriptInterpreterObjectSP();
     }
     
     virtual lldb::ScriptInterpreterObjectSP
     OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
     {
         return lldb::ScriptInterpreterObjectSP();
     }
     
     virtual lldb::ScriptInterpreterObjectSP
     OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
     {
         return lldb::ScriptInterpreterObjectSP();
     }
     
     virtual lldb::ScriptInterpreterObjectSP
     OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
                                   lldb::tid_t thread_id)
     {
         return lldb::ScriptInterpreterObjectSP();
     }
 
     virtual lldb::ScriptInterpreterObjectSP
     OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
                            lldb::tid_t tid,
                            lldb::addr_t context)
     {
         return lldb::ScriptInterpreterObjectSP();
     }
     
     virtual lldb::ScriptInterpreterObjectSP
     LoadPluginModule (const FileSpec& file_spec,
                      lldb_private::Error& error)
     {
         return lldb::ScriptInterpreterObjectSP();
     }
     
     virtual lldb::ScriptInterpreterObjectSP
     GetDynamicSettings (lldb::ScriptInterpreterObjectSP plugin_module_sp,
                         Target* target,
                         const char* setting_name,
                         lldb_private::Error& error)
     {
         return lldb::ScriptInterpreterObjectSP();
     }
 
     virtual Error
     GenerateFunction(const char *signature, const StringList &input)
     {
         Error error;
         error.SetErrorString("unimplemented");
         return error;
     }
 
     virtual void 
     CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
                                              CommandReturnObject &result);
 
     virtual void 
     CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
                                              CommandReturnObject &result);
 
     /// Set the specified text as the callback for the breakpoint.
     virtual Error
     SetBreakpointCommandCallback (BreakpointOptions *bp_options,
                                   const char *callback_text)
     {
         Error error;
         error.SetErrorString("unimplemented");
         return error;
     }
     
     /// Set a one-liner as the callback for the breakpoint.
     virtual void 
     SetBreakpointCommandCallbackFunction (BreakpointOptions *bp_options,
                                   const char *function_name)
     {
         return;
     }
     
     /// Set a one-liner as the callback for the watchpoint.
     virtual void 
     SetWatchpointCommandCallback (WatchpointOptions *wp_options,
                                   const char *oneliner)
     {
         return;
     }
     
     virtual bool
     GetScriptedSummary (const char *function_name,
                         lldb::ValueObjectSP valobj,
                         lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
                         std::string& retval)
     {
         return false;
     }
     
     virtual void
     Clear ()
     {
         // Clean up any ref counts to SBObjects that might be in global variables
     }
     
     virtual size_t
     CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor)
     {
         return 0;
     }
     
     virtual lldb::ValueObjectSP
     GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor, uint32_t idx)
     {
         return lldb::ValueObjectSP();
     }
     
     virtual int
     GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor, const char* child_name)
     {
         return UINT32_MAX;
     }
     
     virtual bool
     UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor)
     {
         return false;
     }
     
     virtual bool
     MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor)
     {
         return true;
     }
     
     virtual bool
     RunScriptBasedCommand (const char* impl_function,
                            const char* args,
                            ScriptedCommandSynchronicity synchronicity,
                            lldb_private::CommandReturnObject& cmd_retobj,
                            Error& error)
     {
         return false;
     }
     
     virtual bool
     RunScriptFormatKeyword (const char* impl_function,
                             Process* process,
                             std::string& output,
                             Error& error)
     {
         error.SetErrorString("unimplemented");
         return false;
     }
 
     virtual bool
     RunScriptFormatKeyword (const char* impl_function,
                             Thread* thread,
                             std::string& output,
                             Error& error)
     {
         error.SetErrorString("unimplemented");
         return false;
     }
     
     virtual bool
     RunScriptFormatKeyword (const char* impl_function,
                             Target* target,
                             std::string& output,
                             Error& error)
     {
         error.SetErrorString("unimplemented");
         return false;
     }
     
     virtual bool
     RunScriptFormatKeyword (const char* impl_function,
                             StackFrame* frame,
                             std::string& output,
                             Error& error)
     {
         error.SetErrorString("unimplemented");
         return false;
     }
     
     virtual bool
     GetDocumentationForItem (const char* item, std::string& dest)
     {
 		dest.clear();
         return false;
     }
     
     virtual bool
     CheckObjectExists (const char* name)
     {
         return false;
     }
 
     virtual bool
     LoadScriptingModule (const char* filename,
                          bool can_reload,
                          bool init_session,
                          lldb_private::Error& error,
                          lldb::ScriptInterpreterObjectSP* module_sp = nullptr)
     {
         error.SetErrorString("loading unimplemented");
         return false;
     }
 
     virtual lldb::ScriptInterpreterObjectSP
     MakeScriptObject (void* object)
     {
         return lldb::ScriptInterpreterObjectSP(new ScriptInterpreterObject(object));
     }
     
     virtual std::unique_ptr<ScriptInterpreterLocker>
     AcquireInterpreterLock ();
     
     const char *
     GetScriptInterpreterPtyName ();
 
     int
     GetMasterFileDescriptor ();
 
 	CommandInterpreter &
 	GetCommandInterpreter ();
 
     static std::string
     LanguageToString (lldb::ScriptLanguage language);
     
     static void
     InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
                            SWIGBreakpointCallbackFunction swig_breakpoint_callback,
                            SWIGWatchpointCallbackFunction swig_watchpoint_callback,
                            SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
                            SWIGPythonCreateSyntheticProvider swig_synthetic_script,
                            SWIGPythonCalculateNumChildren swig_calc_children,
                            SWIGPythonGetChildAtIndex swig_get_child_index,
                            SWIGPythonGetIndexOfChildWithName swig_get_index_child,
                            SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue ,
                            SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
                            SWIGPythonUpdateSynthProviderInstance swig_update_provider,
                            SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
                            SWIGPythonCallCommand swig_call_command,
                            SWIGPythonCallModuleInit swig_call_module_init,
                            SWIGPythonCreateOSPlugin swig_create_os_plugin,
                            SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
                            SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
                            SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
                            SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
                            SWIGPython_GetDynamicSetting swig_plugin_get);
 
-    static void
-    TerminateInterpreter ();
-
     virtual void
     ResetOutputFileHandle (FILE *new_fh) { } //By default, do nothing.
 
 protected:
     CommandInterpreter &m_interpreter;
     lldb::ScriptLanguage m_script_lang;
 };
 
 } // namespace lldb_private
 
 #endif // #ifndef liblldb_ScriptInterpreter_h_
diff --git a/source/Interpreter/ScriptInterpreter.cpp b/source/Interpreter/ScriptInterpreter.cpp
index 1b751af..561e881 100644
--- a/source/Interpreter/ScriptInterpreter.cpp
+++ b/source/Interpreter/ScriptInterpreter.cpp
@@ -1,143 +1,134 @@
 //===-- ScriptInterpreter.cpp -----------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 
 #include "lldb/lldb-python.h"
 
 #include "lldb/Interpreter/ScriptInterpreter.h"
 
 #include <string>
 #include <stdlib.h>
 #include <stdio.h>
 
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/StringList.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/ScriptInterpreterPython.h"
 #include "lldb/Utility/PseudoTerminal.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
 ScriptInterpreter::ScriptInterpreter (CommandInterpreter &interpreter, lldb::ScriptLanguage script_lang) :
     m_interpreter (interpreter),
     m_script_lang (script_lang)
 {
 }
 
 ScriptInterpreter::~ScriptInterpreter ()
 {
 }
 
 CommandInterpreter &
 ScriptInterpreter::GetCommandInterpreter ()
 {
     return m_interpreter;
 }
 
 void 
 ScriptInterpreter::CollectDataForBreakpointCommandCallback 
 (
     BreakpointOptions *bp_options,
     CommandReturnObject &result
 )
 {
     result.SetStatus (eReturnStatusFailed);
     result.AppendError ("ScriptInterpreter::GetScriptCommands(StringList &) is not implemented.");
 }
 
 void 
 ScriptInterpreter::CollectDataForWatchpointCommandCallback 
 (
     WatchpointOptions *bp_options,
     CommandReturnObject &result
 )
 {
     result.SetStatus (eReturnStatusFailed);
     result.AppendError ("ScriptInterpreter::GetScriptCommands(StringList &) is not implemented.");
 }
 
 std::string
 ScriptInterpreter::LanguageToString (lldb::ScriptLanguage language)
 {
     std::string return_value;
 
     switch (language)
     {
         case eScriptLanguageNone:
             return_value = "None";
             break;
         case eScriptLanguagePython:
             return_value = "Python";
             break;
     }
 
     return return_value;
 }
 
 std::unique_ptr<ScriptInterpreterLocker>
 ScriptInterpreter::AcquireInterpreterLock ()
 {
     return std::unique_ptr<ScriptInterpreterLocker>(new ScriptInterpreterLocker());
 }
 
 void
 ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
                                           SWIGBreakpointCallbackFunction swig_breakpoint_callback,
                                           SWIGWatchpointCallbackFunction swig_watchpoint_callback,
                                           SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
                                           SWIGPythonCreateSyntheticProvider swig_synthetic_script,
                                           SWIGPythonCalculateNumChildren swig_calc_children,
                                           SWIGPythonGetChildAtIndex swig_get_child_index,
                                           SWIGPythonGetIndexOfChildWithName swig_get_index_child,
                                           SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue ,
                                           SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
                                           SWIGPythonUpdateSynthProviderInstance swig_update_provider,
                                           SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
                                           SWIGPythonCallCommand swig_call_command,
                                           SWIGPythonCallModuleInit swig_call_module_init,
                                           SWIGPythonCreateOSPlugin swig_create_os_plugin,
                                           SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
                                           SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
                                           SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
                                           SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
                                           SWIGPython_GetDynamicSetting swig_plugin_get)
 {
 #ifndef LLDB_DISABLE_PYTHON
     ScriptInterpreterPython::InitializeInterpreter (python_swig_init_callback,
                                                     swig_breakpoint_callback,
                                                     swig_watchpoint_callback,
                                                     swig_typescript_callback,
                                                     swig_synthetic_script,
                                                     swig_calc_children,
                                                     swig_get_child_index,
                                                     swig_get_index_child,
                                                     swig_cast_to_sbvalue ,
                                                     swig_get_valobj_sp_from_sbvalue,
                                                     swig_update_provider,
                                                     swig_mighthavechildren_provider,
                                                     swig_call_command,
                                                     swig_call_module_init,
                                                     swig_create_os_plugin,
                                                     swig_run_script_keyword_process,
                                                     swig_run_script_keyword_thread,
                                                     swig_run_script_keyword_target,
                                                     swig_run_script_keyword_frame,
                                                     swig_plugin_get);
 #endif // #ifndef LLDB_DISABLE_PYTHON
 }
-
-void
-ScriptInterpreter::TerminateInterpreter ()
-{
-#ifndef LLDB_DISABLE_PYTHON
-    ScriptInterpreterPython::TerminateInterpreter ();
-#endif // #ifndef LLDB_DISABLE_PYTHON
-}
-
diff --git a/source/Interpreter/ScriptInterpreterPython.cpp b/source/Interpreter/ScriptInterpreterPython.cpp
index ef0d71b..76b8b6e 100644
--- a/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/source/Interpreter/ScriptInterpreterPython.cpp
@@ -1,2660 +1,2660 @@
 //===-- ScriptInterpreterPython.cpp -----------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
 // This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 
 // In order to guarantee correct working with Python, Python.h *MUST* be
 // the *FIRST* header file included here.
 #ifdef LLDB_DISABLE_PYTHON
 
 // Python is disabled in this build
 
 #else
 
 #include "lldb/lldb-python.h"
 #include "lldb/Interpreter/ScriptInterpreterPython.h"
 
 #include <stdlib.h>
 #include <stdio.h>
 
 #include <string>
 
 #include "lldb/API/SBValue.h"
 #include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Breakpoint/StoppointCallbackContext.h"
 #include "lldb/Breakpoint/WatchpointOptions.h"
 #include "lldb/Core/Communication.h"
 #include "lldb/Core/ConnectionFileDescriptor.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Timer.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/PythonDataObjects.h"
 #include "lldb/Target/Thread.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
 
 static ScriptInterpreter::SWIGInitCallback g_swig_init_callback = nullptr;
 static ScriptInterpreter::SWIGBreakpointCallbackFunction g_swig_breakpoint_callback = nullptr;
 static ScriptInterpreter::SWIGWatchpointCallbackFunction g_swig_watchpoint_callback = nullptr;
 static ScriptInterpreter::SWIGPythonTypeScriptCallbackFunction g_swig_typescript_callback = nullptr;
 static ScriptInterpreter::SWIGPythonCreateSyntheticProvider g_swig_synthetic_script = nullptr;
 static ScriptInterpreter::SWIGPythonCalculateNumChildren g_swig_calc_children = nullptr;
 static ScriptInterpreter::SWIGPythonGetChildAtIndex g_swig_get_child_index = nullptr;
 static ScriptInterpreter::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = nullptr;
 static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue  = nullptr;
 static ScriptInterpreter::SWIGPythonGetValueObjectSPFromSBValue g_swig_get_valobj_sp_from_sbvalue = nullptr;
 static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = nullptr;
 static ScriptInterpreter::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = nullptr;
 static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = nullptr;
 static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = nullptr;
 static ScriptInterpreter::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = nullptr;
 static ScriptInterpreter::SWIGPythonScriptKeyword_Process g_swig_run_script_keyword_process = nullptr;
 static ScriptInterpreter::SWIGPythonScriptKeyword_Thread g_swig_run_script_keyword_thread = nullptr;
 static ScriptInterpreter::SWIGPythonScriptKeyword_Target g_swig_run_script_keyword_target = nullptr;
 static ScriptInterpreter::SWIGPythonScriptKeyword_Frame g_swig_run_script_keyword_frame = nullptr;
 static ScriptInterpreter::SWIGPython_GetDynamicSetting g_swig_plugin_get = nullptr;
 
 static std::string
 ReadPythonBacktrace (PyObject* py_backtrace);
 
 ScriptInterpreterPython::Locker::Locker (ScriptInterpreterPython *py_interpreter,
                                          uint16_t on_entry,
                                          uint16_t on_leave,
                                          FILE *in,
                                          FILE *out,
                                          FILE *err) :
     ScriptInterpreterLocker (),
     m_teardown_session( (on_leave & TearDownSession) == TearDownSession ),
     m_python_interpreter(py_interpreter)
 {
     DoAcquireLock();
     if ((on_entry & InitSession) == InitSession)
     {
         if (DoInitSession(on_entry, in, out, err) == false)
         {
             // Don't teardown the session if we didn't init it.
             m_teardown_session = false;
         }
     }
 }
 
 bool
 ScriptInterpreterPython::Locker::DoAcquireLock()
 {
     Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
     m_GILState = PyGILState_Ensure();
     if (log)
         log->Printf("Ensured PyGILState. Previous state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
     
     // we need to save the thread state when we first start the command
     // because we might decide to interrupt it while some action is taking
     // place outside of Python (e.g. printing to screen, waiting for the network, ...)
     // in that case, _PyThreadState_Current will be NULL - and we would be unable
     // to set the asynchronous exception - not a desirable situation
     m_python_interpreter->SetThreadState (_PyThreadState_Current);
     return true;
 }
 
 bool
 ScriptInterpreterPython::Locker::DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err)
 {
     if (!m_python_interpreter)
         return false;
     return m_python_interpreter->EnterSession (on_entry_flags, in, out, err);
 }
 
 bool
 ScriptInterpreterPython::Locker::DoFreeLock()
 {
     Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
     if (log)
         log->Printf("Releasing PyGILState. Returning to state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
     PyGILState_Release(m_GILState);
     return true;
 }
 
 bool
 ScriptInterpreterPython::Locker::DoTearDownSession()
 {
     if (!m_python_interpreter)
         return false;
     m_python_interpreter->LeaveSession ();
     return true;
 }
 
 ScriptInterpreterPython::Locker::~Locker()
 {
     if (m_teardown_session)
         DoTearDownSession();
     DoFreeLock();
 }
 
 
 ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interpreter) :
     ScriptInterpreter (interpreter, eScriptLanguagePython),
     IOHandlerDelegateMultiline("DONE"),
     m_saved_stdin (),
     m_saved_stdout (),
     m_saved_stderr (),
     m_main_module (),
     m_lldb_module (),
     m_session_dict (false),     // Don't create an empty dictionary, leave it invalid
     m_sys_module_dict (false),  // Don't create an empty dictionary, leave it invalid
     m_run_one_line_function (),
     m_run_one_line_str_global (),
     m_dictionary_name (interpreter.GetDebugger().GetInstanceName().AsCString()),
     m_terminal_state (),
     m_active_io_handler (eIOHandlerNone),
     m_session_is_active (false),
     m_pty_slave_is_open (false),
     m_valid_session (true),
     m_command_thread_state (nullptr)
 {
 
     ScriptInterpreterPython::InitializePrivate ();
 
     m_dictionary_name.append("_dict");
     StreamString run_string;
     run_string.Printf ("%s = dict()", m_dictionary_name.c_str());
 
     Locker locker(this,
                   ScriptInterpreterPython::Locker::AcquireLock,
                   ScriptInterpreterPython::Locker::FreeAcquiredLock);
     PyRun_SimpleString (run_string.GetData());
 
     run_string.Clear();
 
     // Importing 'lldb' module calls SBDebugger::Initialize, which calls Debugger::Initialize, which increments a
     // global debugger ref-count; therefore we need to check the ref-count before and after importing lldb, and if the
     // ref-count increased we need to call Debugger::Terminate here to decrement the ref-count so that when the final 
     // call to Debugger::Terminate is made, the ref-count has the correct value. 
     //
     // Bonus question:  Why doesn't the ref-count always increase?  Because sometimes lldb has already been imported, in
     // which case the code inside it, including the call to SBDebugger::Initialize(), does not get executed.
     
     int old_count = Debugger::TestDebuggerRefCount();
     
     run_string.Printf ("run_one_line (%s, 'import copy, os, re, sys, uuid, lldb')", m_dictionary_name.c_str());
     PyRun_SimpleString (run_string.GetData());
 
     // WARNING: temporary code that loads Cocoa formatters - this should be done on a per-platform basis rather than loading the whole set
     // and letting the individual formatter classes exploit APIs to check whether they can/cannot do their task
     run_string.Clear();
     run_string.Printf ("run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp, pydoc')", m_dictionary_name.c_str());
     PyRun_SimpleString (run_string.GetData());
     run_string.Clear();
 
     int new_count = Debugger::TestDebuggerRefCount();
     
     if (new_count > old_count)
         Debugger::Terminate();
 
     run_string.Printf ("run_one_line (%s, 'import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line')", m_dictionary_name.c_str());
     PyRun_SimpleString (run_string.GetData());
     run_string.Clear();
     
     run_string.Printf ("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64 "; pydoc.pager = pydoc.plainpager')", m_dictionary_name.c_str(),
                        interpreter.GetDebugger().GetID());
     PyRun_SimpleString (run_string.GetData());
 }
 
 ScriptInterpreterPython::~ScriptInterpreterPython ()
 {
 }
 
 void
 ScriptInterpreterPython::IOHandlerActivated (IOHandler &io_handler)
 {
     const char *instructions = nullptr;
     
     switch (m_active_io_handler)
     {
     case eIOHandlerNone:
             break;
     case eIOHandlerBreakpoint:
             instructions = R"(Enter your Python command(s). Type 'DONE' to end.
 def function (frame, bp_loc, internal_dict):
     """frame: the lldb.SBFrame for the location at which you stopped
        bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
        internal_dict: an LLDB support object not to be used"""
 )";
             break;
     case eIOHandlerWatchpoint:
             instructions = "Enter your Python command(s). Type 'DONE' to end.\n";
             break;
     }
     
     if (instructions)
     {
         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
         if (output_sp)
         {
             output_sp->PutCString(instructions);
             output_sp->Flush();
         }
     }
 }
 
 void
 ScriptInterpreterPython::IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
 {
     io_handler.SetIsDone(true);
     bool batch_mode = m_interpreter.GetBatchCommandMode();
 
     switch (m_active_io_handler)
     {
     case eIOHandlerNone:
         break;
     case eIOHandlerBreakpoint:
         {
             BreakpointOptions *bp_options = (BreakpointOptions *)io_handler.GetUserData();
             std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
             if (data_ap.get())
             {
                 data_ap->user_source.SplitIntoLines(data);
                 
                 if (GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source).Success())
                 {
                     BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
                     bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
                 }
                 else if (!batch_mode)
                 {
                     StreamFileSP error_sp = io_handler.GetErrorStreamFile();
                     if (error_sp)
                     {
                         error_sp->Printf ("Warning: No command attached to breakpoint.\n");
                         error_sp->Flush();
                     }
                 }
             }
             m_active_io_handler = eIOHandlerNone;
         }
         break;
     case eIOHandlerWatchpoint:
         {
             WatchpointOptions *wp_options = (WatchpointOptions *)io_handler.GetUserData();
             std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
             if (data_ap.get())
             {
                 data_ap->user_source.SplitIntoLines(data);
                 
                 if (GenerateWatchpointCommandCallbackData (data_ap->user_source, data_ap->script_source))
                 {
                     BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
                     wp_options->SetCallback (ScriptInterpreterPython::WatchpointCallbackFunction, baton_sp);
                 }
                 else if (!batch_mode)
                 {
                     StreamFileSP error_sp = io_handler.GetErrorStreamFile();
                     if (error_sp)
                     {
                         error_sp->Printf ("Warning: No command attached to breakpoint.\n");
                         error_sp->Flush();
                     }
                 }
             }
             m_active_io_handler = eIOHandlerNone;
         }
         break;
     }
 
 
 }
 
 
 void
 ScriptInterpreterPython::ResetOutputFileHandle (FILE *fh)
 {
 }
 
 void
 ScriptInterpreterPython::SaveTerminalState (int fd)
 {
     // Python mucks with the terminal state of STDIN. If we can possibly avoid
     // this by setting the file handles up correctly prior to entering the
     // interpreter we should. For now we save and restore the terminal state
     // on the input file handle.
     m_terminal_state.Save (fd, false);
 }
 
 void
 ScriptInterpreterPython::RestoreTerminalState ()
 {
     // Python mucks with the terminal state of STDIN. If we can possibly avoid
     // this by setting the file handles up correctly prior to entering the
     // interpreter we should. For now we save and restore the terminal state
     // on the input file handle.
     m_terminal_state.Restore();
 }
 
 void
 ScriptInterpreterPython::LeaveSession ()
 {
     Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
     if (log)
         log->PutCString("ScriptInterpreterPython::LeaveSession()");
 
     // checking that we have a valid thread state - since we use our own threading and locking
     // in some (rare) cases during cleanup Python may end up believing we have no thread state
     // and PyImport_AddModule will crash if that is the case - since that seems to only happen
     // when destroying the SBDebugger, we can make do without clearing up stdout and stderr
 
     // rdar://problem/11292882
     // When the current thread state is NULL, PyThreadState_Get() issues a fatal error.
     if (PyThreadState_GetDict())
     {
         PythonDictionary &sys_module_dict = GetSysModuleDictionary ();
         if (sys_module_dict)
         {
             if (m_saved_stdin)
             {
                 sys_module_dict.SetItemForKey("stdin", m_saved_stdin);
                 m_saved_stdin.Reset ();
             }
             if (m_saved_stdout)
             {
                 sys_module_dict.SetItemForKey("stdout", m_saved_stdout);
                 m_saved_stdout.Reset ();
             }
             if (m_saved_stderr)
             {
                 sys_module_dict.SetItemForKey("stderr", m_saved_stderr);
                 m_saved_stderr.Reset ();
             }
         }
     }
 
     m_session_is_active = false;
 }
 
 bool
 ScriptInterpreterPython::EnterSession (uint16_t on_entry_flags,
                                        FILE *in,
                                        FILE *out,
                                        FILE *err)
 {
     // If we have already entered the session, without having officially 'left' it, then there is no need to 
     // 'enter' it again.
     Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
     if (m_session_is_active)
     {
         if (log)
             log->Printf("ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ") session is already active, returning without doing anything", on_entry_flags);
         return false;
     }
 
     if (log)
         log->Printf("ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ")", on_entry_flags);
     
 
     m_session_is_active = true;
 
     StreamString run_string;
 
     if (on_entry_flags & Locker::InitGlobals)
     {
         run_string.Printf (    "run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
         run_string.Printf (    "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", GetCommandInterpreter().GetDebugger().GetID());
         run_string.PutCString ("; lldb.target = lldb.debugger.GetSelectedTarget()");
         run_string.PutCString ("; lldb.process = lldb.target.GetProcess()");
         run_string.PutCString ("; lldb.thread = lldb.process.GetSelectedThread ()");
         run_string.PutCString ("; lldb.frame = lldb.thread.GetSelectedFrame ()");
         run_string.PutCString ("')");
     }
     else
     {
         // If we aren't initing the globals, we should still always set the debugger (since that is always unique.)
         run_string.Printf (    "run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
         run_string.Printf (    "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", GetCommandInterpreter().GetDebugger().GetID());
         run_string.PutCString ("')");
     }
 
     PyRun_SimpleString (run_string.GetData());
     run_string.Clear();
 
     PythonDictionary &sys_module_dict = GetSysModuleDictionary ();
     if (sys_module_dict)
     {
         lldb::StreamFileSP in_sp;
         lldb::StreamFileSP out_sp;
         lldb::StreamFileSP err_sp;
         if (in == nullptr || out == nullptr || err == nullptr)
             m_interpreter.GetDebugger().AdoptTopIOHandlerFilesIfInvalid (in_sp, out_sp, err_sp);
 
         if (in == nullptr && in_sp && (on_entry_flags & Locker::NoSTDIN) == 0)
             in = in_sp->GetFile().GetStream();
         if (in)
         {
             m_saved_stdin.Reset(sys_module_dict.GetItemForKey("stdin"));
 
             PyObject *new_file = PyFile_FromFile (in, (char *) "", (char *) "r", nullptr);
             sys_module_dict.SetItemForKey ("stdin", new_file);
             Py_DECREF (new_file);
         }
         else
             m_saved_stdin.Reset();
         
         if (out == nullptr && out_sp)
             out = out_sp->GetFile().GetStream();
         if (out)
         {
             m_saved_stdout.Reset(sys_module_dict.GetItemForKey("stdout"));
 
             PyObject *new_file = PyFile_FromFile (out, (char *) "", (char *) "w", nullptr);
             sys_module_dict.SetItemForKey ("stdout", new_file);
             Py_DECREF (new_file);
         }
         else
             m_saved_stdout.Reset();
 
         if (err == nullptr && err_sp)
             err = err_sp->GetFile().GetStream();
         if (err)
         {
             m_saved_stderr.Reset(sys_module_dict.GetItemForKey("stderr"));
 
             PyObject *new_file = PyFile_FromFile (err, (char *) "", (char *) "w", nullptr);
             sys_module_dict.SetItemForKey ("stderr", new_file);
             Py_DECREF (new_file);
         }
         else
             m_saved_stderr.Reset();
     }
 
     if (PyErr_Occurred())
         PyErr_Clear ();
     
     return true;
 }
 
 PythonObject &
 ScriptInterpreterPython::GetMainModule ()
 {
     if (!m_main_module)
         m_main_module.Reset(PyImport_AddModule ("__main__"));
     return m_main_module;
 }
 
 PythonDictionary &
 ScriptInterpreterPython::GetSessionDictionary ()
 {
     if (!m_session_dict)
     {
         PythonObject &main_module = GetMainModule ();
         if (main_module)
         {
             PythonDictionary main_dict(PyModule_GetDict (main_module.get()));
             if (main_dict)
             {
                 m_session_dict = main_dict.GetItemForKey(m_dictionary_name.c_str());
             }
         }
     }
     return m_session_dict;
 }
 
 PythonDictionary &
 ScriptInterpreterPython::GetSysModuleDictionary ()
 {
     if (!m_sys_module_dict)
     {
         PyObject *sys_module = PyImport_AddModule ("sys");
         if (sys_module)
             m_sys_module_dict.Reset(PyModule_GetDict (sys_module));
     }
     return m_sys_module_dict;
 }
 
 static std::string
 GenerateUniqueName (const char* base_name_wanted,
                     uint32_t& functions_counter,
                     void* name_token = nullptr)
 {
     StreamString sstr;
     
     if (!base_name_wanted)
         return std::string();
     
     if (!name_token)
         sstr.Printf ("%s_%d", base_name_wanted, functions_counter++);
     else
         sstr.Printf ("%s_%p", base_name_wanted, name_token);
     
     return sstr.GetString();
 }
 
 bool
 ScriptInterpreterPython::GetEmbeddedInterpreterModuleObjects ()
 {
     if (!m_run_one_line_function)
     {
         PyObject *module = PyImport_AddModule ("lldb.embedded_interpreter");
         if (module != nullptr)
         {
             PythonDictionary module_dict (PyModule_GetDict (module));
             if (module_dict)
             {
                 m_run_one_line_function = module_dict.GetItemForKey("run_one_line");
                 m_run_one_line_str_global = module_dict.GetItemForKey("g_run_one_line_str");
             }
         }
     }
     return (bool)m_run_one_line_function;
 }
 
 static void
 ReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
 {
     if (src && src_len)
     {
         Stream *strm = (Stream *)baton;
         strm->Write(src, src_len);
         strm->Flush();
     }
 }
 
 bool
 ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result, const ExecuteScriptOptions &options)
 {
     if (!m_valid_session)
         return false;
     
     if (command && command[0])
     {
         // We want to call run_one_line, passing in the dictionary and the command string.  We cannot do this through
         // PyRun_SimpleString here because the command string may contain escaped characters, and putting it inside
         // another string to pass to PyRun_SimpleString messes up the escaping.  So we use the following more complicated
         // method to pass the command string directly down to Python.
         Debugger &debugger = m_interpreter.GetDebugger();
         
         StreamFileSP input_file_sp;
         StreamFileSP output_file_sp;
         StreamFileSP error_file_sp;
         Communication output_comm ("lldb.ScriptInterpreterPython.ExecuteOneLine.comm");
         int pipe_fds[2] = { -1, -1 };
         
         if (options.GetEnableIO())
         {
             if (result)
             {
                 input_file_sp = debugger.GetInputFile();
                 // Set output to a temporary file so we can forward the results on to the result object
                 
 #ifdef _MSC_VER
                 // pipe is not supported on windows so default to a fail condition
-                int err = 1;
+                int err = _pipe(pipe_fds, 1024, _O_BINARY);
 #else
                 int err = pipe(pipe_fds);
 #endif
                 if (err == 0)
                 {
                     std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor(pipe_fds[0], true));
                     if (conn_ap->IsConnected())
                     {
                         output_comm.SetConnection(conn_ap.release());
                         output_comm.SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived, &result->GetOutputStream());
                         output_comm.StartReadThread();
                         FILE *outfile_handle = fdopen (pipe_fds[1], "w");
                         output_file_sp.reset(new StreamFile(outfile_handle, true));
                         error_file_sp = output_file_sp;
                         if (outfile_handle)
                             ::setbuf (outfile_handle, nullptr);
                         
                         result->SetImmediateOutputFile(debugger.GetOutputFile()->GetFile().GetStream());
                         result->SetImmediateErrorFile(debugger.GetErrorFile()->GetFile().GetStream());
                     }
                 }
             }
             if (!input_file_sp || !output_file_sp || !error_file_sp)
                 debugger.AdoptTopIOHandlerFilesIfInvalid(input_file_sp, output_file_sp, error_file_sp);
         }
         else
         {
             input_file_sp.reset (new StreamFile ());
             input_file_sp->GetFile().Open("/dev/null", File::eOpenOptionRead);
             output_file_sp.reset (new StreamFile ());
             output_file_sp->GetFile().Open("/dev/null", File::eOpenOptionWrite);
             error_file_sp = output_file_sp;
         }
 
         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),
                       ScriptInterpreterPython::Locker::FreeAcquiredLock |
                       ScriptInterpreterPython::Locker::TearDownSession,
                       in_file,
                       out_file,
                       err_file);
         
         bool success = false;
         
         // Find the correct script interpreter dictionary in the main module.
         PythonDictionary &session_dict = GetSessionDictionary ();
         if (session_dict)
         {
             if (GetEmbeddedInterpreterModuleObjects ())
             {
                 PyObject *pfunc = m_run_one_line_function.get();
                 
                 if (pfunc && PyCallable_Check (pfunc))
                 {
                     PythonObject pargs (Py_BuildValue("(Os)", session_dict.get(), command));
                     if (pargs)
                     {
                         PythonObject return_value(PyObject_CallObject (pfunc, pargs.get()));
                         if (return_value)
                             success = true;
                         else if (options.GetMaskoutErrors() && PyErr_Occurred ())
                         {
                             PyErr_Print();
                             PyErr_Clear();
                         }
                     }
                 }
             }
         }
 
         // Flush our output and error file handles
         ::fflush (out_file);
         if (out_file != err_file)
             ::fflush (err_file);
         
         if (pipe_fds[0] != -1)
         {
             // Close the write end of the pipe since we are done with our
             // one line script. This should cause the read thread that
             // output_comm is using to exit
             output_file_sp->GetFile().Close();
             // The close above should cause this thread to exit when it gets
             // to the end of file, so let it get all its data
             output_comm.JoinReadThread();
             // Now we can close the read end of the pipe
             output_comm.Disconnect();
         }
         
         
         if (success)
             return true;
 
         // The one-liner failed.  Append the error message.
         if (result)
             result->AppendErrorWithFormat ("python failed attempting to evaluate '%s'\n", command);
         return false;
     }
 
     if (result)
         result->AppendError ("empty command passed to python\n");
     return false;
 }
 
 
 class IOHandlerPythonInterpreter :
     public IOHandler
 {
 public:
     
     IOHandlerPythonInterpreter (Debugger &debugger,
                                 ScriptInterpreterPython *python) :
         IOHandler (debugger),
         m_python(python)
     {
         
     }
     
     virtual
     ~IOHandlerPythonInterpreter()
     {
         
     }
     
     virtual ConstString
     GetControlSequence (char ch)
     {
         if (ch == 'd')
             return ConstString("quit()\n");
         return ConstString();
     }
 
     virtual void
     Run ()
     {
         if (m_python)
         {
             int stdin_fd = GetInputFD();
             if (stdin_fd >= 0)
             {
                 Terminal terminal(stdin_fd);
                 TerminalState terminal_state;
                 const bool is_a_tty = terminal.IsATerminal();
                 
                 if (is_a_tty)
                 {
                     terminal_state.Save (stdin_fd, false);
                     terminal.SetCanonical(false);
                     terminal.SetEcho(true);
                 }
                 
                 ScriptInterpreterPython::Locker locker (m_python,
                                                         ScriptInterpreterPython::Locker::AcquireLock |
                                                         ScriptInterpreterPython::Locker::InitSession |
                                                         ScriptInterpreterPython::Locker::InitGlobals,
                                                         ScriptInterpreterPython::Locker::FreeAcquiredLock |
                                                         ScriptInterpreterPython::Locker::TearDownSession);
 
                 // The following call drops into the embedded interpreter loop and stays there until the
                 // user chooses to exit from the Python interpreter.
                 // This embedded interpreter will, as any Python code that performs I/O, unlock the GIL before
                 // a system call that can hang, and lock it when the syscall has returned.
                 
                 // We need to surround the call to the embedded interpreter with calls to PyGILState_Ensure and
                 // PyGILState_Release (using the Locker above). This is because Python has a global lock which must be held whenever we want
                 // to touch any Python objects. Otherwise, if the user calls Python code, the interpreter state will be off,
                 // and things could hang (it's happened before).
                 
                 StreamString run_string;
                 run_string.Printf ("run_python_interpreter (%s)", m_python->GetDictionaryName ());
                 PyRun_SimpleString (run_string.GetData());
                 
                 if (is_a_tty)
                     terminal_state.Restore();
             }
         }
         SetIsDone(true);
     }
 
     virtual void
     Hide ()
     {
         
     }
     
     virtual void
     Refresh ()
     {
         
     }
 
     virtual void
     Cancel ()
     {
         
     }
 
     virtual bool
     Interrupt ()
     {
         Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
 
         PyThreadState* state = _PyThreadState_Current;
         if (!state)
             state = m_python->GetThreadState();
         if (state)
         {
             long tid = state->thread_id;
             _PyThreadState_Current = state;
             int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
             if (log)
                 log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, tid = %ld, num_threads = %d, state = %p",
                             tid,num_threads,state);
         }
         else if (log)
             log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL");
 
         return false;
     }
     
     virtual void
     GotEOF()
     {
         
     }
 protected:
     ScriptInterpreterPython *m_python;
 };
 
 
 void
 ScriptInterpreterPython::ExecuteInterpreterLoop ()
 {
     Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
 
     Debugger &debugger = GetCommandInterpreter().GetDebugger();
 
     // At the moment, the only time the debugger does not have an input file handle is when this is called
     // directly from Python, in which case it is both dangerous and unnecessary (not to mention confusing) to
     // try to embed a running interpreter loop inside the already running Python interpreter loop, so we won't
     // do it.
 
     if (!debugger.GetInputFile()->GetFile().IsValid())
         return;
 
     IOHandlerSP io_handler_sp (new IOHandlerPythonInterpreter (debugger, this));
     if (io_handler_sp)
     {
         debugger.PushIOHandler(io_handler_sp);
     }
 }
 
 bool
 ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
                                                    ScriptInterpreter::ScriptReturnType return_type,
                                                    void *ret_value,
                                                    const ExecuteScriptOptions &options)
 {
 
     Locker locker(this,
                   ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
                   ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
 
     PyObject *py_return = nullptr;
     PythonObject &main_module = GetMainModule ();
     PythonDictionary globals (PyModule_GetDict(main_module.get()));
     PyObject *py_error = nullptr;
     bool ret_success = false;
     int success;
     
     PythonDictionary locals = GetSessionDictionary ();
     
     if (!locals)
     {
         locals = PyObject_GetAttrString (globals.get(), m_dictionary_name.c_str());
     }
         
     if (!locals)
         locals = globals;
 
     py_error = PyErr_Occurred();
     if (py_error != nullptr)
         PyErr_Clear();
     
     if (in_string != nullptr)
     {
         { // scope for PythonInputReaderManager
             //PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
             py_return = PyRun_String (in_string, Py_eval_input, globals.get(), locals.get());
             if (py_return == nullptr)
             { 
                 py_error = PyErr_Occurred ();
                 if (py_error != nullptr)
                     PyErr_Clear ();
 
                 py_return = PyRun_String (in_string, Py_single_input, globals.get(), locals.get());
             }
         }
 
         if (py_return != nullptr)
         {
             switch (return_type)
             {
                 case eScriptReturnTypeCharPtr: // "char *"
                 {
                     const char format[3] = "s#";
                     success = PyArg_Parse (py_return, format, (char **) ret_value);
                     break;
                 }
                 case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return == Py_None
                 {
                     const char format[3] = "z";
                     success = PyArg_Parse (py_return, format, (char **) ret_value);
                     break;
                 }
                 case eScriptReturnTypeBool:
                 {
                     const char format[2] = "b";
                     success = PyArg_Parse (py_return, format, (bool *) ret_value);
                     break;
                 }
                 case eScriptReturnTypeShortInt:
                 {
                     const char format[2] = "h";
                     success = PyArg_Parse (py_return, format, (short *) ret_value);
                     break;
                 }
                 case eScriptReturnTypeShortIntUnsigned:
                 {
                     const char format[2] = "H";
                     success = PyArg_Parse (py_return, format, (unsigned short *) ret_value);
                     break;
                 }
                 case eScriptReturnTypeInt:
                 {
                     const char format[2] = "i";
                     success = PyArg_Parse (py_return, format, (int *) ret_value);
                     break;
                 }
                 case eScriptReturnTypeIntUnsigned:
                 {
                     const char format[2] = "I";
                     success = PyArg_Parse (py_return, format, (unsigned int *) ret_value);
                     break;
                 }
                 case eScriptReturnTypeLongInt:
                 {
                     const char format[2] = "l";
                     success = PyArg_Parse (py_return, format, (long *) ret_value);
                     break;
                 }
                 case eScriptReturnTypeLongIntUnsigned:
                 {
                     const char format[2] = "k";
                     success = PyArg_Parse (py_return, format, (unsigned long *) ret_value);
                     break;
                 }
                 case eScriptReturnTypeLongLong:
                 {
                     const char format[2] = "L";
                     success = PyArg_Parse (py_return, format, (long long *) ret_value);
                     break;
                 }
                 case eScriptReturnTypeLongLongUnsigned:
                 {
                     const char format[2] = "K";
                     success = PyArg_Parse (py_return, format, (unsigned long long *) ret_value);
                     break;
                 }
                 case eScriptReturnTypeFloat:
                 {
                     const char format[2] = "f";
                     success = PyArg_Parse (py_return, format, (float *) ret_value);
                     break;
                 }
                 case eScriptReturnTypeDouble:
                 {
                     const char format[2] = "d";
                     success = PyArg_Parse (py_return, format, (double *) ret_value);
                     break;
                 }
                 case eScriptReturnTypeChar:
                 {
                     const char format[2] = "c";
                     success = PyArg_Parse (py_return, format, (char *) ret_value);
                     break;
                 }
                 case eScriptReturnTypeOpaqueObject:
                 {
                     success = true;
                     Py_XINCREF(py_return);
                     *((PyObject**)ret_value) = py_return;
                     break;
                 }
             }
             Py_XDECREF (py_return);
             if (success)
                 ret_success = true;
             else
                 ret_success = false;
         }
     }
 
     py_error = PyErr_Occurred();
     if (py_error != nullptr)
     {
         ret_success = false;
         if (options.GetMaskoutErrors())
         {
             if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
                 PyErr_Print ();
             PyErr_Clear();
         }
     }
 
     return ret_success;
 }
 
 Error
 ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, const ExecuteScriptOptions &options)
 {
     Error error;
     
     Locker locker(this,
                   ScriptInterpreterPython::Locker::AcquireLock      | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
                   ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
 
     PythonObject return_value;
     PythonObject &main_module = GetMainModule ();
     PythonDictionary globals (PyModule_GetDict(main_module.get()));
     PyObject *py_error = nullptr;
 
     PythonDictionary locals = GetSessionDictionary ();
     
     if (!locals)
     {
         locals = PyObject_GetAttrString (globals.get(), m_dictionary_name.c_str());
     }
 
     if (!locals)
     {
         locals = globals;
     }
 
     py_error = PyErr_Occurred();
     if (py_error != nullptr)
         PyErr_Clear();
     
     if (in_string != nullptr)
     {
         struct _node *compiled_node = PyParser_SimpleParseString (in_string, Py_file_input);
         if (compiled_node)
         {
             PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
             if (compiled_code)
             {
               return_value.Reset(PyEval_EvalCode (compiled_code, globals.get(), locals.get()));
             }
         }
     }
 
     py_error = PyErr_Occurred ();
     if (py_error != nullptr)
     {
 //        puts(in_string);
 //        _PyObject_Dump (py_error);
 //        PyErr_Print();
 //        success = false;
         
         PyObject *type = nullptr;
         PyObject *value = nullptr;
         PyObject *traceback = nullptr;
         PyErr_Fetch (&type,&value,&traceback);
         
         // get the backtrace
         std::string bt = ReadPythonBacktrace(traceback);
         
         if (value && value != Py_None)
             error.SetErrorStringWithFormat("%s\n%s", PyString_AsString(PyObject_Str(value)),bt.c_str());
         else
             error.SetErrorStringWithFormat("%s",bt.c_str());
         Py_XDECREF(type);
         Py_XDECREF(value);
         Py_XDECREF(traceback);
         if (options.GetMaskoutErrors())
         {
             PyErr_Clear();
         }
     }
 
     return error;
 }
 
 
 void
 ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
                                                                   CommandReturnObject &result)
 {
     m_active_io_handler = eIOHandlerBreakpoint;
     m_interpreter.GetPythonCommandsFromIOHandler ("    ", *this, true, bp_options);
 }
 
 void
 ScriptInterpreterPython::CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
                                                                   CommandReturnObject &result)
 {
     m_active_io_handler = eIOHandlerWatchpoint;
     m_interpreter.GetPythonCommandsFromIOHandler ("    ", *this, true, wp_options);
 }
 
 void
 ScriptInterpreterPython::SetBreakpointCommandCallbackFunction (BreakpointOptions *bp_options,
                                                                const char *function_name)
 {
     // For now just cons up a oneliner that calls the provided function.
     std::string oneliner("return ");
     oneliner += function_name;
     oneliner += "(frame, bp_loc, internal_dict)";
     m_interpreter.GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options,
                                                                         oneliner.c_str());
 }
 
 // Set a Python one-liner as the callback for the breakpoint.
 Error
 ScriptInterpreterPython::SetBreakpointCommandCallback (BreakpointOptions *bp_options,
                                                        const char *command_body_text)
 {
     std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
 
     // Split the command_body_text into lines, and pass that to GenerateBreakpointCommandCallbackData.  That will
     // wrap the body in an auto-generated function, and return the function name in script_source.  That is what
     // the callback will actually invoke.
     
     data_ap->user_source.SplitIntoLines(command_body_text);
     Error error = GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source);
     if (error.Success())
     {
         BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
         bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
         return error;
     }
     else
         return error;
 }
 
 // Set a Python one-liner as the callback for the watchpoint.
 void
 ScriptInterpreterPython::SetWatchpointCommandCallback (WatchpointOptions *wp_options,
                                                        const char *oneliner)
 {
     std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
 
     // It's necessary to set both user_source and script_source to the oneliner.
     // The former is used to generate callback description (as in watchpoint command list)
     // while the latter is used for Python to interpret during the actual callback.
 
     data_ap->user_source.AppendString (oneliner);
     data_ap->script_source.assign (oneliner);
 
     if (GenerateWatchpointCommandCallbackData (data_ap->user_source, data_ap->script_source))
     {
         BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
         wp_options->SetCallback (ScriptInterpreterPython::WatchpointCallbackFunction, baton_sp);
     }
     
     return;
 }
 
 Error
 ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
 {
     // Convert StringList to one long, newline delimited, const char *.
     std::string function_def_string(function_def.CopyList());
 
     Error error = ExecuteMultipleLines (function_def_string.c_str(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false));
     return error;
 }
 
 Error
 ScriptInterpreterPython::GenerateFunction(const char *signature, const StringList &input)
 {
     Error error;
     int num_lines = input.GetSize ();
     if (num_lines == 0)
     {
         error.SetErrorString ("No input data.");
         return error;
     }
     
     if (!signature || *signature == 0)
     {
         error.SetErrorString("No output function name.");
         return error;
     }
 
     StreamString sstr;
     StringList auto_generated_function;
     auto_generated_function.AppendString (signature);
     auto_generated_function.AppendString ("     global_dict = globals()");   // Grab the global dictionary
     auto_generated_function.AppendString ("     new_keys = internal_dict.keys()");    // Make a list of keys in the session dict
     auto_generated_function.AppendString ("     old_keys = global_dict.keys()"); // Save list of keys in global dict
     auto_generated_function.AppendString ("     global_dict.update (internal_dict)"); // Add the session dictionary to the 
     // global dictionary.
     
     // Wrap everything up inside the function, increasing the indentation.
     
     auto_generated_function.AppendString("     if True:");
     for (int i = 0; i < num_lines; ++i)
     {
         sstr.Clear ();
         sstr.Printf ("       %s", input.GetStringAtIndex (i));
         auto_generated_function.AppendString (sstr.GetData());
     }
     auto_generated_function.AppendString ("     for key in new_keys:");  // Iterate over all the keys from session dict
     auto_generated_function.AppendString ("         internal_dict[key] = global_dict[key]");  // Update session dict values
     auto_generated_function.AppendString ("         if key not in old_keys:");       // If key was not originally in global dict
     auto_generated_function.AppendString ("             del global_dict[key]");      //  ...then remove key/value from global dict
     
     // Verify that the results are valid Python.
     
     error = ExportFunctionDefinitionToInterpreter (auto_generated_function);
     
     return error;
 }
 
 bool
 ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, std::string& output, void* name_token)
 {
     static uint32_t num_created_functions = 0;
     user_input.RemoveBlankLines ();
     StreamString sstr;
     
     // Check to see if we have any data; if not, just return.
     if (user_input.GetSize() == 0)
         return false;
     
     // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the
     // ValueObject as parameter to the function.
     
     std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_type_print_func", num_created_functions, name_token));
     sstr.Printf ("def %s (valobj, internal_dict):", auto_generated_function_name.c_str());
     
     if (!GenerateFunction(sstr.GetData(), user_input).Success())
         return false;
 
     // Store the name of the auto-generated function to be called.
     output.assign(auto_generated_function_name);
     return true;
 }
 
 bool
 ScriptInterpreterPython::GenerateScriptAliasFunction (StringList &user_input, std::string &output)
 {
     static uint32_t num_created_functions = 0;
     user_input.RemoveBlankLines ();
     StreamString sstr;
     
     // Check to see if we have any data; if not, just return.
     if (user_input.GetSize() == 0)
         return false;
     
     std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_cmd_alias_func", num_created_functions));
 
     sstr.Printf ("def %s (debugger, args, result, internal_dict):", auto_generated_function_name.c_str());
     
     if (!GenerateFunction(sstr.GetData(),user_input).Success())
         return false;
     
     // Store the name of the auto-generated function to be called.
     output.assign(auto_generated_function_name);
     return true;
 }
 
 
 bool
 ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::string &output, void* name_token)
 {
     static uint32_t num_created_classes = 0;
     user_input.RemoveBlankLines ();
     int num_lines = user_input.GetSize ();
     StreamString sstr;
     
     // Check to see if we have any data; if not, just return.
     if (user_input.GetSize() == 0)
         return false;
     
     // Wrap all user input into a Python class
     
     std::string auto_generated_class_name(GenerateUniqueName("lldb_autogen_python_type_synth_class",num_created_classes,name_token));
     
     StringList auto_generated_class;
     
     // Create the function name & definition string.
     
     sstr.Printf ("class %s:", auto_generated_class_name.c_str());
     auto_generated_class.AppendString (sstr.GetData());
         
     // Wrap everything up inside the class, increasing the indentation.
     // we don't need to play any fancy indentation tricks here because there is no
     // surrounding code whose indentation we need to honor
     for (int i = 0; i < num_lines; ++i)
     {
         sstr.Clear ();
         sstr.Printf ("     %s", user_input.GetStringAtIndex (i));
         auto_generated_class.AppendString (sstr.GetData());
     }
     
     
     // Verify that the results are valid Python.
     // (even though the method is ExportFunctionDefinitionToInterpreter, a class will actually be exported)
     // (TODO: rename that method to ExportDefinitionToInterpreter)
     if (!ExportFunctionDefinitionToInterpreter (auto_generated_class).Success())
         return false;
     
     // Store the name of the auto-generated class
     
     output.assign(auto_generated_class_name);
     return true;
 }
 
 lldb::ScriptInterpreterObjectSP
 ScriptInterpreterPython::OSPlugin_CreatePluginObject (const char *class_name, lldb::ProcessSP process_sp)
 {
     if (class_name == nullptr || class_name[0] == '\0')
         return lldb::ScriptInterpreterObjectSP();
     
     if (!process_sp)
         return lldb::ScriptInterpreterObjectSP();
         
     void* ret_val;
     
     {
         Locker py_lock  (this,
                          Locker::AcquireLock | Locker::NoSTDIN,
                          Locker::FreeLock);
         ret_val = g_swig_create_os_plugin    (class_name,
                                               m_dictionary_name.c_str(),
                                               process_sp);
     }
     
     return MakeScriptObject(ret_val);
 }
 
 lldb::ScriptInterpreterObjectSP
 ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
 {
     Locker py_lock(this,
                    Locker::AcquireLock | Locker::NoSTDIN,
                    Locker::FreeLock);
     
     static char callee_name[] = "get_register_info";
     
     if (!os_plugin_object_sp)
         return lldb::ScriptInterpreterObjectSP();
     
     PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
     
     if (implementor == nullptr || implementor == Py_None)
         return lldb::ScriptInterpreterObjectSP();
     
     PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
     
     if (PyErr_Occurred())
     {
         PyErr_Clear();
     }
     
     if (pmeth == nullptr || pmeth == Py_None)
     {
         Py_XDECREF(pmeth);
         return lldb::ScriptInterpreterObjectSP();
     }
     
     if (PyCallable_Check(pmeth) == 0)
     {
         if (PyErr_Occurred())
         {
             PyErr_Clear();
         }
         
         Py_XDECREF(pmeth);
         return lldb::ScriptInterpreterObjectSP();
     }
     
     if (PyErr_Occurred())
     {
         PyErr_Clear();
     }
     
     Py_XDECREF(pmeth);
     
     // right now we know this function exists and is callable..
     PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
     
     // if it fails, print the error but otherwise go on
     if (PyErr_Occurred())
     {
         PyErr_Print();
         PyErr_Clear();
     }
     
     return MakeScriptObject(py_return);
 }
 
 lldb::ScriptInterpreterObjectSP
 ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
 {
     Locker py_lock (this,
                     Locker::AcquireLock | Locker::NoSTDIN,
                     Locker::FreeLock);
 
     static char callee_name[] = "get_thread_info";
     
     if (!os_plugin_object_sp)
         return lldb::ScriptInterpreterObjectSP();
     
     PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
     
     if (implementor == nullptr || implementor == Py_None)
         return lldb::ScriptInterpreterObjectSP();
     
     PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
     
     if (PyErr_Occurred())
     {
         PyErr_Clear();
     }
     
     if (pmeth == nullptr || pmeth == Py_None)
     {
         Py_XDECREF(pmeth);
         return lldb::ScriptInterpreterObjectSP();
     }
     
     if (PyCallable_Check(pmeth) == 0)
     {
         if (PyErr_Occurred())
         {
             PyErr_Clear();
         }
         
         Py_XDECREF(pmeth);
         return lldb::ScriptInterpreterObjectSP();
     }
     
     if (PyErr_Occurred())
     {
         PyErr_Clear();
     }
     
     Py_XDECREF(pmeth);
     
     // right now we know this function exists and is callable..
     PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
     
     // if it fails, print the error but otherwise go on
     if (PyErr_Occurred())
     {
         PyErr_Print();
         PyErr_Clear();
     }
     
     return MakeScriptObject(py_return);
 }
 
 // GetPythonValueFormatString provides a system independent type safe way to
 // convert a variable's type into a python value format. Python value formats
 // are defined in terms of builtin C types and could change from system to
 // as the underlying typedef for uint* types, size_t, off_t and other values
 // change.
 
 template <typename T>
 const char *GetPythonValueFormatString(T t)
 {
     assert(!"Unhandled type passed to GetPythonValueFormatString(T), make a specialization of GetPythonValueFormatString() to support this type.");
     return nullptr;
 }
 template <> const char *GetPythonValueFormatString (char *)             { return "s"; }
 template <> const char *GetPythonValueFormatString (char)               { return "b"; }
 template <> const char *GetPythonValueFormatString (unsigned char)      { return "B"; }
 template <> const char *GetPythonValueFormatString (short)              { return "h"; }
 template <> const char *GetPythonValueFormatString (unsigned short)     { return "H"; }
 template <> const char *GetPythonValueFormatString (int)                { return "i"; }
 template <> const char *GetPythonValueFormatString (unsigned int)       { return "I"; }
 template <> const char *GetPythonValueFormatString (long)               { return "l"; }
 template <> const char *GetPythonValueFormatString (unsigned long)      { return "k"; }
 template <> const char *GetPythonValueFormatString (long long)          { return "L"; }
 template <> const char *GetPythonValueFormatString (unsigned long long) { return "K"; }
 template <> const char *GetPythonValueFormatString (float t)            { return "f"; }
 template <> const char *GetPythonValueFormatString (double t)           { return "d"; }
 
 lldb::ScriptInterpreterObjectSP
 ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
                                                        lldb::tid_t tid)
 {
     Locker py_lock (this,
                     Locker::AcquireLock | Locker::NoSTDIN,
                     Locker::FreeLock);
 
     static char callee_name[] = "get_register_data";
     static char *param_format = const_cast<char *>(GetPythonValueFormatString(tid));
     
     if (!os_plugin_object_sp)
         return lldb::ScriptInterpreterObjectSP();
     
     PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
     
     if (implementor == nullptr || implementor == Py_None)
         return lldb::ScriptInterpreterObjectSP();
 
     PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
     
     if (PyErr_Occurred())
     {
         PyErr_Clear();
     }
     
     if (pmeth == nullptr || pmeth == Py_None)
     {
         Py_XDECREF(pmeth);
         return lldb::ScriptInterpreterObjectSP();
     }
     
     if (PyCallable_Check(pmeth) == 0)
     {
         if (PyErr_Occurred())
         {
             PyErr_Clear();
         }
         
         Py_XDECREF(pmeth);
         return lldb::ScriptInterpreterObjectSP();
     }
     
     if (PyErr_Occurred())
     {
         PyErr_Clear();
     }
     
     Py_XDECREF(pmeth);
     
     // right now we know this function exists and is callable..
     PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, tid);
 
     // if it fails, print the error but otherwise go on
     if (PyErr_Occurred())
     {
         PyErr_Print();
         PyErr_Clear();
     }
     
     return MakeScriptObject(py_return);
 }
 
 lldb::ScriptInterpreterObjectSP
 ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
                                                 lldb::tid_t tid,
                                                 lldb::addr_t context)
 {
     Locker py_lock(this,
                    Locker::AcquireLock | Locker::NoSTDIN,
                    Locker::FreeLock);
     
     static char callee_name[] = "create_thread";
     std::string param_format;
     param_format += GetPythonValueFormatString(tid);
     param_format += GetPythonValueFormatString(context);
     
     if (!os_plugin_object_sp)
         return lldb::ScriptInterpreterObjectSP();
     
     PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
     
     if (implementor == nullptr || implementor == Py_None)
         return lldb::ScriptInterpreterObjectSP();
     
     PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
     
     if (PyErr_Occurred())
     {
         PyErr_Clear();
     }
     
     if (pmeth == nullptr || pmeth == Py_None)
     {
         Py_XDECREF(pmeth);
         return lldb::ScriptInterpreterObjectSP();
     }
     
     if (PyCallable_Check(pmeth) == 0)
     {
         if (PyErr_Occurred())
         {
             PyErr_Clear();
         }
         
         Py_XDECREF(pmeth);
         return lldb::ScriptInterpreterObjectSP();
     }
     
     if (PyErr_Occurred())
     {
         PyErr_Clear();
     }
     
     Py_XDECREF(pmeth);
     
     // right now we know this function exists and is callable..
     PyObject* py_return = PyObject_CallMethod(implementor, callee_name, &param_format[0], tid, context);
     
     // if it fails, print the error but otherwise go on
     if (PyErr_Occurred())
     {
         PyErr_Print();
         PyErr_Clear();
     }
     
     return MakeScriptObject(py_return);
 }
 
 lldb::ScriptInterpreterObjectSP
 ScriptInterpreterPython::LoadPluginModule (const FileSpec& file_spec,
                                            lldb_private::Error& error)
 {
     if (!file_spec.Exists())
     {
         error.SetErrorString("no such file");
         return lldb::ScriptInterpreterObjectSP();
     }
 
     ScriptInterpreterObjectSP module_sp;
     
     if (LoadScriptingModule(file_spec.GetPath().c_str(),true,true,error,&module_sp))
         return module_sp;
     
     return lldb::ScriptInterpreterObjectSP();
 }
 
 lldb::ScriptInterpreterObjectSP
 ScriptInterpreterPython::GetDynamicSettings (lldb::ScriptInterpreterObjectSP plugin_module_sp,
                                              Target* target,
                                              const char* setting_name,
                                              lldb_private::Error& error)
 {
     if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
         return lldb::ScriptInterpreterObjectSP();
     
     if (!g_swig_plugin_get)
         return lldb::ScriptInterpreterObjectSP();
     
     PyObject *reply_pyobj = nullptr;
     
     {
         Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
         TargetSP target_sp(target->shared_from_this());
         reply_pyobj = (PyObject*)g_swig_plugin_get(plugin_module_sp->GetObject(),setting_name,target_sp);
     }
     
     return MakeScriptObject(reply_pyobj);
 }
 
 lldb::ScriptInterpreterObjectSP
 ScriptInterpreterPython::CreateSyntheticScriptedProvider (const char *class_name,
                                                           lldb::ValueObjectSP valobj)
 {
     if (class_name == nullptr || class_name[0] == '\0')
         return lldb::ScriptInterpreterObjectSP();
     
     if (!valobj.get())
         return lldb::ScriptInterpreterObjectSP();
     
     ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
     Target *target = exe_ctx.GetTargetPtr();
     
     if (!target)
         return lldb::ScriptInterpreterObjectSP();
     
     Debugger &debugger = target->GetDebugger();
     ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
     ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
     
     if (!script_interpreter)
         return lldb::ScriptInterpreterObjectSP();
     
     void* ret_val;
 
     {
         Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
         ret_val = g_swig_synthetic_script (class_name,
                                            python_interpreter->m_dictionary_name.c_str(),
                                            valobj);
     }
     
     return MakeScriptObject(ret_val);
 }
 
 bool
 ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token)
 {
     StringList input;
     input.SplitIntoLines(oneliner, strlen(oneliner));
     return GenerateTypeScriptFunction(input, output, name_token);
 }
 
 bool
 ScriptInterpreterPython::GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token)
 {
     StringList input;
     input.SplitIntoLines(oneliner, strlen(oneliner));
     return GenerateTypeSynthClass(input, output, name_token);
 }
 
 
 Error
 ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, std::string& output)
 {
     static uint32_t num_created_functions = 0;
     user_input.RemoveBlankLines ();
     StreamString sstr;
     Error error;
     if (user_input.GetSize() == 0)
     {
         error.SetErrorString("No input data.");
         return error;
     }
 
     std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_bp_callback_func_",num_created_functions));
     sstr.Printf ("def %s (frame, bp_loc, internal_dict):", auto_generated_function_name.c_str());
     
     error = GenerateFunction(sstr.GetData(), user_input);
     if (!error.Success())
         return error;
     
     // Store the name of the auto-generated function to be called.
     output.assign(auto_generated_function_name);
     return error;
 }
 
 bool
 ScriptInterpreterPython::GenerateWatchpointCommandCallbackData (StringList &user_input, std::string& output)
 {
     static uint32_t num_created_functions = 0;
     user_input.RemoveBlankLines ();
     StreamString sstr;
 
     if (user_input.GetSize() == 0)
         return false;
 
     std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_wp_callback_func_",num_created_functions));
     sstr.Printf ("def %s (frame, wp, internal_dict):", auto_generated_function_name.c_str());
     
     if (!GenerateFunction(sstr.GetData(), user_input).Success())
         return false;
     
     // Store the name of the auto-generated function to be called.
     output.assign(auto_generated_function_name);
     return true;
 }
 
 bool
 ScriptInterpreterPython::GetScriptedSummary (const char *python_function_name,
                                              lldb::ValueObjectSP valobj,
                                              lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
                                              std::string& retval)
 {
     
     Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
     
     if (!valobj.get())
     {
         retval.assign("<no object>");
         return false;
     }
         
     void* old_callee = (callee_wrapper_sp ? callee_wrapper_sp->GetObject() : nullptr);
     void* new_callee = old_callee;
     
     bool ret_val;
     if (python_function_name 
         && *python_function_name)
     {
         {
             Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
             {
                 Timer scoped_timer ("g_swig_typescript_callback","g_swig_typescript_callback");
                 ret_val = g_swig_typescript_callback (python_function_name,
                                                       GetSessionDictionary().get(),
                                                       valobj,
                                                       &new_callee,
                                                       retval);
             }
         }
     }
     else
     {
         retval.assign("<no function name>");
         return false;
     }
     
     if (new_callee && old_callee != new_callee)
         callee_wrapper_sp = MakeScriptObject(new_callee);
     
     return ret_val;
     
 }
 
 void
 ScriptInterpreterPython::Clear ()
 {
     // Release any global variables that might have strong references to
     // LLDB objects when clearing the python script interpreter.
     Locker locker(this,
                   ScriptInterpreterPython::Locker::AcquireLock,
                   ScriptInterpreterPython::Locker::FreeAcquiredLock);
     PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process = None; lldb.thread = None; lldb.frame = None");
 }
 
 bool
 ScriptInterpreterPython::BreakpointCallbackFunction 
 (
     void *baton,
     StoppointCallbackContext *context,
     user_id_t break_id,
     user_id_t break_loc_id
 )
 {
     BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton;
     const char *python_function_name = bp_option_data->script_source.c_str();
 
     if (!context)
         return true;
         
     ExecutionContext exe_ctx (context->exe_ctx_ref);
     Target *target = exe_ctx.GetTargetPtr();
     
     if (!target)
         return true;
         
     Debugger &debugger = target->GetDebugger();
     ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
     ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
     
     if (!script_interpreter)
         return true;
     
     if (python_function_name && python_function_name[0])
     {
         const StackFrameSP stop_frame_sp (exe_ctx.GetFrameSP());
         BreakpointSP breakpoint_sp = target->GetBreakpointByID (break_id);
         if (breakpoint_sp)
         {
             const BreakpointLocationSP bp_loc_sp (breakpoint_sp->FindLocationByID (break_loc_id));
 
             if (stop_frame_sp && bp_loc_sp)
             {
                 bool ret_val = true;
                 {
                     Locker py_lock(python_interpreter, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
                     ret_val = g_swig_breakpoint_callback (python_function_name,
                                                           python_interpreter->m_dictionary_name.c_str(),
                                                           stop_frame_sp, 
                                                           bp_loc_sp);
                 }
                 return ret_val;
             }
         }
     }
     // We currently always true so we stop in case anything goes wrong when
     // trying to call the script function
     return true;
 }
 
 bool
 ScriptInterpreterPython::WatchpointCallbackFunction 
 (
     void *baton,
     StoppointCallbackContext *context,
     user_id_t watch_id
 )
 {
     WatchpointOptions::CommandData *wp_option_data = (WatchpointOptions::CommandData *) baton;
     const char *python_function_name = wp_option_data->script_source.c_str();
 
     if (!context)
         return true;
         
     ExecutionContext exe_ctx (context->exe_ctx_ref);
     Target *target = exe_ctx.GetTargetPtr();
     
     if (!target)
         return true;
         
     Debugger &debugger = target->GetDebugger();
     ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
     ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
     
     if (!script_interpreter)
         return true;
     
     if (python_function_name && python_function_name[0])
     {
         const StackFrameSP stop_frame_sp (exe_ctx.GetFrameSP());
         WatchpointSP wp_sp = target->GetWatchpointList().FindByID (watch_id);
         if (wp_sp)
         {
             if (stop_frame_sp && wp_sp)
             {
                 bool ret_val = true;
                 {
                     Locker py_lock(python_interpreter, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
                     ret_val = g_swig_watchpoint_callback (python_function_name,
                                                           python_interpreter->m_dictionary_name.c_str(),
                                                           stop_frame_sp, 
                                                           wp_sp);
                 }
                 return ret_val;
             }
         }
     }
     // We currently always true so we stop in case anything goes wrong when
     // trying to call the script function
     return true;
 }
 
 size_t
 ScriptInterpreterPython::CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor_sp)
 {
     if (!implementor_sp)
         return 0;
     
     void* implementor = implementor_sp->GetObject();
     
     if (!implementor)
         return 0;
     
     if (!g_swig_calc_children)
         return 0;
 
     uint32_t ret_val = 0;
     
     {
         Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
         ret_val = g_swig_calc_children (implementor);
     }
     
     return ret_val;
 }
 
 lldb::ValueObjectSP
 ScriptInterpreterPython::GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor_sp, uint32_t idx)
 {
     if (!implementor_sp)
         return lldb::ValueObjectSP();
     
     void* implementor = implementor_sp->GetObject();
     
     if (!implementor)
         return lldb::ValueObjectSP();
     
     if (!g_swig_get_child_index || !g_swig_cast_to_sbvalue)
         return lldb::ValueObjectSP();
     
     lldb::ValueObjectSP ret_val;
     
     {
         Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
         void* child_ptr = g_swig_get_child_index (implementor,idx);
         if (child_ptr != nullptr && child_ptr != Py_None)
         {
             lldb::SBValue* sb_value_ptr = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
             if (sb_value_ptr == nullptr)
                 Py_XDECREF(child_ptr);
             else
                 ret_val = g_swig_get_valobj_sp_from_sbvalue (sb_value_ptr);
         }
         else
         {
             Py_XDECREF(child_ptr);
         }
     }
     
     return ret_val;
 }
 
 int
 ScriptInterpreterPython::GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor_sp, const char* child_name)
 {
     if (!implementor_sp)
         return UINT32_MAX;
     
     void* implementor = implementor_sp->GetObject();
     
     if (!implementor)
         return UINT32_MAX;
     
     if (!g_swig_get_index_child)
         return UINT32_MAX;
     
     int ret_val = UINT32_MAX;
     
     {
         Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
         ret_val = g_swig_get_index_child (implementor, child_name);
     }
     
     return ret_val;
 }
 
 bool
 ScriptInterpreterPython::UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp)
 {
     bool ret_val = false;
     
     if (!implementor_sp)
         return ret_val;
     
     void* implementor = implementor_sp->GetObject();
     
     if (!implementor)
         return ret_val;
     
     if (!g_swig_update_provider)
         return ret_val;
     
     {
         Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
         ret_val = g_swig_update_provider (implementor);
     }
     
     return ret_val;
 }
 
 bool
 ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp)
 {
     bool ret_val = false;
     
     if (!implementor_sp)
         return ret_val;
     
     void* implementor = implementor_sp->GetObject();
     
     if (!implementor)
         return ret_val;
     
     if (!g_swig_mighthavechildren_provider)
         return ret_val;
     
     {
         Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
         ret_val = g_swig_mighthavechildren_provider (implementor);
     }
     
     return ret_val;
 }
 
 static std::string
 ReadPythonBacktrace (PyObject* py_backtrace)
 {
     PyObject* traceback_module = nullptr,
     *stringIO_module = nullptr,
     *stringIO_builder = nullptr,
     *stringIO_buffer = nullptr,
     *printTB = nullptr,
     *printTB_args = nullptr,
     *printTB_result = nullptr,
     *stringIO_getvalue = nullptr,
     *printTB_string = nullptr;
 
     std::string retval("backtrace unavailable");
     
     if (py_backtrace && py_backtrace != Py_None)
     {
         traceback_module = PyImport_ImportModule("traceback");
         stringIO_module = PyImport_ImportModule("StringIO");
         
         if (traceback_module && traceback_module != Py_None && stringIO_module && stringIO_module != Py_None)
         {
             stringIO_builder = PyObject_GetAttrString(stringIO_module, "StringIO");
             if (stringIO_builder && stringIO_builder != Py_None)
             {
                 stringIO_buffer = PyObject_CallObject(stringIO_builder, nullptr);
                 if (stringIO_buffer && stringIO_buffer != Py_None)
                 {
                     printTB = PyObject_GetAttrString(traceback_module, "print_tb");
                     if (printTB && printTB != Py_None)
                     {
                         printTB_args = Py_BuildValue("OOO",py_backtrace,Py_None,stringIO_buffer);
                         printTB_result = PyObject_CallObject(printTB, printTB_args);
                         stringIO_getvalue = PyObject_GetAttrString(stringIO_buffer, "getvalue");
                         if (stringIO_getvalue && stringIO_getvalue != Py_None)
                         {
                             printTB_string = PyObject_CallObject (stringIO_getvalue,nullptr);
                             if (printTB_string && printTB_string != Py_None && PyString_Check(printTB_string))
                                 retval.assign(PyString_AsString(printTB_string));
                         }
                     }
                 }
             }
         }
     }
     Py_XDECREF(traceback_module);
     Py_XDECREF(stringIO_module);
     Py_XDECREF(stringIO_builder);
     Py_XDECREF(stringIO_buffer);
     Py_XDECREF(printTB);
     Py_XDECREF(printTB_args);
     Py_XDECREF(printTB_result);
     Py_XDECREF(stringIO_getvalue);
     Py_XDECREF(printTB_string);
     return retval;
 }
 
 bool
 ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                  Process* process,
                                                  std::string& output,
                                                  Error& error)
 {
     bool ret_val;
     if (!process)
     {
         error.SetErrorString("no process");
         return false;
     }
     if (!impl_function || !impl_function[0])
     {
         error.SetErrorString("no function to execute");
         return false;
     }
     if (!g_swig_run_script_keyword_process)
     {
         error.SetErrorString("internal helper function missing");
         return false;
     }
     {
         ProcessSP process_sp(process->shared_from_this());
         Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
         ret_val = g_swig_run_script_keyword_process (impl_function, m_dictionary_name.c_str(), process_sp, output);
         if (!ret_val)
             error.SetErrorString("python script evaluation failed");
     }
     return ret_val;
 }
 
 bool
 ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                  Thread* thread,
                                                  std::string& output,
                                                  Error& error)
 {
     bool ret_val;
     if (!thread)
     {
         error.SetErrorString("no thread");
         return false;
     }
     if (!impl_function || !impl_function[0])
     {
         error.SetErrorString("no function to execute");
         return false;
     }
     if (!g_swig_run_script_keyword_thread)
     {
         error.SetErrorString("internal helper function missing");
         return false;
     }
     {
         ThreadSP thread_sp(thread->shared_from_this());
         Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
         ret_val = g_swig_run_script_keyword_thread (impl_function, m_dictionary_name.c_str(), thread_sp, output);
         if (!ret_val)
             error.SetErrorString("python script evaluation failed");
     }
     return ret_val;
 }
 
 bool
 ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                  Target* target,
                                                  std::string& output,
                                                  Error& error)
 {
     bool ret_val;
     if (!target)
     {
         error.SetErrorString("no thread");
         return false;
     }
     if (!impl_function || !impl_function[0])
     {
         error.SetErrorString("no function to execute");
         return false;
     }
     if (!g_swig_run_script_keyword_target)
     {
         error.SetErrorString("internal helper function missing");
         return false;
     }
     {
         TargetSP target_sp(target->shared_from_this());
         Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
         ret_val = g_swig_run_script_keyword_target (impl_function, m_dictionary_name.c_str(), target_sp, output);
         if (!ret_val)
             error.SetErrorString("python script evaluation failed");
     }
     return ret_val;
 }
 
 bool
 ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                  StackFrame* frame,
                                                  std::string& output,
                                                  Error& error)
 {
     bool ret_val;
     if (!frame)
     {
         error.SetErrorString("no frame");
         return false;
     }
     if (!impl_function || !impl_function[0])
     {
         error.SetErrorString("no function to execute");
         return false;
     }
     if (!g_swig_run_script_keyword_frame)
     {
         error.SetErrorString("internal helper function missing");
         return false;
     }
     {
         StackFrameSP frame_sp(frame->shared_from_this());
         Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
         ret_val = g_swig_run_script_keyword_frame (impl_function, m_dictionary_name.c_str(), frame_sp, output);
         if (!ret_val)
             error.SetErrorString("python script evaluation failed");
     }
     return ret_val;
 }
 
 uint64_t replace_all(std::string& str, const std::string& oldStr, const std::string& newStr)
 {
     size_t pos = 0;
     uint64_t matches = 0;
     while((pos = str.find(oldStr, pos)) != std::string::npos)
     {
         matches++;
         str.replace(pos, oldStr.length(), newStr);
         pos += newStr.length();
     }
     return matches;
 }
 
 bool
 ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
                                               bool can_reload,
                                               bool init_session,
                                               lldb_private::Error& error,
                                               lldb::ScriptInterpreterObjectSP* module_sp)
 {
     if (!pathname || !pathname[0])
     {
         error.SetErrorString("invalid pathname");
         return false;
     }
     
     if (!g_swig_call_module_init)
     {
         error.SetErrorString("internal helper function missing");
         return false;
     }
     
     lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
 
     {
         FileSpec target_file(pathname, true);
         std::string basename(target_file.GetFilename().GetCString());
         
         StreamString command_stream;
 
         // Before executing Pyton code, lock the GIL.
         Locker py_lock (this,
                         Locker::AcquireLock      | (init_session ? Locker::InitSession     : 0) | Locker::NoSTDIN,
                         Locker::FreeAcquiredLock | (init_session ? Locker::TearDownSession : 0));
         
         if (target_file.GetFileType() == FileSpec::eFileTypeInvalid ||
             target_file.GetFileType() == FileSpec::eFileTypeUnknown)
         {
             // if not a valid file of any sort, check if it might be a filename still
             // dot can't be used but / and \ can, and if either is found, reject
             if (strchr(pathname,'\\') || strchr(pathname,'/'))
             {
                 error.SetErrorString("invalid pathname");
                 return false;
             }
             basename = pathname; // not a filename, probably a package of some sort, let it go through
         }
         else if (target_file.GetFileType() == FileSpec::eFileTypeDirectory ||
                  target_file.GetFileType() == FileSpec::eFileTypeRegular ||
                  target_file.GetFileType() == FileSpec::eFileTypeSymbolicLink)
         {
             std::string directory(target_file.GetDirectory().GetCString());
             replace_all(directory,"'","\\'");
             
             // now make sure that Python has "directory" in the search path
             StreamString command_stream;
             command_stream.Printf("if not (sys.path.__contains__('%s')):\n    sys.path.insert(1,'%s');\n\n",
                                   directory.c_str(),
                                   directory.c_str());
             bool syspath_retval = ExecuteMultipleLines(command_stream.GetData(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false)).Success();
             if (!syspath_retval)
             {
                 error.SetErrorString("Python sys.path handling failed");
                 return false;
             }
             
             // strip .py or .pyc extension
             ConstString extension = target_file.GetFileNameExtension();
             if (extension)
             {
                 if (::strcmp(extension.GetCString(), "py") == 0)
                     basename.resize(basename.length()-3);
                 else if(::strcmp(extension.GetCString(), "pyc") == 0)
                     basename.resize(basename.length()-4);
             }
         }
         else
         {
             error.SetErrorString("no known way to import this module specification");
             return false;
         }
         
         // check if the module is already import-ed
         command_stream.Clear();
         command_stream.Printf("sys.modules.__contains__('%s')",basename.c_str());
         bool does_contain = false;
         // this call will succeed if the module was ever imported in any Debugger in the lifetime of the process
         // in which this LLDB framework is living
         bool was_imported_globally = (ExecuteOneLineWithReturn(command_stream.GetData(),
                                                                ScriptInterpreterPython::eScriptReturnTypeBool,
                                                                &does_contain,
                                                                ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false)) && does_contain);
         // this call will fail if the module was not imported in this Debugger before
         command_stream.Clear();
         command_stream.Printf("sys.getrefcount(%s)",basename.c_str());
         bool was_imported_locally = !(GetSessionDictionary().GetItemForKey(basename.c_str()).IsNULLOrNone());
         
         bool was_imported = (was_imported_globally || was_imported_locally);
         
         if (was_imported == true && can_reload == false)
         {
             error.SetErrorString("module already imported");
             return false;
         }
 
         // now actually do the import
         command_stream.Clear();
         
         if (was_imported)
         {
             if (!was_imported_locally)
                 command_stream.Printf("import %s ; reload(%s)",basename.c_str(),basename.c_str());
             else
                 command_stream.Printf("reload(%s)",basename.c_str());
         }
         else
             command_stream.Printf("import %s",basename.c_str());
         
         error = ExecuteMultipleLines(command_stream.GetData(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false));
         if (error.Fail())
             return false;
         
         // if we are here, everything worked
         // call __lldb_init_module(debugger,dict)
         if (!g_swig_call_module_init (basename.c_str(),
                                       m_dictionary_name.c_str(),
                                       debugger_sp))
         {
             error.SetErrorString("calling __lldb_init_module failed");
             return false;
         }
         
         if (module_sp)
         {
             // everything went just great, now set the module object
             command_stream.Clear();
             command_stream.Printf("%s",basename.c_str());
             void* module_pyobj = nullptr;
             if (ExecuteOneLineWithReturn(command_stream.GetData(),ScriptInterpreter::eScriptReturnTypeOpaqueObject,&module_pyobj) && module_pyobj)
                 *module_sp = MakeScriptObject(module_pyobj);
         }
         
         return true;
     }
 }
 
 lldb::ScriptInterpreterObjectSP
 ScriptInterpreterPython::MakeScriptObject (void* object)
 {
     return lldb::ScriptInterpreterObjectSP(new ScriptInterpreterPythonObject(object));
 }
 
 ScriptInterpreterPython::SynchronicityHandler::SynchronicityHandler (lldb::DebuggerSP debugger_sp,
                                                                      ScriptedCommandSynchronicity synchro) :
     m_debugger_sp(debugger_sp),
     m_synch_wanted(synchro),
     m_old_asynch(debugger_sp->GetAsyncExecution())
 {
     if (m_synch_wanted == eScriptedCommandSynchronicitySynchronous)
         m_debugger_sp->SetAsyncExecution(false);
     else if (m_synch_wanted == eScriptedCommandSynchronicityAsynchronous)
         m_debugger_sp->SetAsyncExecution(true);
 }
 
 ScriptInterpreterPython::SynchronicityHandler::~SynchronicityHandler()
 {
     if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
         m_debugger_sp->SetAsyncExecution(m_old_asynch);
 }
 
 bool
 ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
                                                const char* args,
                                                ScriptedCommandSynchronicity synchronicity,
                                                lldb_private::CommandReturnObject& cmd_retobj,
                                                Error& error)
 {
     if (!impl_function)
     {
         error.SetErrorString("no function to execute");
         return false;
     }
     
     if (!g_swig_call_command)
     {
         error.SetErrorString("no helper function to run scripted commands");
         return false;
     }
     
     lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
     
     if (!debugger_sp.get())
     {
         error.SetErrorString("invalid Debugger pointer");
         return false;
     }
     
     bool ret_val = false;
     
     std::string err_msg;
     
     {
         Locker py_lock(this,
                        Locker::AcquireLock | Locker::InitSession,
                        Locker::FreeLock    | Locker::TearDownSession);
         
         SynchronicityHandler synch_handler(debugger_sp,
                                            synchronicity);
         
         ret_val = g_swig_call_command       (impl_function,
                                              m_dictionary_name.c_str(),
                                              debugger_sp,
                                              args,
                                              cmd_retobj);
     }
     
     if (!ret_val)
         error.SetErrorString("unable to execute script function");
     else
         error.Clear();
     
     return ret_val;
 }
 
 // in Python, a special attribute __doc__ contains the docstring
 // for an object (function, method, class, ...) if any is defined
 // Otherwise, the attribute's value is None
 bool
 ScriptInterpreterPython::GetDocumentationForItem(const char* item, std::string& dest)
 {
 	dest.clear();
 	if (!item || !*item)
 		return false;
     std::string command(item);
     command += ".__doc__";
     
     char* result_ptr = nullptr; // Python is going to point this to valid data if ExecuteOneLineWithReturn returns successfully
     
     if (ExecuteOneLineWithReturn (command.c_str(),
                                   ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
                                   &result_ptr,
                                   ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false)))
     {
         if (result_ptr)
             dest.assign(result_ptr);
         return true;
     }
     else
     {
         StreamString str_stream;
         str_stream.Printf("Function %s was not found. Containing module might be missing.",item);
         dest.assign(str_stream.GetData());
         return false;
     }
 }
 
 std::unique_ptr<ScriptInterpreterLocker>
 ScriptInterpreterPython::AcquireInterpreterLock ()
 {
     std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(this,
                                                                 Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
                                                                 Locker::FreeLock | Locker::TearDownSession));
     return py_lock;
 }
 
 void
 ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callback,
                                                 SWIGBreakpointCallbackFunction swig_breakpoint_callback,
                                                 SWIGWatchpointCallbackFunction swig_watchpoint_callback,
                                                 SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
                                                 SWIGPythonCreateSyntheticProvider swig_synthetic_script,
                                                 SWIGPythonCalculateNumChildren swig_calc_children,
                                                 SWIGPythonGetChildAtIndex swig_get_child_index,
                                                 SWIGPythonGetIndexOfChildWithName swig_get_index_child,
                                                 SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue ,
                                                 SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
                                                 SWIGPythonUpdateSynthProviderInstance swig_update_provider,
                                                 SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
                                                 SWIGPythonCallCommand swig_call_command,
                                                 SWIGPythonCallModuleInit swig_call_module_init,
                                                 SWIGPythonCreateOSPlugin swig_create_os_plugin,
                                                 SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
                                                 SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
                                                 SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
                                                 SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
                                                 SWIGPython_GetDynamicSetting swig_plugin_get)
 {
     g_swig_init_callback = swig_init_callback;
     g_swig_breakpoint_callback = swig_breakpoint_callback;
     g_swig_watchpoint_callback = swig_watchpoint_callback;
     g_swig_typescript_callback = swig_typescript_callback;
     g_swig_synthetic_script = swig_synthetic_script;
     g_swig_calc_children = swig_calc_children;
     g_swig_get_child_index = swig_get_child_index;
     g_swig_get_index_child = swig_get_index_child;
     g_swig_cast_to_sbvalue = swig_cast_to_sbvalue;
     g_swig_get_valobj_sp_from_sbvalue = swig_get_valobj_sp_from_sbvalue;
     g_swig_update_provider = swig_update_provider;
     g_swig_mighthavechildren_provider = swig_mighthavechildren_provider;
     g_swig_call_command = swig_call_command;
     g_swig_call_module_init = swig_call_module_init;
     g_swig_create_os_plugin = swig_create_os_plugin;
     g_swig_run_script_keyword_process = swig_run_script_keyword_process;
     g_swig_run_script_keyword_thread = swig_run_script_keyword_thread;
     g_swig_run_script_keyword_target = swig_run_script_keyword_target;
     g_swig_run_script_keyword_frame = swig_run_script_keyword_frame;
     g_swig_plugin_get = swig_plugin_get;
 }
 
 void
 ScriptInterpreterPython::InitializePrivate ()
 {
     static int g_initialized = false;
     
     if (g_initialized)
         return;
     
     g_initialized = true;
 
     Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
 
     // Python will muck with STDIN terminal state, so save off any current TTY
     // settings so we can restore them.
     TerminalState stdin_tty_state;
     stdin_tty_state.Save(STDIN_FILENO, false);
 
     PyGILState_STATE gstate;
     Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
     bool threads_already_initialized = false;
     if (PyEval_ThreadsInitialized ()) {
         gstate = PyGILState_Ensure ();
         if (log)
             log->Printf("Ensured PyGILState. Previous state = %slocked\n", gstate == PyGILState_UNLOCKED ? "un" : "");
         threads_already_initialized = true;
     } else {
         // InitThreads acquires the GIL if it hasn't been called before.
         PyEval_InitThreads ();
     }
     Py_InitializeEx (0);
 
     // Initialize SWIG after setting up python
     if (g_swig_init_callback)
         g_swig_init_callback ();
 
     // Update the path python uses to search for modules to include the current directory.
 
     PyRun_SimpleString ("import sys");
     PyRun_SimpleString ("sys.path.append ('.')");
 
     // Find the module that owns this code and use that path we get to
     // set the sys.path appropriately.
 
     FileSpec file_spec;
     char python_dir_path[PATH_MAX];
     if (Host::GetLLDBPath (ePathTypePythonDir, file_spec))
     {
         std::string python_path("sys.path.insert(0,\"");
         size_t orig_len = python_path.length();
         if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
         {
             python_path.append (python_dir_path);
             python_path.append ("\")");
             PyRun_SimpleString (python_path.c_str());
             python_path.resize (orig_len);
         }
         
         if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, file_spec))
         {
             if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
             {
                 python_path.append (python_dir_path);
                 python_path.append ("\")");
                 PyRun_SimpleString (python_path.c_str());
                 python_path.resize (orig_len);
             }
         }
     }
 
     PyRun_SimpleString ("sys.dont_write_bytecode = 1; import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line; from termios import *");
 
     if (threads_already_initialized) {
         if (log)
             log->Printf("Releasing PyGILState. Returning to state = %slocked\n", gstate == PyGILState_UNLOCKED ? "un" : "");
         PyGILState_Release (gstate);
     } else {
         // We initialized the threads in this function, just unlock the GIL.
         PyEval_SaveThread();
     }
 
     stdin_tty_state.Restore();
 }
 
 //void
 //ScriptInterpreterPython::Terminate ()
 //{
 //    // We are intentionally NOT calling Py_Finalize here (this would be the logical place to call it).  Calling
 //    // Py_Finalize here causes test suite runs to seg fault:  The test suite runs in Python.  It registers 
 //    // SBDebugger::Terminate to be called 'at_exit'.  When the test suite Python harness finishes up, it calls 
 //    // Py_Finalize, which calls all the 'at_exit' registered functions.  SBDebugger::Terminate calls Debugger::Terminate,
 //    // which calls lldb::Terminate, which calls ScriptInterpreter::Terminate, which calls 
 //    // ScriptInterpreterPython::Terminate.  So if we call Py_Finalize here, we end up with Py_Finalize being called from
 //    // within Py_Finalize, which results in a seg fault.
 //    //
 //    // Since this function only gets called when lldb is shutting down and going away anyway, the fact that we don't
 //    // actually call Py_Finalize should not cause any problems (everything should shut down/go away anyway when the
 //    // process exits).
 //    //
 ////    Py_Finalize ();
 //}
 
 #endif // #ifdef LLDB_DISABLE_PYTHON


More information about the lldb-commits mailing list