2013-08-23 13:46:38 -04:00
//===-- 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
2013-12-03 13:51:59 -05:00
# include "lldb/lldb-python.h"
2013-08-23 13:46:38 -04:00
# 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"
2014-02-18 11:23:10 -05:00
# include "lldb/Core/Communication.h"
2013-08-23 13:46:38 -04:00
# include "lldb/Core/Debugger.h"
# include "lldb/Core/Timer.h"
2015-02-06 16:38:51 -05:00
# include "lldb/Host/ConnectionFileDescriptor.h"
2014-11-25 16:00:58 -05:00
# include "lldb/Host/HostInfo.h"
# include "lldb/Host/Pipe.h"
2013-08-23 13:46:38 -04:00
# include "lldb/Interpreter/CommandInterpreter.h"
# include "lldb/Interpreter/CommandReturnObject.h"
2014-02-18 11:23:10 -05:00
# include "lldb/Interpreter/PythonDataObjects.h"
2013-08-23 13:46:38 -04:00
# include "lldb/Target/Thread.h"
2015-02-06 16:38:51 -05:00
# include "lldb/Target/ThreadPlan.h"
# if defined(_WIN32)
# include "lldb/Host/windows/ConnectionGenericFileWindows.h"
# endif
2013-08-23 13:46:38 -04:00
using namespace lldb ;
using namespace lldb_private ;
2014-11-25 16:00:58 -05:00
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 ;
2015-02-06 16:38:51 -05:00
static ScriptInterpreter : : SWIGPythonGetValueSynthProviderInstance g_swig_getvalue_provider = nullptr ;
2014-11-25 16:00:58 -05:00
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 ;
2015-02-06 16:38:51 -05:00
static ScriptInterpreter : : SWIGPythonScriptKeyword_Value g_swig_run_script_keyword_value = nullptr ;
2014-11-25 16:00:58 -05:00
static ScriptInterpreter : : SWIGPython_GetDynamicSetting g_swig_plugin_get = nullptr ;
2015-02-06 16:38:51 -05:00
static ScriptInterpreter : : SWIGPythonCreateScriptedThreadPlan g_swig_thread_plan_script = nullptr ;
static ScriptInterpreter : : SWIGPythonCallThreadPlan g_swig_call_thread_plan = nullptr ;
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
static std : : string
ReadPythonBacktrace ( PyObject * py_backtrace ) ;
2013-08-23 13:46:38 -04:00
ScriptInterpreterPython : : Locker : : Locker ( ScriptInterpreterPython * py_interpreter ,
uint16_t on_entry ,
uint16_t on_leave ,
2014-02-18 11:23:10 -05:00
FILE * in ,
FILE * out ,
FILE * err ) :
2013-08-23 13:46:38 -04:00
ScriptInterpreterLocker ( ) ,
m_teardown_session ( ( on_leave & TearDownSession ) = = TearDownSession ) ,
2014-02-18 11:23:10 -05:00
m_python_interpreter ( py_interpreter )
2013-08-23 13:46:38 -04:00
{
DoAcquireLock ( ) ;
if ( ( on_entry & InitSession ) = = InitSession )
{
2014-02-18 11:23:10 -05:00
if ( DoInitSession ( on_entry , in , out , err ) = = false )
2013-08-23 13:46:38 -04:00
{
// 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 " : " " ) ;
2014-11-25 16:00:58 -05:00
// 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 ) ;
2013-08-23 13:46:38 -04:00
return true ;
}
bool
2014-02-18 11:23:10 -05:00
ScriptInterpreterPython : : Locker : : DoInitSession ( uint16_t on_entry_flags , FILE * in , FILE * out , FILE * err )
2013-08-23 13:46:38 -04:00
{
if ( ! m_python_interpreter )
return false ;
2014-02-18 11:23:10 -05:00
return m_python_interpreter - > EnterSession ( on_entry_flags , in , out , err ) ;
2013-08-23 13:46:38 -04:00
}
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 ) ,
2014-02-18 11:23:10 -05:00
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 ( ) ,
2013-08-23 13:46:38 -04:00
m_dictionary_name ( interpreter . GetDebugger ( ) . GetInstanceName ( ) . AsCString ( ) ) ,
m_terminal_state ( ) ,
2014-02-18 11:23:10 -05:00
m_active_io_handler ( eIOHandlerNone ) ,
2013-08-23 13:46:38 -04:00
m_session_is_active ( false ) ,
2014-02-18 11:23:10 -05:00
m_pty_slave_is_open ( false ) ,
2013-08-23 13:46:38 -04:00
m_valid_session ( true ) ,
2014-11-25 16:00:58 -05:00
m_command_thread_state ( nullptr )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
ScriptInterpreterPython : : InitializePrivate ( ) ;
2013-08-23 13:46:38 -04:00
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 ( ) ) ;
2014-02-18 11:23:10 -05:00
run_string . Clear ( ) ;
2013-08-23 13:46:38 -04:00
int new_count = Debugger : : TestDebuggerRefCount ( ) ;
if ( new_count > old_count )
Debugger : : Terminate ( ) ;
2014-02-18 11:23:10 -05:00
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 ( ) ) ;
2013-08-23 13:46:38 -04:00
run_string . Clear ( ) ;
2014-02-18 11:23:10 -05:00
2013-08-23 13:46:38 -04:00
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 ( )
{
2014-02-18 11:23:10 -05:00
}
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
void
ScriptInterpreterPython : : IOHandlerActivated ( IOHandler & io_handler )
{
2014-11-25 16:00:58 -05:00
const char * instructions = nullptr ;
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
switch ( m_active_io_handler )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
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 ;
2013-08-23 13:46:38 -04:00
}
2014-02-18 11:23:10 -05:00
if ( instructions )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
StreamFileSP output_sp ( io_handler . GetOutputStreamFile ( ) ) ;
if ( output_sp )
{
output_sp - > PutCString ( instructions ) ;
output_sp - > Flush ( ) ;
}
2013-08-23 13:46:38 -04:00
}
}
void
2014-02-18 11:23:10 -05:00
ScriptInterpreterPython : : IOHandlerInputComplete ( IOHandler & io_handler , std : : string & data )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
io_handler . SetIsDone ( true ) ;
bool batch_mode = m_interpreter . GetBatchCommandMode ( ) ;
switch ( m_active_io_handler )
{
case eIOHandlerNone :
break ;
case eIOHandlerBreakpoint :
{
2014-11-25 16:00:58 -05:00
std : : vector < BreakpointOptions * > * bp_options_vec = ( std : : vector < BreakpointOptions * > * ) io_handler . GetUserData ( ) ;
for ( auto bp_options : * bp_options_vec )
2014-02-18 11:23:10 -05:00
{
2014-11-25 16:00:58 -05:00
if ( ! bp_options )
continue ;
std : : unique_ptr < BreakpointOptions : : CommandData > data_ap ( new BreakpointOptions : : CommandData ( ) ) ;
if ( data_ap . get ( ) )
2014-02-18 11:23:10 -05:00
{
2014-11-25 16:00:58 -05:00
data_ap - > user_source . SplitIntoLines ( data ) ;
if ( GenerateBreakpointCommandCallbackData ( data_ap - > user_source , data_ap - > script_source ) . Success ( ) )
2014-02-18 11:23:10 -05:00
{
2014-11-25 16:00:58 -05:00
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 ( ) ;
}
2014-02-18 11:23:10 -05:00
}
}
}
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 )
{
2013-08-23 13:46:38 -04:00
}
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 ( ) )
{
2014-02-18 11:23:10 -05:00
PythonDictionary & sys_module_dict = GetSysModuleDictionary ( ) ;
if ( sys_module_dict )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
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 ( ) ;
}
2013-08-23 13:46:38 -04:00
}
}
m_session_is_active = false ;
}
bool
2014-02-18 11:23:10 -05:00
ScriptInterpreterPython : : EnterSession ( uint16_t on_entry_flags ,
FILE * in ,
FILE * out ,
FILE * err )
2013-08-23 13:46:38 -04:00
{
// 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 )
2014-02-18 11:23:10 -05:00
log - > Printf ( " ScriptInterpreterPython::EnterSession(on_entry_flags=0x% " PRIx16 " ) session is already active, returning without doing anything " , on_entry_flags ) ;
2013-08-23 13:46:38 -04:00
return false ;
}
if ( log )
2014-02-18 11:23:10 -05:00
log - > Printf ( " ScriptInterpreterPython::EnterSession(on_entry_flags=0x% " PRIx16 " ) " , on_entry_flags ) ;
2013-08-23 13:46:38 -04:00
m_session_is_active = true ;
StreamString run_string ;
2014-02-18 11:23:10 -05:00
if ( on_entry_flags & Locker : : InitGlobals )
2013-08-23 13:46:38 -04:00
{
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.)
2014-02-18 11:23:10 -05:00
run_string . Printf ( " run_one_line (%s, 'lldb.debugger_unique_id = % " PRIu64 , m_dictionary_name . c_str ( ) , GetCommandInterpreter ( ) . GetDebugger ( ) . GetID ( ) ) ;
2013-08-23 13:46:38 -04:00
run_string . Printf ( " ; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (% " PRIu64 " ) " , GetCommandInterpreter ( ) . GetDebugger ( ) . GetID ( ) ) ;
2014-02-18 11:23:10 -05:00
run_string . PutCString ( " ') " ) ;
2013-08-23 13:46:38 -04:00
}
PyRun_SimpleString ( run_string . GetData ( ) ) ;
run_string . Clear ( ) ;
2014-02-18 11:23:10 -05:00
PythonDictionary & sys_module_dict = GetSysModuleDictionary ( ) ;
if ( sys_module_dict )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
lldb : : StreamFileSP in_sp ;
lldb : : StreamFileSP out_sp ;
lldb : : StreamFileSP err_sp ;
2014-11-25 16:00:58 -05:00
if ( in = = nullptr | | out = = nullptr | | err = = nullptr )
2014-02-18 11:23:10 -05:00
m_interpreter . GetDebugger ( ) . AdoptTopIOHandlerFilesIfInvalid ( in_sp , out_sp , err_sp ) ;
2015-02-06 16:38:51 -05:00
m_saved_stdin . Reset ( ) ;
2014-02-18 11:23:10 -05:00
2015-02-06 16:38:51 -05:00
if ( ( on_entry_flags & Locker : : NoSTDIN ) = = 0 )
{
// STDIN is enabled
if ( in = = nullptr & & in_sp )
in = in_sp - > GetFile ( ) . GetStream ( ) ;
if ( in )
{
m_saved_stdin . Reset ( sys_module_dict . GetItemForKey ( " stdin " ) ) ;
// This call can deadlock your process if the file is locked
PyObject * new_file = PyFile_FromFile ( in , ( char * ) " " , ( char * ) " r " , nullptr ) ;
sys_module_dict . SetItemForKey ( " stdin " , new_file ) ;
Py_DECREF ( new_file ) ;
}
2013-08-23 13:46:38 -04:00
}
2015-02-06 16:38:51 -05:00
2014-11-25 16:00:58 -05:00
if ( out = = nullptr & & out_sp )
2014-02-18 11:23:10 -05:00
out = out_sp - > GetFile ( ) . GetStream ( ) ;
if ( out )
{
m_saved_stdout . Reset ( sys_module_dict . GetItemForKey ( " stdout " ) ) ;
2014-11-25 16:00:58 -05:00
PyObject * new_file = PyFile_FromFile ( out , ( char * ) " " , ( char * ) " w " , nullptr ) ;
2014-02-18 11:23:10 -05:00
sys_module_dict . SetItemForKey ( " stdout " , new_file ) ;
Py_DECREF ( new_file ) ;
}
else
m_saved_stdout . Reset ( ) ;
2014-11-25 16:00:58 -05:00
if ( err = = nullptr & & err_sp )
2014-02-18 11:23:10 -05:00
err = err_sp - > GetFile ( ) . GetStream ( ) ;
if ( err )
{
m_saved_stderr . Reset ( sys_module_dict . GetItemForKey ( " stderr " ) ) ;
2014-11-25 16:00:58 -05:00
PyObject * new_file = PyFile_FromFile ( err , ( char * ) " " , ( char * ) " w " , nullptr ) ;
2014-02-18 11:23:10 -05:00
sys_module_dict . SetItemForKey ( " stderr " , new_file ) ;
Py_DECREF ( new_file ) ;
}
else
m_saved_stderr . Reset ( ) ;
2013-08-23 13:46:38 -04:00
}
if ( PyErr_Occurred ( ) )
PyErr_Clear ( ) ;
return true ;
}
2014-02-18 11:23:10 -05:00
PythonObject &
ScriptInterpreterPython : : GetMainModule ( )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
if ( ! m_main_module )
m_main_module . Reset ( PyImport_AddModule ( " __main__ " ) ) ;
return m_main_module ;
}
PythonDictionary &
ScriptInterpreterPython : : GetSessionDictionary ( )
{
if ( ! m_session_dict )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
PythonObject & main_module = GetMainModule ( ) ;
if ( main_module )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
PythonDictionary main_dict ( PyModule_GetDict ( main_module . get ( ) ) ) ;
if ( main_dict )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
m_session_dict = main_dict . GetItemForKey ( m_dictionary_name . c_str ( ) ) ;
2013-08-23 13:46:38 -04:00
}
}
}
2014-02-18 11:23:10 -05:00
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 ;
2013-08-23 13:46:38 -04:00
}
static std : : string
GenerateUniqueName ( const char * base_name_wanted ,
uint32_t & functions_counter ,
2014-11-25 16:00:58 -05:00
void * name_token = nullptr )
2013-08-23 13:46:38 -04:00
{
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 ( ) ;
}
2014-02-18 11:23:10 -05:00
bool
ScriptInterpreterPython : : GetEmbeddedInterpreterModuleObjects ( )
{
if ( ! m_run_one_line_function )
{
PyObject * module = PyImport_AddModule ( " lldb.embedded_interpreter " ) ;
2014-11-25 16:00:58 -05:00
if ( module ! = nullptr )
2014-02-18 11:23:10 -05:00
{
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 ( ) ;
}
}
2013-08-23 13:46:38 -04:00
bool
ScriptInterpreterPython : : ExecuteOneLine ( const char * command , CommandReturnObject * result , const ExecuteScriptOptions & options )
{
if ( ! m_valid_session )
return false ;
2014-02-18 11:23:10 -05:00
if ( command & & command [ 0 ] )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
// 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 " ) ;
2014-11-25 16:00:58 -05:00
bool join_read_thread = false ;
2014-02-18 11:23:10 -05:00
if ( options . GetEnableIO ( ) )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
if ( result )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
input_file_sp = debugger . GetInputFile ( ) ;
// Set output to a temporary file so we can forward the results on to the result object
2014-11-25 16:00:58 -05:00
Pipe pipe ;
2015-02-06 16:38:51 -05:00
Error pipe_result = pipe . CreateNew ( false ) ;
if ( pipe_result . Success ( ) )
2013-08-23 13:46:38 -04:00
{
2015-02-06 16:38:51 -05:00
# if defined(_WIN32)
lldb : : file_t read_file = pipe . GetReadNativeHandle ( ) ;
pipe . ReleaseReadFileDescriptor ( ) ;
std : : unique_ptr < ConnectionGenericFile > conn_ap ( new ConnectionGenericFile ( read_file , true ) ) ;
# else
2014-11-25 16:00:58 -05:00
std : : unique_ptr < ConnectionFileDescriptor > conn_ap ( new ConnectionFileDescriptor ( pipe . ReleaseReadFileDescriptor ( ) , true ) ) ;
2015-02-06 16:38:51 -05:00
# endif
2014-02-18 11:23:10 -05:00
if ( conn_ap - > IsConnected ( ) )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
output_comm . SetConnection ( conn_ap . release ( ) ) ;
output_comm . SetReadThreadBytesReceivedCallback ( ReadThreadBytesReceived , & result - > GetOutputStream ( ) ) ;
output_comm . StartReadThread ( ) ;
2014-11-25 16:00:58 -05:00
join_read_thread = true ;
FILE * outfile_handle = fdopen ( pipe . ReleaseWriteFileDescriptor ( ) , " w " ) ;
2014-02-18 11:23:10 -05:00
output_file_sp . reset ( new StreamFile ( outfile_handle , true ) ) ;
error_file_sp = output_file_sp ;
if ( outfile_handle )
2014-11-25 16:00:58 -05:00
: : setbuf ( outfile_handle , nullptr ) ;
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
result - > SetImmediateOutputFile ( debugger . GetOutputFile ( ) - > GetFile ( ) . GetStream ( ) ) ;
result - > SetImmediateErrorFile ( debugger . GetErrorFile ( ) - > GetFile ( ) . GetStream ( ) ) ;
2013-08-23 13:46:38 -04:00
}
2014-02-18 11:23:10 -05:00
}
}
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 |
2015-02-06 16:38:51 -05:00
( options . GetSetLLDBGlobals ( ) ? ScriptInterpreterPython : : Locker : : InitGlobals : 0 ) |
( ( result & & result - > GetInteractive ( ) ) ? 0 : Locker : : NoSTDIN ) ,
2014-02-18 11:23:10 -05:00
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 )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
PythonObject return_value ( PyObject_CallObject ( pfunc , pargs . get ( ) ) ) ;
if ( return_value )
success = true ;
else if ( options . GetMaskoutErrors ( ) & & PyErr_Occurred ( ) )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
2013-08-23 13:46:38 -04:00
}
}
}
}
}
2014-02-18 11:23:10 -05:00
// Flush our output and error file handles
: : fflush ( out_file ) ;
if ( out_file ! = err_file )
: : fflush ( err_file ) ;
2014-11-25 16:00:58 -05:00
if ( join_read_thread )
2014-02-18 11:23:10 -05:00
{
// 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 ( ) ;
}
2013-08-23 13:46:38 -04:00
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 ;
}
2014-02-18 11:23:10 -05:00
class IOHandlerPythonInterpreter :
public IOHandler
{
public :
IOHandlerPythonInterpreter ( Debugger & debugger ,
ScriptInterpreterPython * python ) :
2015-02-06 16:38:51 -05:00
IOHandler ( debugger , IOHandler : : Type : : PythonInterpreter ) ,
2014-02-18 11:23:10 -05:00
m_python ( python )
{
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
}
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
virtual
~ IOHandlerPythonInterpreter ( )
{
}
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
virtual ConstString
GetControlSequence ( char ch )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
if ( ch = = ' d ' )
return ConstString ( " quit() \ n " ) ;
return ConstString ( ) ;
}
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
virtual void
Run ( )
{
if ( m_python )
{
int stdin_fd = GetInputFD ( ) ;
if ( stdin_fd > = 0 )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
Terminal terminal ( stdin_fd ) ;
TerminalState terminal_state ;
const bool is_a_tty = terminal . IsATerminal ( ) ;
if ( is_a_tty )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
terminal_state . Save ( stdin_fd , false ) ;
terminal . SetCanonical ( false ) ;
terminal . SetEcho ( true ) ;
2013-08-23 13:46:38 -04:00
}
2014-02-18 11:23:10 -05:00
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 ( ) ;
2013-08-23 13:46:38 -04:00
}
}
2014-02-18 11:23:10 -05:00
SetIsDone ( true ) ;
}
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
virtual void
Hide ( )
{
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
}
virtual void
Refresh ( )
{
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
}
2014-02-25 16:42:16 -05:00
virtual void
Cancel ( )
{
}
2014-11-25 16:00:58 -05:00
virtual bool
2014-02-18 11:23:10 -05:00
Interrupt ( )
{
2014-11-25 16:00:58 -05:00
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 ;
2014-02-18 11:23:10 -05:00
}
virtual void
GotEOF ( )
{
2013-08-23 13:46:38 -04:00
}
2014-02-18 11:23:10 -05:00
protected :
ScriptInterpreterPython * m_python ;
} ;
2013-08-23 13:46:38 -04:00
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.
2014-02-18 11:23:10 -05:00
if ( ! debugger . GetInputFile ( ) - > GetFile ( ) . IsValid ( ) )
2013-08-23 13:46:38 -04:00
return ;
2014-02-18 11:23:10 -05:00
IOHandlerSP io_handler_sp ( new IOHandlerPythonInterpreter ( debugger , this ) ) ;
if ( io_handler_sp )
{
debugger . PushIOHandler ( io_handler_sp ) ;
2013-08-23 13:46:38 -04:00
}
}
bool
ScriptInterpreterPython : : ExecuteOneLineWithReturn ( const char * in_string ,
ScriptInterpreter : : ScriptReturnType return_type ,
void * ret_value ,
const ExecuteScriptOptions & options )
{
Locker locker ( this ,
2014-11-25 16:00:58 -05:00
ScriptInterpreterPython : : Locker : : AcquireLock | ScriptInterpreterPython : : Locker : : InitSession | ( options . GetSetLLDBGlobals ( ) ? ScriptInterpreterPython : : Locker : : InitGlobals : 0 ) | Locker : : NoSTDIN ,
2013-08-23 13:46:38 -04:00
ScriptInterpreterPython : : Locker : : FreeAcquiredLock | ScriptInterpreterPython : : Locker : : TearDownSession ) ;
2014-11-25 16:00:58 -05:00
PyObject * py_return = nullptr ;
2014-02-18 11:23:10 -05:00
PythonObject & main_module = GetMainModule ( ) ;
PythonDictionary globals ( PyModule_GetDict ( main_module . get ( ) ) ) ;
2014-11-25 16:00:58 -05:00
PyObject * py_error = nullptr ;
2013-08-23 13:46:38 -04:00
bool ret_success = false ;
int success ;
2014-02-18 11:23:10 -05:00
PythonDictionary locals = GetSessionDictionary ( ) ;
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
if ( ! locals )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
locals = PyObject_GetAttrString ( globals . get ( ) , m_dictionary_name . c_str ( ) ) ;
2013-08-23 13:46:38 -04:00
}
2014-02-18 11:23:10 -05:00
if ( ! locals )
2013-08-23 13:46:38 -04:00
locals = globals ;
py_error = PyErr_Occurred ( ) ;
2014-11-25 16:00:58 -05:00
if ( py_error ! = nullptr )
2013-08-23 13:46:38 -04:00
PyErr_Clear ( ) ;
2014-11-25 16:00:58 -05:00
if ( in_string ! = nullptr )
2013-08-23 13:46:38 -04:00
{
{ // scope for PythonInputReaderManager
2014-02-18 11:23:10 -05:00
//PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
py_return = PyRun_String ( in_string , Py_eval_input , globals . get ( ) , locals . get ( ) ) ;
2014-11-25 16:00:58 -05:00
if ( py_return = = nullptr )
2013-08-23 13:46:38 -04:00
{
py_error = PyErr_Occurred ( ) ;
2014-11-25 16:00:58 -05:00
if ( py_error ! = nullptr )
2013-08-23 13:46:38 -04:00
PyErr_Clear ( ) ;
2014-02-18 11:23:10 -05:00
py_return = PyRun_String ( in_string , Py_single_input , globals . get ( ) , locals . get ( ) ) ;
2013-08-23 13:46:38 -04:00
}
}
2014-11-25 16:00:58 -05:00
if ( py_return ! = nullptr )
2013-08-23 13:46:38 -04:00
{
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 ;
}
2013-11-06 11:48:53 -05:00
case eScriptReturnTypeOpaqueObject :
{
success = true ;
Py_XINCREF ( py_return ) ;
* ( ( PyObject * * ) ret_value ) = py_return ;
break ;
}
2013-08-23 13:46:38 -04:00
}
Py_XDECREF ( py_return ) ;
if ( success )
ret_success = true ;
else
ret_success = false ;
}
}
py_error = PyErr_Occurred ( ) ;
2014-11-25 16:00:58 -05:00
if ( py_error ! = nullptr )
2013-08-23 13:46:38 -04:00
{
ret_success = false ;
if ( options . GetMaskoutErrors ( ) )
{
if ( PyErr_GivenExceptionMatches ( py_error , PyExc_SyntaxError ) )
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
}
}
return ret_success ;
}
2014-02-18 11:23:10 -05:00
Error
2013-08-23 13:46:38 -04:00
ScriptInterpreterPython : : ExecuteMultipleLines ( const char * in_string , const ExecuteScriptOptions & options )
{
2014-02-18 11:23:10 -05:00
Error error ;
2013-08-23 13:46:38 -04:00
Locker locker ( this ,
2014-11-25 16:00:58 -05:00
ScriptInterpreterPython : : Locker : : AcquireLock | ScriptInterpreterPython : : Locker : : InitSession | ( options . GetSetLLDBGlobals ( ) ? ScriptInterpreterPython : : Locker : : InitGlobals : 0 ) | Locker : : NoSTDIN ,
2013-08-23 13:46:38 -04:00
ScriptInterpreterPython : : Locker : : FreeAcquiredLock | ScriptInterpreterPython : : Locker : : TearDownSession ) ;
2014-02-18 11:23:10 -05:00
PythonObject return_value ;
PythonObject & main_module = GetMainModule ( ) ;
PythonDictionary globals ( PyModule_GetDict ( main_module . get ( ) ) ) ;
2014-11-25 16:00:58 -05:00
PyObject * py_error = nullptr ;
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
PythonDictionary locals = GetSessionDictionary ( ) ;
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
if ( ! locals )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
locals = PyObject_GetAttrString ( globals . get ( ) , m_dictionary_name . c_str ( ) ) ;
2013-08-23 13:46:38 -04:00
}
2014-02-18 11:23:10 -05:00
if ( ! locals )
2013-08-23 13:46:38 -04:00
{
locals = globals ;
}
py_error = PyErr_Occurred ( ) ;
2014-11-25 16:00:58 -05:00
if ( py_error ! = nullptr )
2013-08-23 13:46:38 -04:00
PyErr_Clear ( ) ;
2014-11-25 16:00:58 -05:00
if ( in_string ! = nullptr )
2013-08-23 13:46:38 -04:00
{
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 )
{
2014-11-25 16:00:58 -05:00
return_value . Reset ( PyEval_EvalCode ( compiled_code , globals . get ( ) , locals . get ( ) ) ) ;
2013-08-23 13:46:38 -04:00
}
}
}
py_error = PyErr_Occurred ( ) ;
2014-11-25 16:00:58 -05:00
if ( py_error ! = nullptr )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
// puts(in_string);
// _PyObject_Dump (py_error);
// PyErr_Print();
// success = false;
2013-08-23 13:46:38 -04:00
2014-11-25 16:00:58 -05:00
PyObject * type = nullptr ;
PyObject * value = nullptr ;
PyObject * traceback = nullptr ;
2014-02-18 11:23:10 -05:00
PyErr_Fetch ( & type , & value , & traceback ) ;
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
// get the backtrace
std : : string bt = ReadPythonBacktrace ( traceback ) ;
2013-08-23 13:46:38 -04:00
2014-02-18 11:23:10 -05:00
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 ( ) )
2013-08-23 13:46:38 -04:00
{
2014-02-18 11:23:10 -05:00
PyErr_Clear ( ) ;
2013-08-23 13:46:38 -04:00
}
}
2014-02-18 11:23:10 -05:00
return error ;
2013-08-23 13:46:38 -04:00
}
void
2014-11-25 16:00:58 -05:00
ScriptInterpreterPython : : CollectDataForBreakpointCommandCallback ( std : : vector < BreakpointOptions * > & bp_options_vec ,
2013-08-23 13:46:38 -04:00
CommandReturnObject & result )
{
2014-02-18 11:23:10 -05:00
m_active_io_handler = eIOHandlerBreakpoint ;
2014-11-25 16:00:58 -05:00
m_interpreter . GetPythonCommandsFromIOHandler ( " " , * this , true , & bp_options_vec ) ;
2013-08-23 13:46:38 -04:00
}
void
ScriptInterpreterPython : : CollectDataForWatchpointCommandCallback ( WatchpointOptions * wp_options ,
CommandReturnObject & result )
{
2014-02-18 11:23:10 -05:00
m_active_io_handler = eIOHandlerWatchpoint ;
m_interpreter . GetPythonCommandsFromIOHandler ( " " , * this , true , wp_options ) ;
2013-08-23 13:46:38 -04:00
}
void
2014-11-25 16:00:58 -05:00
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
2013-08-23 13:46:38 -04:00
ScriptInterpreterPython : : SetBreakpointCommandCallback ( BreakpointOptions * bp_options ,
2014-11-25 16:00:58 -05:00
const char * command_body_text )
2013-08-23 13:46:38 -04:00
{
std : : unique_ptr < BreakpointOptions : : CommandData > data_ap ( new BreakpointOptions : : CommandData ( ) ) ;
2014-11-25 16:00:58 -05:00
// 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 ( ) )
2013-08-23 13:46:38 -04:00
{
BatonSP baton_sp ( new BreakpointOptions : : CommandBaton ( data_ap . release ( ) ) ) ;
bp_options - > SetCallback ( ScriptInterpreterPython : : BreakpointCallbackFunction , baton_sp ) ;
2014-11-25 16:00:58 -05:00
return error ;
2013-08-23 13:46:38 -04:00
}
2014-11-25 16:00:58 -05:00
else
return error ;
2013-08-23 13:46:38 -04:00
}
// 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 ;
}
2014-11-25 16:00:58 -05:00
Error
2013-08-23 13:46:38 -04:00
ScriptInterpreterPython : : ExportFunctionDefinitionToInterpreter ( StringList & function_def )
{
// Convert StringList to one long, newline delimited, const char *.
std : : string function_def_string ( function_def . CopyList ( ) ) ;
2014-11-25 16:00:58 -05:00
Error error = ExecuteMultipleLines ( function_def_string . c_str ( ) , ScriptInterpreter : : ExecuteScriptOptions ( ) . SetEnableIO ( false ) ) ;
return error ;
2013-08-23 13:46:38 -04:00
}
2014-11-25 16:00:58 -05:00
Error
2013-08-23 13:46:38 -04:00
ScriptInterpreterPython : : GenerateFunction ( const char * signature , const StringList & input )
{
2014-11-25 16:00:58 -05:00
Error error ;
2013-08-23 13:46:38 -04:00
int num_lines = input . GetSize ( ) ;
if ( num_lines = = 0 )
2014-11-25 16:00:58 -05:00
{
error . SetErrorString ( " No input data. " ) ;
return error ;
}
2013-08-23 13:46:38 -04:00
if ( ! signature | | * signature = = 0 )
2014-11-25 16:00:58 -05:00
{
error . SetErrorString ( " No output function name. " ) ;
return error ;
}
2013-08-23 13:46:38 -04:00
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.
2014-11-25 16:00:58 -05:00
error = ExportFunctionDefinitionToInterpreter ( auto_generated_function ) ;
2013-08-23 13:46:38 -04:00
2014-11-25 16:00:58 -05:00
return error ;
2013-08-23 13:46:38 -04:00
}
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 ( ) ) ;
2014-11-25 16:00:58 -05:00
if ( ! GenerateFunction ( sstr . GetData ( ) , user_input ) . Success ( ) )
2013-08-23 13:46:38 -04:00
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 ( ) ) ;
2014-11-25 16:00:58 -05:00
if ( ! GenerateFunction ( sstr . GetData ( ) , user_input ) . Success ( ) )
2013-08-23 13:46:38 -04:00
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)
2014-11-25 16:00:58 -05:00
if ( ! ExportFunctionDefinitionToInterpreter ( auto_generated_class ) . Success ( ) )
2013-08-23 13:46:38 -04:00
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 )
{
2014-11-25 16:00:58 -05:00
if ( class_name = = nullptr | | class_name [ 0 ] = = ' \0 ' )
2013-08-23 13:46:38 -04:00
return lldb : : ScriptInterpreterObjectSP ( ) ;
if ( ! process_sp )
return lldb : : ScriptInterpreterObjectSP ( ) ;
void * ret_val ;
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this ,
Locker : : AcquireLock | Locker : : NoSTDIN ,
Locker : : FreeLock ) ;
2013-08-23 13:46:38 -04:00
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 )
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this ,
Locker : : AcquireLock | Locker : : NoSTDIN ,
Locker : : FreeLock ) ;
2013-08-23 13:46:38 -04:00
static char callee_name [ ] = " get_register_info " ;
if ( ! os_plugin_object_sp )
return lldb : : ScriptInterpreterObjectSP ( ) ;
PyObject * implementor = ( PyObject * ) os_plugin_object_sp - > GetObject ( ) ;
2014-11-25 16:00:58 -05:00
if ( implementor = = nullptr | | implementor = = Py_None )
2013-08-23 13:46:38 -04:00
return lldb : : ScriptInterpreterObjectSP ( ) ;
PyObject * pmeth = PyObject_GetAttrString ( implementor , callee_name ) ;
if ( PyErr_Occurred ( ) )
{
PyErr_Clear ( ) ;
}
2014-11-25 16:00:58 -05:00
if ( pmeth = = nullptr | | pmeth = = Py_None )
2013-08-23 13:46:38 -04:00
{
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..
2014-11-25 16:00:58 -05:00
PyObject * py_return = PyObject_CallMethod ( implementor , callee_name , nullptr ) ;
2013-08-23 13:46:38 -04:00
// 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 )
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this ,
Locker : : AcquireLock | Locker : : NoSTDIN ,
Locker : : FreeLock ) ;
2013-08-23 13:46:38 -04:00
static char callee_name [ ] = " get_thread_info " ;
if ( ! os_plugin_object_sp )
return lldb : : ScriptInterpreterObjectSP ( ) ;
PyObject * implementor = ( PyObject * ) os_plugin_object_sp - > GetObject ( ) ;
2014-11-25 16:00:58 -05:00
if ( implementor = = nullptr | | implementor = = Py_None )
2013-08-23 13:46:38 -04:00
return lldb : : ScriptInterpreterObjectSP ( ) ;
PyObject * pmeth = PyObject_GetAttrString ( implementor , callee_name ) ;
if ( PyErr_Occurred ( ) )
{
PyErr_Clear ( ) ;
}
2014-11-25 16:00:58 -05:00
if ( pmeth = = nullptr | | pmeth = = Py_None )
2013-08-23 13:46:38 -04:00
{
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..
2014-11-25 16:00:58 -05:00
PyObject * py_return = PyObject_CallMethod ( implementor , callee_name , nullptr ) ;
2013-08-23 13:46:38 -04:00
// 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. " ) ;
2014-11-25 16:00:58 -05:00
return nullptr ;
2013-08-23 13:46:38 -04:00
}
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 )
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this ,
Locker : : AcquireLock | Locker : : NoSTDIN ,
Locker : : FreeLock ) ;
2013-08-23 13:46:38 -04:00
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 ( ) ;
2014-11-25 16:00:58 -05:00
if ( implementor = = nullptr | | implementor = = Py_None )
2013-08-23 13:46:38 -04:00
return lldb : : ScriptInterpreterObjectSP ( ) ;
PyObject * pmeth = PyObject_GetAttrString ( implementor , callee_name ) ;
if ( PyErr_Occurred ( ) )
{
PyErr_Clear ( ) ;
}
2014-11-25 16:00:58 -05:00
if ( pmeth = = nullptr | | pmeth = = Py_None )
2013-08-23 13:46:38 -04:00
{
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 )
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this ,
Locker : : AcquireLock | Locker : : NoSTDIN ,
Locker : : FreeLock ) ;
2013-08-23 13:46:38 -04:00
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 ( ) ;
2014-11-25 16:00:58 -05:00
if ( implementor = = nullptr | | implementor = = Py_None )
2013-08-23 13:46:38 -04:00
return lldb : : ScriptInterpreterObjectSP ( ) ;
PyObject * pmeth = PyObject_GetAttrString ( implementor , callee_name ) ;
if ( PyErr_Occurred ( ) )
{
PyErr_Clear ( ) ;
}
2014-11-25 16:00:58 -05:00
if ( pmeth = = nullptr | | pmeth = = Py_None )
2013-08-23 13:46:38 -04:00
{
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 ) ;
}
2015-02-06 16:38:51 -05:00
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 ;
}
2013-11-06 11:48:53 -05:00
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 ;
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
2013-11-06 11:48:53 -05:00
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 ) ;
}
2013-08-23 13:46:38 -04:00
lldb : : ScriptInterpreterObjectSP
ScriptInterpreterPython : : CreateSyntheticScriptedProvider ( const char * class_name ,
lldb : : ValueObjectSP valobj )
{
2014-11-25 16:00:58 -05:00
if ( class_name = = nullptr | | class_name [ 0 ] = = ' \0 ' )
2013-08-23 13:46:38 -04:00
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 ;
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
2013-08-23 13:46:38 -04:00
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 ) ;
}
2014-11-25 16:00:58 -05:00
Error
2013-08-23 13:46:38 -04:00
ScriptInterpreterPython : : GenerateBreakpointCommandCallbackData ( StringList & user_input , std : : string & output )
{
static uint32_t num_created_functions = 0 ;
user_input . RemoveBlankLines ( ) ;
StreamString sstr ;
2014-11-25 16:00:58 -05:00
Error error ;
2013-08-23 13:46:38 -04:00
if ( user_input . GetSize ( ) = = 0 )
2014-11-25 16:00:58 -05:00
{
error . SetErrorString ( " No input data. " ) ;
return error ;
}
2013-08-23 13:46:38 -04:00
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 ( ) ) ;
2014-11-25 16:00:58 -05:00
error = GenerateFunction ( sstr . GetData ( ) , user_input ) ;
if ( ! error . Success ( ) )
return error ;
2013-08-23 13:46:38 -04:00
// Store the name of the auto-generated function to be called.
output . assign ( auto_generated_function_name ) ;
2014-11-25 16:00:58 -05:00
return error ;
2013-08-23 13:46:38 -04:00
}
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 ( ) ) ;
2014-11-25 16:00:58 -05:00
if ( ! GenerateFunction ( sstr . GetData ( ) , user_input ) . Success ( ) )
2013-08-23 13:46:38 -04:00
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 ,
2015-02-06 16:38:51 -05:00
const TypeSummaryOptions & options ,
2013-08-23 13:46:38 -04:00
std : : string & retval )
{
Timer scoped_timer ( __PRETTY_FUNCTION__ , __PRETTY_FUNCTION__ ) ;
if ( ! valobj . get ( ) )
{
retval . assign ( " <no object> " ) ;
return false ;
}
2014-11-25 16:00:58 -05:00
void * old_callee = ( callee_wrapper_sp ? callee_wrapper_sp - > GetObject ( ) : nullptr ) ;
2013-08-23 13:46:38 -04:00
void * new_callee = old_callee ;
bool ret_val ;
if ( python_function_name
& & * python_function_name )
{
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
2013-08-23 13:46:38 -04:00
{
2015-02-06 16:38:51 -05:00
TypeSummaryOptionsSP options_sp ( new TypeSummaryOptions ( options ) ) ;
2014-02-18 11:23:10 -05:00
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 ,
2015-02-06 16:38:51 -05:00
options_sp ,
2014-02-18 11:23:10 -05:00
retval ) ;
2013-08-23 13:46:38 -04:00
}
}
}
else
{
retval . assign ( " <no function name> " ) ;
return false ;
}
if ( new_callee & & old_callee ! = new_callee )
callee_wrapper_sp = MakeScriptObject ( new_callee ) ;
return ret_val ;
}
2014-11-25 16:00:58 -05:00
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 " ) ;
}
2013-08-23 13:46:38 -04:00
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 ;
2014-02-18 11:23:10 -05:00
if ( python_function_name & & python_function_name [ 0 ] )
2013-08-23 13:46:38 -04:00
{
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 ;
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( python_interpreter , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
ret_val = g_swig_breakpoint_callback ( python_function_name ,
2013-08-23 13:46:38 -04:00
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 ;
2014-02-18 11:23:10 -05:00
if ( python_function_name & & python_function_name [ 0 ] )
2013-08-23 13:46:38 -04:00
{
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 ;
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( python_interpreter , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
ret_val = g_swig_watchpoint_callback ( python_function_name ,
2013-08-23 13:46:38 -04:00
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 ;
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
2013-08-23 13:46:38 -04:00
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 ;
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
2013-11-06 11:48:53 -05:00
void * child_ptr = g_swig_get_child_index ( implementor , idx ) ;
2014-11-25 16:00:58 -05:00
if ( child_ptr ! = nullptr & & child_ptr ! = Py_None )
2013-08-23 13:46:38 -04:00
{
2013-11-06 11:48:53 -05:00
lldb : : SBValue * sb_value_ptr = ( lldb : : SBValue * ) g_swig_cast_to_sbvalue ( child_ptr ) ;
2014-11-25 16:00:58 -05:00
if ( sb_value_ptr = = nullptr )
2013-08-23 13:46:38 -04:00
Py_XDECREF ( child_ptr ) ;
else
2013-11-06 11:48:53 -05:00
ret_val = g_swig_get_valobj_sp_from_sbvalue ( sb_value_ptr ) ;
2013-08-23 13:46:38 -04:00
}
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 ;
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
2013-08-23 13:46:38 -04:00
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 ;
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
2013-08-23 13:46:38 -04:00
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 ;
{
2014-02-18 11:23:10 -05:00
Locker py_lock ( this , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
2013-08-23 13:46:38 -04:00
ret_val = g_swig_mighthavechildren_provider ( implementor ) ;
}
return ret_val ;
}
2015-02-06 16:38:51 -05:00
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 ;
}
2013-08-23 13:46:38 -04:00
static std : : string
ReadPythonBacktrace ( PyObject * py_backtrace )
{
2014-11-25 16:00:58 -05:00
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 ;
2013-08-23 13:46:38 -04:00
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 )
{
2014-11-25 16:00:58 -05:00
stringIO_buffer = PyObject_CallObject ( stringIO_builder , nullptr ) ;
2013-08-23 13:46:38 -04:00
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 )
{
2014-11-25 16:00:58 -05:00
printTB_string = PyObject_CallObject ( stringIO_getvalue , nullptr ) ;
2013-08-23 13:46:38 -04:00
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 ( ) ) ;
2014-02-18 11:23:10 -05:00
Locker py_lock ( this , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
2013-08-23 13:46:38 -04:00
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 ( ) ) ;
2014-02-18 11:23:10 -05:00
Locker py_lock ( this , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
2013-08-23 13:46:38 -04:00
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 ( ) ) ;
2014-02-18 11:23:10 -05:00
Locker py_lock ( this , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
2013-08-23 13:46:38 -04:00
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 ( ) ) ;
2014-02-18 11:23:10 -05:00
Locker py_lock ( this , Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ) ;
2013-08-23 13:46:38 -04:00
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 ;
}
2015-02-06 16:38:51 -05:00
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 ;
}
2013-08-23 13:46:38 -04:00
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 ,
2013-11-06 11:48:53 -05:00
lldb_private : : Error & error ,
lldb : : ScriptInterpreterObjectSP * module_sp )
2013-08-23 13:46:38 -04:00
{
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 ,
2014-02-18 11:23:10 -05:00
Locker : : AcquireLock | ( init_session ? Locker : : InitSession : 0 ) | Locker : : NoSTDIN ,
2013-08-23 13:46:38 -04:00
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 ( ) ) ;
2014-02-18 11:23:10 -05:00
bool syspath_retval = ExecuteMultipleLines ( command_stream . GetData ( ) , ScriptInterpreter : : ExecuteScriptOptions ( ) . SetEnableIO ( false ) . SetSetLLDBGlobals ( false ) ) . Success ( ) ;
2013-08-23 13:46:38 -04:00
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 ( ) ) ;
2014-02-25 16:42:16 -05:00
bool was_imported_locally = ! ( GetSessionDictionary ( ) . GetItemForKey ( basename . c_str ( ) ) . IsNULLOrNone ( ) ) ;
2013-08-23 13:46:38 -04:00
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 ( ) ) ;
2014-02-18 11:23:10 -05:00
error = ExecuteMultipleLines ( command_stream . GetData ( ) , ScriptInterpreter : : ExecuteScriptOptions ( ) . SetEnableIO ( false ) . SetSetLLDBGlobals ( false ) ) ;
if ( error . Fail ( ) )
2013-08-23 13:46:38 -04:00
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 ;
}
2013-11-06 11:48:53 -05:00
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 ) ;
}
2013-08-23 13:46:38 -04:00
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 ,
2015-02-06 16:38:51 -05:00
Error & error ,
const lldb_private : : ExecutionContext & exe_ctx )
2013-08-23 13:46:38 -04:00
{
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 ( ) ;
2015-02-06 16:38:51 -05:00
lldb : : ExecutionContextRefSP exe_ctx_ref_sp ( new ExecutionContextRef ( exe_ctx ) ) ;
2013-08-23 13:46:38 -04:00
if ( ! debugger_sp . get ( ) )
{
error . SetErrorString ( " invalid Debugger pointer " ) ;
return false ;
2014-11-25 16:00:58 -05:00
}
2013-08-23 13:46:38 -04:00
bool ret_val = false ;
std : : string err_msg ;
2014-11-25 16:00:58 -05:00
2013-08-23 13:46:38 -04:00
{
Locker py_lock ( this ,
2014-11-25 16:00:58 -05:00
Locker : : AcquireLock | Locker : : InitSession | ( cmd_retobj . GetInteractive ( ) ? 0 : Locker : : NoSTDIN ) ,
2013-08-23 13:46:38 -04:00
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 ,
2015-02-06 16:38:51 -05:00
cmd_retobj ,
exe_ctx_ref_sp ) ;
2013-08-23 13:46:38 -04:00
}
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__ " ;
2014-11-25 16:00:58 -05:00
char * result_ptr = nullptr ; // Python is going to point this to valid data if ExecuteOneLineWithReturn returns successfully
2013-08-23 13:46:38 -04:00
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 ,
2014-02-18 11:23:10 -05:00
Locker : : AcquireLock | Locker : : InitSession | Locker : : NoSTDIN ,
Locker : : FreeLock | Locker : : TearDownSession ) ) ;
2013-08-23 13:46:38 -04:00
return py_lock ;
}
void
2013-11-06 11:48:53 -05:00
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 ,
2015-02-06 16:38:51 -05:00
SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider ,
2013-11-06 11:48:53 -05:00
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 ,
2015-02-06 16:38:51 -05:00
SWIGPythonScriptKeyword_Value swig_run_script_keyword_value ,
SWIGPython_GetDynamicSetting swig_plugin_get ,
SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script ,
SWIGPythonCallThreadPlan swig_call_thread_plan )
2013-11-06 11:48:53 -05:00
{
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 ;
2015-02-06 16:38:51 -05:00
g_swig_getvalue_provider = swig_getvalue_provider ;
2013-11-06 11:48:53 -05:00
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 ;
2015-02-06 16:38:51 -05:00
g_swig_run_script_keyword_value = swig_run_script_keyword_value ;
2013-11-06 11:48:53 -05:00
g_swig_plugin_get = swig_plugin_get ;
2015-02-06 16:38:51 -05:00
g_swig_thread_plan_script = swig_thread_plan_script ;
g_swig_call_thread_plan = swig_call_thread_plan ;
2013-08-23 13:46:38 -04:00
}
void
ScriptInterpreterPython : : InitializePrivate ( )
{
2014-02-18 11:23:10 -05:00
static int g_initialized = false ;
if ( g_initialized )
return ;
g_initialized = true ;
2013-08-23 13:46:38 -04:00
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
2014-02-25 16:42:16 -05:00
if ( g_swig_init_callback )
g_swig_init_callback ( ) ;
2013-08-23 13:46:38 -04:00
// 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 ] ;
2014-11-25 16:00:58 -05:00
if ( HostInfo : : GetLLDBPath ( ePathTypePythonDir , file_spec ) )
2013-08-23 13:46:38 -04:00
{
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 ) ;
}
2014-11-25 16:00:58 -05:00
if ( HostInfo : : GetLLDBPath ( ePathTypeLLDBShlibDir , file_spec ) )
2013-08-23 13:46:38 -04:00
{
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 ) ;
}
}
}
2014-11-25 16:00:58 -05:00
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 " ) ;
2013-08-23 13:46:38 -04:00
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