1061da546Spatrick //===-- ScriptInterpreterPythonImpl.h ---------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9*be691f3bSpatrick #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 10*be691f3bSpatrick #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 11*be691f3bSpatrick 12061da546Spatrick #include "lldb/Host/Config.h" 13061da546Spatrick 14061da546Spatrick #if LLDB_ENABLE_PYTHON 15061da546Spatrick 16061da546Spatrick #include "lldb-python.h" 17061da546Spatrick 18061da546Spatrick #include "PythonDataObjects.h" 19061da546Spatrick #include "ScriptInterpreterPython.h" 20061da546Spatrick 21061da546Spatrick #include "lldb/Host/Terminal.h" 22061da546Spatrick #include "lldb/Utility/StreamString.h" 23061da546Spatrick 24061da546Spatrick #include "llvm/ADT/STLExtras.h" 25061da546Spatrick #include "llvm/ADT/StringRef.h" 26061da546Spatrick 27061da546Spatrick namespace lldb_private { 28061da546Spatrick class IOHandlerPythonInterpreter; 29061da546Spatrick class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { 30061da546Spatrick public: 31061da546Spatrick friend class IOHandlerPythonInterpreter; 32061da546Spatrick 33061da546Spatrick ScriptInterpreterPythonImpl(Debugger &debugger); 34061da546Spatrick 35061da546Spatrick ~ScriptInterpreterPythonImpl() override; 36061da546Spatrick 37061da546Spatrick bool Interrupt() override; 38061da546Spatrick 39061da546Spatrick bool ExecuteOneLine( 40061da546Spatrick llvm::StringRef command, CommandReturnObject *result, 41061da546Spatrick const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 42061da546Spatrick 43061da546Spatrick void ExecuteInterpreterLoop() override; 44061da546Spatrick 45061da546Spatrick bool ExecuteOneLineWithReturn( 46061da546Spatrick llvm::StringRef in_string, 47061da546Spatrick ScriptInterpreter::ScriptReturnType return_type, void *ret_value, 48061da546Spatrick const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 49061da546Spatrick 50061da546Spatrick lldb_private::Status ExecuteMultipleLines( 51061da546Spatrick const char *in_string, 52061da546Spatrick const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 53061da546Spatrick 54061da546Spatrick Status 55061da546Spatrick ExportFunctionDefinitionToInterpreter(StringList &function_def) override; 56061da546Spatrick 57061da546Spatrick bool GenerateTypeScriptFunction(StringList &input, std::string &output, 58061da546Spatrick const void *name_token = nullptr) override; 59061da546Spatrick 60061da546Spatrick bool GenerateTypeSynthClass(StringList &input, std::string &output, 61061da546Spatrick const void *name_token = nullptr) override; 62061da546Spatrick 63061da546Spatrick bool GenerateTypeSynthClass(const char *oneliner, std::string &output, 64061da546Spatrick const void *name_token = nullptr) override; 65061da546Spatrick 66061da546Spatrick // use this if the function code is just a one-liner script 67061da546Spatrick bool GenerateTypeScriptFunction(const char *oneliner, std::string &output, 68061da546Spatrick const void *name_token = nullptr) override; 69061da546Spatrick 70061da546Spatrick bool GenerateScriptAliasFunction(StringList &input, 71061da546Spatrick std::string &output) override; 72061da546Spatrick 73061da546Spatrick StructuredData::ObjectSP 74061da546Spatrick CreateSyntheticScriptedProvider(const char *class_name, 75061da546Spatrick lldb::ValueObjectSP valobj) override; 76061da546Spatrick 77061da546Spatrick StructuredData::GenericSP 78061da546Spatrick CreateScriptCommandObject(const char *class_name) override; 79061da546Spatrick 80061da546Spatrick StructuredData::ObjectSP 81061da546Spatrick CreateScriptedThreadPlan(const char *class_name, 82061da546Spatrick StructuredDataImpl *args_data, 83061da546Spatrick std::string &error_str, 84061da546Spatrick lldb::ThreadPlanSP thread_plan) override; 85061da546Spatrick 86061da546Spatrick bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, 87061da546Spatrick Event *event, 88061da546Spatrick bool &script_error) override; 89061da546Spatrick 90061da546Spatrick bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, 91061da546Spatrick Event *event, bool &script_error) override; 92061da546Spatrick 93061da546Spatrick bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp, 94061da546Spatrick bool &script_error) override; 95061da546Spatrick 96061da546Spatrick lldb::StateType 97061da546Spatrick ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, 98061da546Spatrick bool &script_error) override; 99061da546Spatrick 100061da546Spatrick StructuredData::GenericSP 101061da546Spatrick CreateScriptedBreakpointResolver(const char *class_name, 102061da546Spatrick StructuredDataImpl *args_data, 103061da546Spatrick lldb::BreakpointSP &bkpt_sp) override; 104061da546Spatrick bool ScriptedBreakpointResolverSearchCallback( 105061da546Spatrick StructuredData::GenericSP implementor_sp, 106061da546Spatrick SymbolContext *sym_ctx) override; 107061da546Spatrick 108061da546Spatrick lldb::SearchDepth ScriptedBreakpointResolverSearchDepth( 109061da546Spatrick StructuredData::GenericSP implementor_sp) override; 110061da546Spatrick 111061da546Spatrick StructuredData::GenericSP 112*be691f3bSpatrick CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, 113*be691f3bSpatrick StructuredDataImpl *args_data, Status &error) override; 114*be691f3bSpatrick 115*be691f3bSpatrick bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp, 116*be691f3bSpatrick ExecutionContext &exc_ctx, 117*be691f3bSpatrick lldb::StreamSP stream_sp) override; 118*be691f3bSpatrick 119*be691f3bSpatrick StructuredData::GenericSP 120061da546Spatrick CreateFrameRecognizer(const char *class_name) override; 121061da546Spatrick 122061da546Spatrick lldb::ValueObjectListSP 123061da546Spatrick GetRecognizedArguments(const StructuredData::ObjectSP &implementor, 124061da546Spatrick lldb::StackFrameSP frame_sp) override; 125061da546Spatrick 126061da546Spatrick StructuredData::GenericSP 127061da546Spatrick OSPlugin_CreatePluginObject(const char *class_name, 128061da546Spatrick lldb::ProcessSP process_sp) override; 129061da546Spatrick 130061da546Spatrick StructuredData::DictionarySP 131061da546Spatrick OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 132061da546Spatrick 133061da546Spatrick StructuredData::ArraySP 134061da546Spatrick OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 135061da546Spatrick 136061da546Spatrick StructuredData::StringSP 137061da546Spatrick OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, 138061da546Spatrick lldb::tid_t thread_id) override; 139061da546Spatrick 140061da546Spatrick StructuredData::DictionarySP 141061da546Spatrick OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, 142061da546Spatrick lldb::tid_t tid, lldb::addr_t context) override; 143061da546Spatrick 144061da546Spatrick StructuredData::ObjectSP 145061da546Spatrick LoadPluginModule(const FileSpec &file_spec, 146061da546Spatrick lldb_private::Status &error) override; 147061da546Spatrick 148061da546Spatrick StructuredData::DictionarySP 149061da546Spatrick GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, 150061da546Spatrick const char *setting_name, 151061da546Spatrick lldb_private::Status &error) override; 152061da546Spatrick 153061da546Spatrick size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, 154061da546Spatrick uint32_t max) override; 155061da546Spatrick 156061da546Spatrick lldb::ValueObjectSP 157061da546Spatrick GetChildAtIndex(const StructuredData::ObjectSP &implementor, 158061da546Spatrick uint32_t idx) override; 159061da546Spatrick 160061da546Spatrick int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, 161061da546Spatrick const char *child_name) override; 162061da546Spatrick 163061da546Spatrick bool UpdateSynthProviderInstance( 164061da546Spatrick const StructuredData::ObjectSP &implementor) override; 165061da546Spatrick 166061da546Spatrick bool MightHaveChildrenSynthProviderInstance( 167061da546Spatrick const StructuredData::ObjectSP &implementor) override; 168061da546Spatrick 169061da546Spatrick lldb::ValueObjectSP 170061da546Spatrick GetSyntheticValue(const StructuredData::ObjectSP &implementor) override; 171061da546Spatrick 172061da546Spatrick ConstString 173061da546Spatrick GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override; 174061da546Spatrick 175061da546Spatrick bool 176061da546Spatrick RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, 177061da546Spatrick ScriptedCommandSynchronicity synchronicity, 178061da546Spatrick lldb_private::CommandReturnObject &cmd_retobj, 179061da546Spatrick Status &error, 180061da546Spatrick const lldb_private::ExecutionContext &exe_ctx) override; 181061da546Spatrick 182061da546Spatrick bool RunScriptBasedCommand( 183061da546Spatrick StructuredData::GenericSP impl_obj_sp, llvm::StringRef args, 184061da546Spatrick ScriptedCommandSynchronicity synchronicity, 185061da546Spatrick lldb_private::CommandReturnObject &cmd_retobj, Status &error, 186061da546Spatrick const lldb_private::ExecutionContext &exe_ctx) override; 187061da546Spatrick 188061da546Spatrick Status GenerateFunction(const char *signature, 189061da546Spatrick const StringList &input) override; 190061da546Spatrick 191061da546Spatrick Status GenerateBreakpointCommandCallbackData( 192061da546Spatrick StringList &input, 193061da546Spatrick std::string &output, 194061da546Spatrick bool has_extra_args) override; 195061da546Spatrick 196061da546Spatrick bool GenerateWatchpointCommandCallbackData(StringList &input, 197061da546Spatrick std::string &output) override; 198061da546Spatrick 199061da546Spatrick bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, 200061da546Spatrick StructuredData::ObjectSP &callee_wrapper_sp, 201061da546Spatrick const TypeSummaryOptions &options, 202061da546Spatrick std::string &retval) override; 203061da546Spatrick 204061da546Spatrick bool GetDocumentationForItem(const char *item, std::string &dest) override; 205061da546Spatrick 206061da546Spatrick bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 207061da546Spatrick std::string &dest) override; 208061da546Spatrick 209061da546Spatrick uint32_t 210061da546Spatrick GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override; 211061da546Spatrick 212061da546Spatrick bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 213061da546Spatrick std::string &dest) override; 214061da546Spatrick 215061da546Spatrick bool CheckObjectExists(const char *name) override { 216061da546Spatrick if (!name || !name[0]) 217061da546Spatrick return false; 218061da546Spatrick std::string temp; 219061da546Spatrick return GetDocumentationForItem(name, temp); 220061da546Spatrick } 221061da546Spatrick 222061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, Process *process, 223061da546Spatrick std::string &output, Status &error) override; 224061da546Spatrick 225061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, Thread *thread, 226061da546Spatrick std::string &output, Status &error) override; 227061da546Spatrick 228061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, Target *target, 229061da546Spatrick std::string &output, Status &error) override; 230061da546Spatrick 231061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame, 232061da546Spatrick std::string &output, Status &error) override; 233061da546Spatrick 234061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value, 235061da546Spatrick std::string &output, Status &error) override; 236061da546Spatrick 237*be691f3bSpatrick bool LoadScriptingModule(const char *filename, 238*be691f3bSpatrick const LoadScriptOptions &options, 239061da546Spatrick lldb_private::Status &error, 240*be691f3bSpatrick StructuredData::ObjectSP *module_sp = nullptr, 241*be691f3bSpatrick FileSpec extra_search_dir = {}) override; 242061da546Spatrick 243061da546Spatrick bool IsReservedWord(const char *word) override; 244061da546Spatrick 245061da546Spatrick std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override; 246061da546Spatrick 247061da546Spatrick void CollectDataForBreakpointCommandCallback( 248*be691f3bSpatrick std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, 249061da546Spatrick CommandReturnObject &result) override; 250061da546Spatrick 251061da546Spatrick void 252061da546Spatrick CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, 253061da546Spatrick CommandReturnObject &result) override; 254061da546Spatrick 255061da546Spatrick /// Set the callback body text into the callback for the breakpoint. 256*be691f3bSpatrick Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 257061da546Spatrick const char *callback_body) override; 258061da546Spatrick 259061da546Spatrick Status SetBreakpointCommandCallbackFunction( 260*be691f3bSpatrick BreakpointOptions &bp_options, const char *function_name, 261061da546Spatrick StructuredData::ObjectSP extra_args_sp) override; 262061da546Spatrick 263061da546Spatrick /// This one is for deserialization: 264061da546Spatrick Status SetBreakpointCommandCallback( 265*be691f3bSpatrick BreakpointOptions &bp_options, 266061da546Spatrick std::unique_ptr<BreakpointOptions::CommandData> &data_up) override; 267061da546Spatrick 268*be691f3bSpatrick Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 269061da546Spatrick const char *command_body_text, 270061da546Spatrick StructuredData::ObjectSP extra_args_sp, 271061da546Spatrick bool uses_extra_args); 272061da546Spatrick 273061da546Spatrick /// Set a one-liner as the callback for the watchpoint. 274061da546Spatrick void SetWatchpointCommandCallback(WatchpointOptions *wp_options, 275061da546Spatrick const char *oneliner) override; 276061da546Spatrick 277061da546Spatrick const char *GetDictionaryName() { return m_dictionary_name.c_str(); } 278061da546Spatrick 279061da546Spatrick PyThreadState *GetThreadState() { return m_command_thread_state; } 280061da546Spatrick 281061da546Spatrick void SetThreadState(PyThreadState *s) { 282061da546Spatrick if (s) 283061da546Spatrick m_command_thread_state = s; 284061da546Spatrick } 285061da546Spatrick 286061da546Spatrick // IOHandlerDelegate 287061da546Spatrick void IOHandlerActivated(IOHandler &io_handler, bool interactive) override; 288061da546Spatrick 289061da546Spatrick void IOHandlerInputComplete(IOHandler &io_handler, 290061da546Spatrick std::string &data) override; 291061da546Spatrick 292061da546Spatrick static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger); 293061da546Spatrick 294061da546Spatrick // PluginInterface protocol 295061da546Spatrick lldb_private::ConstString GetPluginName() override; 296061da546Spatrick 297061da546Spatrick uint32_t GetPluginVersion() override; 298061da546Spatrick 299061da546Spatrick class Locker : public ScriptInterpreterLocker { 300061da546Spatrick public: 301061da546Spatrick enum OnEntry { 302061da546Spatrick AcquireLock = 0x0001, 303061da546Spatrick InitSession = 0x0002, 304061da546Spatrick InitGlobals = 0x0004, 305061da546Spatrick NoSTDIN = 0x0008 306061da546Spatrick }; 307061da546Spatrick 308061da546Spatrick enum OnLeave { 309061da546Spatrick FreeLock = 0x0001, 310061da546Spatrick FreeAcquiredLock = 0x0002, // do not free the lock if we already held it 311061da546Spatrick // when calling constructor 312061da546Spatrick TearDownSession = 0x0004 313061da546Spatrick }; 314061da546Spatrick 315061da546Spatrick Locker(ScriptInterpreterPythonImpl *py_interpreter, 316061da546Spatrick uint16_t on_entry = AcquireLock | InitSession, 317061da546Spatrick uint16_t on_leave = FreeLock | TearDownSession, 318061da546Spatrick lldb::FileSP in = nullptr, lldb::FileSP out = nullptr, 319061da546Spatrick lldb::FileSP err = nullptr); 320061da546Spatrick 321061da546Spatrick ~Locker() override; 322061da546Spatrick 323061da546Spatrick private: 324061da546Spatrick bool DoAcquireLock(); 325061da546Spatrick 326061da546Spatrick bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in, 327061da546Spatrick lldb::FileSP out, lldb::FileSP err); 328061da546Spatrick 329061da546Spatrick bool DoFreeLock(); 330061da546Spatrick 331061da546Spatrick bool DoTearDownSession(); 332061da546Spatrick 333061da546Spatrick bool m_teardown_session; 334061da546Spatrick ScriptInterpreterPythonImpl *m_python_interpreter; 335061da546Spatrick PyGILState_STATE m_GILState; 336061da546Spatrick }; 337061da546Spatrick 338061da546Spatrick static bool BreakpointCallbackFunction(void *baton, 339061da546Spatrick StoppointCallbackContext *context, 340061da546Spatrick lldb::user_id_t break_id, 341061da546Spatrick lldb::user_id_t break_loc_id); 342061da546Spatrick static bool WatchpointCallbackFunction(void *baton, 343061da546Spatrick StoppointCallbackContext *context, 344061da546Spatrick lldb::user_id_t watch_id); 345061da546Spatrick static void InitializePrivate(); 346061da546Spatrick 347061da546Spatrick class SynchronicityHandler { 348061da546Spatrick private: 349061da546Spatrick lldb::DebuggerSP m_debugger_sp; 350061da546Spatrick ScriptedCommandSynchronicity m_synch_wanted; 351061da546Spatrick bool m_old_asynch; 352061da546Spatrick 353061da546Spatrick public: 354061da546Spatrick SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity); 355061da546Spatrick 356061da546Spatrick ~SynchronicityHandler(); 357061da546Spatrick }; 358061da546Spatrick 359061da546Spatrick enum class AddLocation { Beginning, End }; 360061da546Spatrick 361061da546Spatrick static void AddToSysPath(AddLocation location, std::string path); 362061da546Spatrick 363061da546Spatrick bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, 364061da546Spatrick lldb::FileSP err); 365061da546Spatrick 366061da546Spatrick void LeaveSession(); 367061da546Spatrick 368061da546Spatrick uint32_t IsExecutingPython() const { return m_lock_count > 0; } 369061da546Spatrick 370061da546Spatrick uint32_t IncrementLockCount() { return ++m_lock_count; } 371061da546Spatrick 372061da546Spatrick uint32_t DecrementLockCount() { 373061da546Spatrick if (m_lock_count > 0) 374061da546Spatrick --m_lock_count; 375061da546Spatrick return m_lock_count; 376061da546Spatrick } 377061da546Spatrick 378061da546Spatrick enum ActiveIOHandler { 379061da546Spatrick eIOHandlerNone, 380061da546Spatrick eIOHandlerBreakpoint, 381061da546Spatrick eIOHandlerWatchpoint 382061da546Spatrick }; 383061da546Spatrick 384061da546Spatrick python::PythonModule &GetMainModule(); 385061da546Spatrick 386061da546Spatrick python::PythonDictionary &GetSessionDictionary(); 387061da546Spatrick 388061da546Spatrick python::PythonDictionary &GetSysModuleDictionary(); 389061da546Spatrick 390061da546Spatrick llvm::Expected<unsigned> GetMaxPositionalArgumentsForCallable( 391061da546Spatrick const llvm::StringRef &callable_name) override; 392061da546Spatrick 393061da546Spatrick bool GetEmbeddedInterpreterModuleObjects(); 394061da546Spatrick 395061da546Spatrick bool SetStdHandle(lldb::FileSP file, const char *py_name, 396061da546Spatrick python::PythonObject &save_file, const char *mode); 397061da546Spatrick 398061da546Spatrick python::PythonObject m_saved_stdin; 399061da546Spatrick python::PythonObject m_saved_stdout; 400061da546Spatrick python::PythonObject m_saved_stderr; 401061da546Spatrick python::PythonModule m_main_module; 402061da546Spatrick python::PythonDictionary m_session_dict; 403061da546Spatrick python::PythonDictionary m_sys_module_dict; 404061da546Spatrick python::PythonObject m_run_one_line_function; 405061da546Spatrick python::PythonObject m_run_one_line_str_global; 406061da546Spatrick std::string m_dictionary_name; 407061da546Spatrick ActiveIOHandler m_active_io_handler; 408061da546Spatrick bool m_session_is_active; 409dda28197Spatrick bool m_pty_secondary_is_open; 410061da546Spatrick bool m_valid_session; 411061da546Spatrick uint32_t m_lock_count; 412061da546Spatrick PyThreadState *m_command_thread_state; 413061da546Spatrick }; 414061da546Spatrick 415061da546Spatrick class IOHandlerPythonInterpreter : public IOHandler { 416061da546Spatrick public: 417061da546Spatrick IOHandlerPythonInterpreter(Debugger &debugger, 418061da546Spatrick ScriptInterpreterPythonImpl *python) 419061da546Spatrick : IOHandler(debugger, IOHandler::Type::PythonInterpreter), 420061da546Spatrick m_python(python) {} 421061da546Spatrick 422*be691f3bSpatrick ~IOHandlerPythonInterpreter() override = default; 423061da546Spatrick 424061da546Spatrick ConstString GetControlSequence(char ch) override { 425061da546Spatrick if (ch == 'd') 426061da546Spatrick return ConstString("quit()\n"); 427061da546Spatrick return ConstString(); 428061da546Spatrick } 429061da546Spatrick 430061da546Spatrick void Run() override { 431061da546Spatrick if (m_python) { 432061da546Spatrick int stdin_fd = GetInputFD(); 433061da546Spatrick if (stdin_fd >= 0) { 434061da546Spatrick Terminal terminal(stdin_fd); 435061da546Spatrick TerminalState terminal_state; 436061da546Spatrick const bool is_a_tty = terminal.IsATerminal(); 437061da546Spatrick 438061da546Spatrick if (is_a_tty) { 439061da546Spatrick terminal_state.Save(stdin_fd, false); 440061da546Spatrick terminal.SetCanonical(false); 441061da546Spatrick terminal.SetEcho(true); 442061da546Spatrick } 443061da546Spatrick 444061da546Spatrick ScriptInterpreterPythonImpl::Locker locker( 445061da546Spatrick m_python, 446061da546Spatrick ScriptInterpreterPythonImpl::Locker::AcquireLock | 447061da546Spatrick ScriptInterpreterPythonImpl::Locker::InitSession | 448061da546Spatrick ScriptInterpreterPythonImpl::Locker::InitGlobals, 449061da546Spatrick ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock | 450061da546Spatrick ScriptInterpreterPythonImpl::Locker::TearDownSession); 451061da546Spatrick 452061da546Spatrick // The following call drops into the embedded interpreter loop and 453061da546Spatrick // stays there until the user chooses to exit from the Python 454061da546Spatrick // interpreter. This embedded interpreter will, as any Python code that 455061da546Spatrick // performs I/O, unlock the GIL before a system call that can hang, and 456061da546Spatrick // lock it when the syscall has returned. 457061da546Spatrick 458061da546Spatrick // We need to surround the call to the embedded interpreter with calls 459061da546Spatrick // to PyGILState_Ensure and PyGILState_Release (using the Locker 460061da546Spatrick // above). This is because Python has a global lock which must be held 461061da546Spatrick // whenever we want to touch any Python objects. Otherwise, if the user 462061da546Spatrick // calls Python code, the interpreter state will be off, and things 463061da546Spatrick // could hang (it's happened before). 464061da546Spatrick 465061da546Spatrick StreamString run_string; 466061da546Spatrick run_string.Printf("run_python_interpreter (%s)", 467061da546Spatrick m_python->GetDictionaryName()); 468061da546Spatrick PyRun_SimpleString(run_string.GetData()); 469061da546Spatrick 470061da546Spatrick if (is_a_tty) 471061da546Spatrick terminal_state.Restore(); 472061da546Spatrick } 473061da546Spatrick } 474061da546Spatrick SetIsDone(true); 475061da546Spatrick } 476061da546Spatrick 477061da546Spatrick void Cancel() override {} 478061da546Spatrick 479061da546Spatrick bool Interrupt() override { return m_python->Interrupt(); } 480061da546Spatrick 481061da546Spatrick void GotEOF() override {} 482061da546Spatrick 483061da546Spatrick protected: 484061da546Spatrick ScriptInterpreterPythonImpl *m_python; 485061da546Spatrick }; 486061da546Spatrick 487061da546Spatrick } // namespace lldb_private 488061da546Spatrick 489*be691f3bSpatrick #endif // LLDB_ENABLE_PYTHON 490*be691f3bSpatrick #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 491