1*061da546Spatrick //===-- ScriptInterpreterPythonImpl.h ---------------------------*- C++ -*-===// 2*061da546Spatrick // 3*061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*061da546Spatrick // 7*061da546Spatrick //===----------------------------------------------------------------------===// 8*061da546Spatrick 9*061da546Spatrick #include "lldb/Host/Config.h" 10*061da546Spatrick 11*061da546Spatrick #if LLDB_ENABLE_PYTHON 12*061da546Spatrick 13*061da546Spatrick #include "lldb-python.h" 14*061da546Spatrick 15*061da546Spatrick #include "PythonDataObjects.h" 16*061da546Spatrick #include "ScriptInterpreterPython.h" 17*061da546Spatrick 18*061da546Spatrick #include "lldb/Host/Terminal.h" 19*061da546Spatrick #include "lldb/Utility/StreamString.h" 20*061da546Spatrick 21*061da546Spatrick #include "llvm/ADT/STLExtras.h" 22*061da546Spatrick #include "llvm/ADT/StringRef.h" 23*061da546Spatrick 24*061da546Spatrick namespace lldb_private { 25*061da546Spatrick class IOHandlerPythonInterpreter; 26*061da546Spatrick class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { 27*061da546Spatrick public: 28*061da546Spatrick friend class IOHandlerPythonInterpreter; 29*061da546Spatrick 30*061da546Spatrick ScriptInterpreterPythonImpl(Debugger &debugger); 31*061da546Spatrick 32*061da546Spatrick ~ScriptInterpreterPythonImpl() override; 33*061da546Spatrick 34*061da546Spatrick bool Interrupt() override; 35*061da546Spatrick 36*061da546Spatrick bool ExecuteOneLine( 37*061da546Spatrick llvm::StringRef command, CommandReturnObject *result, 38*061da546Spatrick const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 39*061da546Spatrick 40*061da546Spatrick void ExecuteInterpreterLoop() override; 41*061da546Spatrick 42*061da546Spatrick bool ExecuteOneLineWithReturn( 43*061da546Spatrick llvm::StringRef in_string, 44*061da546Spatrick ScriptInterpreter::ScriptReturnType return_type, void *ret_value, 45*061da546Spatrick const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 46*061da546Spatrick 47*061da546Spatrick lldb_private::Status ExecuteMultipleLines( 48*061da546Spatrick const char *in_string, 49*061da546Spatrick const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 50*061da546Spatrick 51*061da546Spatrick Status 52*061da546Spatrick ExportFunctionDefinitionToInterpreter(StringList &function_def) override; 53*061da546Spatrick 54*061da546Spatrick bool GenerateTypeScriptFunction(StringList &input, std::string &output, 55*061da546Spatrick const void *name_token = nullptr) override; 56*061da546Spatrick 57*061da546Spatrick bool GenerateTypeSynthClass(StringList &input, std::string &output, 58*061da546Spatrick const void *name_token = nullptr) override; 59*061da546Spatrick 60*061da546Spatrick bool GenerateTypeSynthClass(const char *oneliner, std::string &output, 61*061da546Spatrick const void *name_token = nullptr) override; 62*061da546Spatrick 63*061da546Spatrick // use this if the function code is just a one-liner script 64*061da546Spatrick bool GenerateTypeScriptFunction(const char *oneliner, std::string &output, 65*061da546Spatrick const void *name_token = nullptr) override; 66*061da546Spatrick 67*061da546Spatrick bool GenerateScriptAliasFunction(StringList &input, 68*061da546Spatrick std::string &output) override; 69*061da546Spatrick 70*061da546Spatrick StructuredData::ObjectSP 71*061da546Spatrick CreateSyntheticScriptedProvider(const char *class_name, 72*061da546Spatrick lldb::ValueObjectSP valobj) override; 73*061da546Spatrick 74*061da546Spatrick StructuredData::GenericSP 75*061da546Spatrick CreateScriptCommandObject(const char *class_name) override; 76*061da546Spatrick 77*061da546Spatrick StructuredData::ObjectSP 78*061da546Spatrick CreateScriptedThreadPlan(const char *class_name, 79*061da546Spatrick StructuredDataImpl *args_data, 80*061da546Spatrick std::string &error_str, 81*061da546Spatrick lldb::ThreadPlanSP thread_plan) override; 82*061da546Spatrick 83*061da546Spatrick bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, 84*061da546Spatrick Event *event, 85*061da546Spatrick bool &script_error) override; 86*061da546Spatrick 87*061da546Spatrick bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, 88*061da546Spatrick Event *event, bool &script_error) override; 89*061da546Spatrick 90*061da546Spatrick bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp, 91*061da546Spatrick bool &script_error) override; 92*061da546Spatrick 93*061da546Spatrick lldb::StateType 94*061da546Spatrick ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, 95*061da546Spatrick bool &script_error) override; 96*061da546Spatrick 97*061da546Spatrick StructuredData::GenericSP 98*061da546Spatrick CreateScriptedBreakpointResolver(const char *class_name, 99*061da546Spatrick StructuredDataImpl *args_data, 100*061da546Spatrick lldb::BreakpointSP &bkpt_sp) override; 101*061da546Spatrick bool ScriptedBreakpointResolverSearchCallback( 102*061da546Spatrick StructuredData::GenericSP implementor_sp, 103*061da546Spatrick SymbolContext *sym_ctx) override; 104*061da546Spatrick 105*061da546Spatrick lldb::SearchDepth ScriptedBreakpointResolverSearchDepth( 106*061da546Spatrick StructuredData::GenericSP implementor_sp) override; 107*061da546Spatrick 108*061da546Spatrick StructuredData::GenericSP 109*061da546Spatrick CreateFrameRecognizer(const char *class_name) override; 110*061da546Spatrick 111*061da546Spatrick lldb::ValueObjectListSP 112*061da546Spatrick GetRecognizedArguments(const StructuredData::ObjectSP &implementor, 113*061da546Spatrick lldb::StackFrameSP frame_sp) override; 114*061da546Spatrick 115*061da546Spatrick StructuredData::GenericSP 116*061da546Spatrick OSPlugin_CreatePluginObject(const char *class_name, 117*061da546Spatrick lldb::ProcessSP process_sp) override; 118*061da546Spatrick 119*061da546Spatrick StructuredData::DictionarySP 120*061da546Spatrick OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 121*061da546Spatrick 122*061da546Spatrick StructuredData::ArraySP 123*061da546Spatrick OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 124*061da546Spatrick 125*061da546Spatrick StructuredData::StringSP 126*061da546Spatrick OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, 127*061da546Spatrick lldb::tid_t thread_id) override; 128*061da546Spatrick 129*061da546Spatrick StructuredData::DictionarySP 130*061da546Spatrick OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, 131*061da546Spatrick lldb::tid_t tid, lldb::addr_t context) override; 132*061da546Spatrick 133*061da546Spatrick StructuredData::ObjectSP 134*061da546Spatrick LoadPluginModule(const FileSpec &file_spec, 135*061da546Spatrick lldb_private::Status &error) override; 136*061da546Spatrick 137*061da546Spatrick StructuredData::DictionarySP 138*061da546Spatrick GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, 139*061da546Spatrick const char *setting_name, 140*061da546Spatrick lldb_private::Status &error) override; 141*061da546Spatrick 142*061da546Spatrick size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, 143*061da546Spatrick uint32_t max) override; 144*061da546Spatrick 145*061da546Spatrick lldb::ValueObjectSP 146*061da546Spatrick GetChildAtIndex(const StructuredData::ObjectSP &implementor, 147*061da546Spatrick uint32_t idx) override; 148*061da546Spatrick 149*061da546Spatrick int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, 150*061da546Spatrick const char *child_name) override; 151*061da546Spatrick 152*061da546Spatrick bool UpdateSynthProviderInstance( 153*061da546Spatrick const StructuredData::ObjectSP &implementor) override; 154*061da546Spatrick 155*061da546Spatrick bool MightHaveChildrenSynthProviderInstance( 156*061da546Spatrick const StructuredData::ObjectSP &implementor) override; 157*061da546Spatrick 158*061da546Spatrick lldb::ValueObjectSP 159*061da546Spatrick GetSyntheticValue(const StructuredData::ObjectSP &implementor) override; 160*061da546Spatrick 161*061da546Spatrick ConstString 162*061da546Spatrick GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override; 163*061da546Spatrick 164*061da546Spatrick bool 165*061da546Spatrick RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, 166*061da546Spatrick ScriptedCommandSynchronicity synchronicity, 167*061da546Spatrick lldb_private::CommandReturnObject &cmd_retobj, 168*061da546Spatrick Status &error, 169*061da546Spatrick const lldb_private::ExecutionContext &exe_ctx) override; 170*061da546Spatrick 171*061da546Spatrick bool RunScriptBasedCommand( 172*061da546Spatrick StructuredData::GenericSP impl_obj_sp, llvm::StringRef args, 173*061da546Spatrick ScriptedCommandSynchronicity synchronicity, 174*061da546Spatrick lldb_private::CommandReturnObject &cmd_retobj, Status &error, 175*061da546Spatrick const lldb_private::ExecutionContext &exe_ctx) override; 176*061da546Spatrick 177*061da546Spatrick Status GenerateFunction(const char *signature, 178*061da546Spatrick const StringList &input) override; 179*061da546Spatrick 180*061da546Spatrick Status GenerateBreakpointCommandCallbackData( 181*061da546Spatrick StringList &input, 182*061da546Spatrick std::string &output, 183*061da546Spatrick bool has_extra_args) override; 184*061da546Spatrick 185*061da546Spatrick bool GenerateWatchpointCommandCallbackData(StringList &input, 186*061da546Spatrick std::string &output) override; 187*061da546Spatrick 188*061da546Spatrick bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, 189*061da546Spatrick StructuredData::ObjectSP &callee_wrapper_sp, 190*061da546Spatrick const TypeSummaryOptions &options, 191*061da546Spatrick std::string &retval) override; 192*061da546Spatrick 193*061da546Spatrick bool GetDocumentationForItem(const char *item, std::string &dest) override; 194*061da546Spatrick 195*061da546Spatrick bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 196*061da546Spatrick std::string &dest) override; 197*061da546Spatrick 198*061da546Spatrick uint32_t 199*061da546Spatrick GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override; 200*061da546Spatrick 201*061da546Spatrick bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 202*061da546Spatrick std::string &dest) override; 203*061da546Spatrick 204*061da546Spatrick bool CheckObjectExists(const char *name) override { 205*061da546Spatrick if (!name || !name[0]) 206*061da546Spatrick return false; 207*061da546Spatrick std::string temp; 208*061da546Spatrick return GetDocumentationForItem(name, temp); 209*061da546Spatrick } 210*061da546Spatrick 211*061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, Process *process, 212*061da546Spatrick std::string &output, Status &error) override; 213*061da546Spatrick 214*061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, Thread *thread, 215*061da546Spatrick std::string &output, Status &error) override; 216*061da546Spatrick 217*061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, Target *target, 218*061da546Spatrick std::string &output, Status &error) override; 219*061da546Spatrick 220*061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame, 221*061da546Spatrick std::string &output, Status &error) override; 222*061da546Spatrick 223*061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value, 224*061da546Spatrick std::string &output, Status &error) override; 225*061da546Spatrick 226*061da546Spatrick bool 227*061da546Spatrick LoadScriptingModule(const char *filename, bool init_session, 228*061da546Spatrick lldb_private::Status &error, 229*061da546Spatrick StructuredData::ObjectSP *module_sp = nullptr) override; 230*061da546Spatrick 231*061da546Spatrick bool IsReservedWord(const char *word) override; 232*061da546Spatrick 233*061da546Spatrick std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override; 234*061da546Spatrick 235*061da546Spatrick void CollectDataForBreakpointCommandCallback( 236*061da546Spatrick std::vector<BreakpointOptions *> &bp_options_vec, 237*061da546Spatrick CommandReturnObject &result) override; 238*061da546Spatrick 239*061da546Spatrick void 240*061da546Spatrick CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, 241*061da546Spatrick CommandReturnObject &result) override; 242*061da546Spatrick 243*061da546Spatrick /// Set the callback body text into the callback for the breakpoint. 244*061da546Spatrick Status SetBreakpointCommandCallback(BreakpointOptions *bp_options, 245*061da546Spatrick const char *callback_body) override; 246*061da546Spatrick 247*061da546Spatrick Status SetBreakpointCommandCallbackFunction( 248*061da546Spatrick BreakpointOptions *bp_options, 249*061da546Spatrick const char *function_name, 250*061da546Spatrick StructuredData::ObjectSP extra_args_sp) override; 251*061da546Spatrick 252*061da546Spatrick /// This one is for deserialization: 253*061da546Spatrick Status SetBreakpointCommandCallback( 254*061da546Spatrick BreakpointOptions *bp_options, 255*061da546Spatrick std::unique_ptr<BreakpointOptions::CommandData> &data_up) override; 256*061da546Spatrick 257*061da546Spatrick Status SetBreakpointCommandCallback(BreakpointOptions *bp_options, 258*061da546Spatrick const char *command_body_text, 259*061da546Spatrick StructuredData::ObjectSP extra_args_sp, 260*061da546Spatrick bool uses_extra_args); 261*061da546Spatrick 262*061da546Spatrick /// Set a one-liner as the callback for the watchpoint. 263*061da546Spatrick void SetWatchpointCommandCallback(WatchpointOptions *wp_options, 264*061da546Spatrick const char *oneliner) override; 265*061da546Spatrick 266*061da546Spatrick const char *GetDictionaryName() { return m_dictionary_name.c_str(); } 267*061da546Spatrick 268*061da546Spatrick PyThreadState *GetThreadState() { return m_command_thread_state; } 269*061da546Spatrick 270*061da546Spatrick void SetThreadState(PyThreadState *s) { 271*061da546Spatrick if (s) 272*061da546Spatrick m_command_thread_state = s; 273*061da546Spatrick } 274*061da546Spatrick 275*061da546Spatrick // IOHandlerDelegate 276*061da546Spatrick void IOHandlerActivated(IOHandler &io_handler, bool interactive) override; 277*061da546Spatrick 278*061da546Spatrick void IOHandlerInputComplete(IOHandler &io_handler, 279*061da546Spatrick std::string &data) override; 280*061da546Spatrick 281*061da546Spatrick static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger); 282*061da546Spatrick 283*061da546Spatrick // PluginInterface protocol 284*061da546Spatrick lldb_private::ConstString GetPluginName() override; 285*061da546Spatrick 286*061da546Spatrick uint32_t GetPluginVersion() override; 287*061da546Spatrick 288*061da546Spatrick class Locker : public ScriptInterpreterLocker { 289*061da546Spatrick public: 290*061da546Spatrick enum OnEntry { 291*061da546Spatrick AcquireLock = 0x0001, 292*061da546Spatrick InitSession = 0x0002, 293*061da546Spatrick InitGlobals = 0x0004, 294*061da546Spatrick NoSTDIN = 0x0008 295*061da546Spatrick }; 296*061da546Spatrick 297*061da546Spatrick enum OnLeave { 298*061da546Spatrick FreeLock = 0x0001, 299*061da546Spatrick FreeAcquiredLock = 0x0002, // do not free the lock if we already held it 300*061da546Spatrick // when calling constructor 301*061da546Spatrick TearDownSession = 0x0004 302*061da546Spatrick }; 303*061da546Spatrick 304*061da546Spatrick Locker(ScriptInterpreterPythonImpl *py_interpreter, 305*061da546Spatrick uint16_t on_entry = AcquireLock | InitSession, 306*061da546Spatrick uint16_t on_leave = FreeLock | TearDownSession, 307*061da546Spatrick lldb::FileSP in = nullptr, lldb::FileSP out = nullptr, 308*061da546Spatrick lldb::FileSP err = nullptr); 309*061da546Spatrick 310*061da546Spatrick ~Locker() override; 311*061da546Spatrick 312*061da546Spatrick private: 313*061da546Spatrick bool DoAcquireLock(); 314*061da546Spatrick 315*061da546Spatrick bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in, 316*061da546Spatrick lldb::FileSP out, lldb::FileSP err); 317*061da546Spatrick 318*061da546Spatrick bool DoFreeLock(); 319*061da546Spatrick 320*061da546Spatrick bool DoTearDownSession(); 321*061da546Spatrick 322*061da546Spatrick bool m_teardown_session; 323*061da546Spatrick ScriptInterpreterPythonImpl *m_python_interpreter; 324*061da546Spatrick PyGILState_STATE m_GILState; 325*061da546Spatrick }; 326*061da546Spatrick 327*061da546Spatrick static bool BreakpointCallbackFunction(void *baton, 328*061da546Spatrick StoppointCallbackContext *context, 329*061da546Spatrick lldb::user_id_t break_id, 330*061da546Spatrick lldb::user_id_t break_loc_id); 331*061da546Spatrick static bool WatchpointCallbackFunction(void *baton, 332*061da546Spatrick StoppointCallbackContext *context, 333*061da546Spatrick lldb::user_id_t watch_id); 334*061da546Spatrick static void InitializePrivate(); 335*061da546Spatrick 336*061da546Spatrick class SynchronicityHandler { 337*061da546Spatrick private: 338*061da546Spatrick lldb::DebuggerSP m_debugger_sp; 339*061da546Spatrick ScriptedCommandSynchronicity m_synch_wanted; 340*061da546Spatrick bool m_old_asynch; 341*061da546Spatrick 342*061da546Spatrick public: 343*061da546Spatrick SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity); 344*061da546Spatrick 345*061da546Spatrick ~SynchronicityHandler(); 346*061da546Spatrick }; 347*061da546Spatrick 348*061da546Spatrick enum class AddLocation { Beginning, End }; 349*061da546Spatrick 350*061da546Spatrick static void AddToSysPath(AddLocation location, std::string path); 351*061da546Spatrick 352*061da546Spatrick bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, 353*061da546Spatrick lldb::FileSP err); 354*061da546Spatrick 355*061da546Spatrick void LeaveSession(); 356*061da546Spatrick 357*061da546Spatrick uint32_t IsExecutingPython() const { return m_lock_count > 0; } 358*061da546Spatrick 359*061da546Spatrick uint32_t IncrementLockCount() { return ++m_lock_count; } 360*061da546Spatrick 361*061da546Spatrick uint32_t DecrementLockCount() { 362*061da546Spatrick if (m_lock_count > 0) 363*061da546Spatrick --m_lock_count; 364*061da546Spatrick return m_lock_count; 365*061da546Spatrick } 366*061da546Spatrick 367*061da546Spatrick enum ActiveIOHandler { 368*061da546Spatrick eIOHandlerNone, 369*061da546Spatrick eIOHandlerBreakpoint, 370*061da546Spatrick eIOHandlerWatchpoint 371*061da546Spatrick }; 372*061da546Spatrick 373*061da546Spatrick python::PythonModule &GetMainModule(); 374*061da546Spatrick 375*061da546Spatrick python::PythonDictionary &GetSessionDictionary(); 376*061da546Spatrick 377*061da546Spatrick python::PythonDictionary &GetSysModuleDictionary(); 378*061da546Spatrick 379*061da546Spatrick llvm::Expected<unsigned> GetMaxPositionalArgumentsForCallable( 380*061da546Spatrick const llvm::StringRef &callable_name) override; 381*061da546Spatrick 382*061da546Spatrick bool GetEmbeddedInterpreterModuleObjects(); 383*061da546Spatrick 384*061da546Spatrick bool SetStdHandle(lldb::FileSP file, const char *py_name, 385*061da546Spatrick python::PythonObject &save_file, const char *mode); 386*061da546Spatrick 387*061da546Spatrick python::PythonObject m_saved_stdin; 388*061da546Spatrick python::PythonObject m_saved_stdout; 389*061da546Spatrick python::PythonObject m_saved_stderr; 390*061da546Spatrick python::PythonModule m_main_module; 391*061da546Spatrick python::PythonDictionary m_session_dict; 392*061da546Spatrick python::PythonDictionary m_sys_module_dict; 393*061da546Spatrick python::PythonObject m_run_one_line_function; 394*061da546Spatrick python::PythonObject m_run_one_line_str_global; 395*061da546Spatrick std::string m_dictionary_name; 396*061da546Spatrick ActiveIOHandler m_active_io_handler; 397*061da546Spatrick bool m_session_is_active; 398*061da546Spatrick bool m_pty_slave_is_open; 399*061da546Spatrick bool m_valid_session; 400*061da546Spatrick uint32_t m_lock_count; 401*061da546Spatrick PyThreadState *m_command_thread_state; 402*061da546Spatrick }; 403*061da546Spatrick 404*061da546Spatrick class IOHandlerPythonInterpreter : public IOHandler { 405*061da546Spatrick public: 406*061da546Spatrick IOHandlerPythonInterpreter(Debugger &debugger, 407*061da546Spatrick ScriptInterpreterPythonImpl *python) 408*061da546Spatrick : IOHandler(debugger, IOHandler::Type::PythonInterpreter), 409*061da546Spatrick m_python(python) {} 410*061da546Spatrick 411*061da546Spatrick ~IOHandlerPythonInterpreter() override {} 412*061da546Spatrick 413*061da546Spatrick ConstString GetControlSequence(char ch) override { 414*061da546Spatrick if (ch == 'd') 415*061da546Spatrick return ConstString("quit()\n"); 416*061da546Spatrick return ConstString(); 417*061da546Spatrick } 418*061da546Spatrick 419*061da546Spatrick void Run() override { 420*061da546Spatrick if (m_python) { 421*061da546Spatrick int stdin_fd = GetInputFD(); 422*061da546Spatrick if (stdin_fd >= 0) { 423*061da546Spatrick Terminal terminal(stdin_fd); 424*061da546Spatrick TerminalState terminal_state; 425*061da546Spatrick const bool is_a_tty = terminal.IsATerminal(); 426*061da546Spatrick 427*061da546Spatrick if (is_a_tty) { 428*061da546Spatrick terminal_state.Save(stdin_fd, false); 429*061da546Spatrick terminal.SetCanonical(false); 430*061da546Spatrick terminal.SetEcho(true); 431*061da546Spatrick } 432*061da546Spatrick 433*061da546Spatrick ScriptInterpreterPythonImpl::Locker locker( 434*061da546Spatrick m_python, 435*061da546Spatrick ScriptInterpreterPythonImpl::Locker::AcquireLock | 436*061da546Spatrick ScriptInterpreterPythonImpl::Locker::InitSession | 437*061da546Spatrick ScriptInterpreterPythonImpl::Locker::InitGlobals, 438*061da546Spatrick ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock | 439*061da546Spatrick ScriptInterpreterPythonImpl::Locker::TearDownSession); 440*061da546Spatrick 441*061da546Spatrick // The following call drops into the embedded interpreter loop and 442*061da546Spatrick // stays there until the user chooses to exit from the Python 443*061da546Spatrick // interpreter. This embedded interpreter will, as any Python code that 444*061da546Spatrick // performs I/O, unlock the GIL before a system call that can hang, and 445*061da546Spatrick // lock it when the syscall has returned. 446*061da546Spatrick 447*061da546Spatrick // We need to surround the call to the embedded interpreter with calls 448*061da546Spatrick // to PyGILState_Ensure and PyGILState_Release (using the Locker 449*061da546Spatrick // above). This is because Python has a global lock which must be held 450*061da546Spatrick // whenever we want to touch any Python objects. Otherwise, if the user 451*061da546Spatrick // calls Python code, the interpreter state will be off, and things 452*061da546Spatrick // could hang (it's happened before). 453*061da546Spatrick 454*061da546Spatrick StreamString run_string; 455*061da546Spatrick run_string.Printf("run_python_interpreter (%s)", 456*061da546Spatrick m_python->GetDictionaryName()); 457*061da546Spatrick PyRun_SimpleString(run_string.GetData()); 458*061da546Spatrick 459*061da546Spatrick if (is_a_tty) 460*061da546Spatrick terminal_state.Restore(); 461*061da546Spatrick } 462*061da546Spatrick } 463*061da546Spatrick SetIsDone(true); 464*061da546Spatrick } 465*061da546Spatrick 466*061da546Spatrick void Cancel() override {} 467*061da546Spatrick 468*061da546Spatrick bool Interrupt() override { return m_python->Interrupt(); } 469*061da546Spatrick 470*061da546Spatrick void GotEOF() override {} 471*061da546Spatrick 472*061da546Spatrick protected: 473*061da546Spatrick ScriptInterpreterPythonImpl *m_python; 474*061da546Spatrick }; 475*061da546Spatrick 476*061da546Spatrick } // namespace lldb_private 477*061da546Spatrick 478*061da546Spatrick #endif 479