//===-- 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/Debugger.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/PythonDataObjects.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"

#if defined(_WIN32)
#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
#endif

using namespace lldb;
using namespace lldb_private;


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::SWIGPythonGetValueSynthProviderInstance g_swig_getvalue_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::SWIGPythonScriptKeyword_Value g_swig_run_script_keyword_value = nullptr;
static ScriptInterpreter::SWIGPython_GetDynamicSetting g_swig_plugin_get = nullptr;
static ScriptInterpreter::SWIGPythonCreateScriptedThreadPlan g_swig_thread_plan_script = nullptr;
static ScriptInterpreter::SWIGPythonCallThreadPlan g_swig_call_thread_plan = 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:
        {
            std::vector<BreakpointOptions *> *bp_options_vec = (std::vector<BreakpointOptions *> *)io_handler.GetUserData();
            for (auto bp_options : *bp_options_vec)
            {
                if (!bp_options)
                    continue;
                    
                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");
        bool join_read_thread = false;
        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
                
                Pipe pipe;
#if defined(_WIN32)
                // By default Windows does not create a pipe object that can be used for a non-blocking read.
                // We must explicitly request it.  Furthermore, we can't use an fd for non-blocking read
                // operations, and must use the native os HANDLE.
                if (pipe.Open(true, false))
                {
                    lldb::file_t read_file = pipe.GetReadNativeHandle();
                    pipe.ReleaseReadFileDescriptor();
                    std::unique_ptr<ConnectionGenericFile> conn_ap(new ConnectionGenericFile(read_file, true));
#else
                if (pipe.Open())
                {
                    std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor(pipe.ReleaseReadFileDescriptor(), true));
#endif
                    if (conn_ap->IsConnected())
                    {
                        output_comm.SetConnection(conn_ap.release());
                        output_comm.SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived, &result->GetOutputStream());
                        output_comm.StartReadThread();
                        join_read_thread = true;
                        FILE *outfile_handle = fdopen (pipe.ReleaseWriteFileDescriptor(), "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 (join_read_thread)
        {
            // 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, static_cast<void *>(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) | Locker::NoSTDIN,
                  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) | Locker::NoSTDIN,
                  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 (std::vector<BreakpointOptions *> &bp_options_vec,
                                                                  CommandReturnObject &result)
{
    m_active_io_handler = eIOHandlerBreakpoint;
    m_interpreter.GetPythonCommandsFromIOHandler ("    ", *this, true, &bp_options_vec);
}

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::CreateScriptedThreadPlan (const char *class_name,
                              lldb::ThreadPlanSP thread_plan_sp)
{
    if (class_name == nullptr || class_name[0] == '\0')
        return lldb::ScriptInterpreterObjectSP();
    
    if (!thread_plan_sp.get())
        return lldb::ScriptInterpreterObjectSP();

    Debugger &debugger = thread_plan_sp->GetTarget().GetDebugger();
    ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
    ScriptInterpreterPython *python_interpreter = static_cast<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_thread_plan_script (class_name,
                                             python_interpreter->m_dictionary_name.c_str(),
                                             thread_plan_sp);
    }
    
    return MakeScriptObject(ret_val);
}

bool
ScriptInterpreterPython::ScriptedThreadPlanExplainsStop (lldb::ScriptInterpreterObjectSP implementor_sp,
                                Event *event,
                                bool &script_error)
{
    bool explains_stop = true;
    if (implementor_sp)
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        explains_stop = g_swig_call_thread_plan (implementor_sp->GetObject(), "explains_stop", event, script_error);
        if (script_error)
            return true;
    }
    return explains_stop;
}

bool
ScriptInterpreterPython::ScriptedThreadPlanShouldStop (lldb::ScriptInterpreterObjectSP implementor_sp,
                              Event *event,
                              bool &script_error)
{
    bool should_stop = true;
    if (implementor_sp)
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        should_stop = g_swig_call_thread_plan (implementor_sp->GetObject(), "should_stop", event, script_error);
        if (script_error)
            return true;
    }
    return should_stop;
}

lldb::StateType
ScriptInterpreterPython::ScriptedThreadPlanGetRunState (lldb::ScriptInterpreterObjectSP implementor_sp,
                                                        bool &script_error)
{
    bool should_step = false;
    if (implementor_sp)
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        should_step = g_swig_call_thread_plan (implementor_sp->GetObject(), "should_step", NULL, script_error);
        if (script_error)
            should_step = true;
    }
    if (should_step)
        return lldb::eStateStepping;
    else
        return lldb::eStateRunning;
}


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);

    // This may be called as part of Py_Finalize.  In that case the modules are destroyed in random
    // order and we can't guarantee that we can access these.
    if (Py_IsInitialized())
        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;
}

lldb::ValueObjectSP
ScriptInterpreterPython::GetSyntheticValue (const lldb::ScriptInterpreterObjectSP& implementor_sp)
{
    lldb::ValueObjectSP ret_val(nullptr);
    
    if (!implementor_sp)
        return ret_val;
    
    void* implementor = implementor_sp->GetObject();
    
    if (!implementor)
        return ret_val;
    
    if (!g_swig_getvalue_provider || !g_swig_cast_to_sbvalue || !g_swig_get_valobj_sp_from_sbvalue)
        return ret_val;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        void* child_ptr = g_swig_getvalue_provider (implementor);
        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;
}

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;
}
    
bool
ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                 ValueObject *value,
                                                 std::string& output,
                                                 Error& error)
{
    bool ret_val;
    if (!value)
    {
        error.SetErrorString("no value");
        return false;
    }
    if (!impl_function || !impl_function[0])
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    if (!g_swig_run_script_keyword_value)
    {
        error.SetErrorString("internal helper function missing");
        return false;
    }
    {
        ValueObjectSP value_sp(value->GetSP());
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_run_script_keyword_value (impl_function, m_dictionary_name.c_str(), value_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,
                                               const lldb_private::ExecutionContext& exe_ctx)
{
    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();
    lldb::ExecutionContextRefSP exe_ctx_ref_sp(new ExecutionContextRef(exe_ctx));
    
    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 | (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
                       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,
                                             exe_ctx_ref_sp);
    }
    
    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,
                                                SWIGPythonGetValueSynthProviderInstance swig_getvalue_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,
                                                SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
                                                SWIGPython_GetDynamicSetting swig_plugin_get,
                                                SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
                                                SWIGPythonCallThreadPlan swig_call_thread_plan)
{
    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_getvalue_provider = swig_getvalue_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_run_script_keyword_value = swig_run_script_keyword_value;
    g_swig_plugin_get = swig_plugin_get;
    g_swig_thread_plan_script = swig_thread_plan_script;
    g_swig_call_thread_plan = swig_call_thread_plan;
}

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 (HostInfo::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 (HostInfo::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");

    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
