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 9be691f3bSpatrick #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 10be691f3bSpatrick #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 11be691f3bSpatrick 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, 82*f6aab3d8Srobert const 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, 102*f6aab3d8Srobert const 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 112be691f3bSpatrick CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, 113*f6aab3d8Srobert const StructuredDataImpl &args_data, 114*f6aab3d8Srobert Status &error) override; 115be691f3bSpatrick 116be691f3bSpatrick bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp, 117be691f3bSpatrick ExecutionContext &exc_ctx, 118be691f3bSpatrick lldb::StreamSP stream_sp) override; 119be691f3bSpatrick 120be691f3bSpatrick StructuredData::GenericSP 121061da546Spatrick CreateFrameRecognizer(const char *class_name) override; 122061da546Spatrick 123061da546Spatrick lldb::ValueObjectListSP 124061da546Spatrick GetRecognizedArguments(const StructuredData::ObjectSP &implementor, 125061da546Spatrick lldb::StackFrameSP frame_sp) override; 126061da546Spatrick 127061da546Spatrick StructuredData::GenericSP 128061da546Spatrick OSPlugin_CreatePluginObject(const char *class_name, 129061da546Spatrick lldb::ProcessSP process_sp) override; 130061da546Spatrick 131061da546Spatrick StructuredData::DictionarySP 132061da546Spatrick OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 133061da546Spatrick 134061da546Spatrick StructuredData::ArraySP 135061da546Spatrick OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 136061da546Spatrick 137061da546Spatrick StructuredData::StringSP 138061da546Spatrick OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, 139061da546Spatrick lldb::tid_t thread_id) override; 140061da546Spatrick 141061da546Spatrick StructuredData::DictionarySP 142061da546Spatrick OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, 143061da546Spatrick lldb::tid_t tid, lldb::addr_t context) override; 144061da546Spatrick 145061da546Spatrick StructuredData::ObjectSP 146061da546Spatrick LoadPluginModule(const FileSpec &file_spec, 147061da546Spatrick lldb_private::Status &error) override; 148061da546Spatrick 149061da546Spatrick StructuredData::DictionarySP 150061da546Spatrick GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, 151061da546Spatrick const char *setting_name, 152061da546Spatrick lldb_private::Status &error) override; 153061da546Spatrick 154061da546Spatrick size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, 155061da546Spatrick uint32_t max) override; 156061da546Spatrick 157061da546Spatrick lldb::ValueObjectSP 158061da546Spatrick GetChildAtIndex(const StructuredData::ObjectSP &implementor, 159061da546Spatrick uint32_t idx) override; 160061da546Spatrick 161061da546Spatrick int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, 162061da546Spatrick const char *child_name) override; 163061da546Spatrick 164061da546Spatrick bool UpdateSynthProviderInstance( 165061da546Spatrick const StructuredData::ObjectSP &implementor) override; 166061da546Spatrick 167061da546Spatrick bool MightHaveChildrenSynthProviderInstance( 168061da546Spatrick const StructuredData::ObjectSP &implementor) override; 169061da546Spatrick 170061da546Spatrick lldb::ValueObjectSP 171061da546Spatrick GetSyntheticValue(const StructuredData::ObjectSP &implementor) override; 172061da546Spatrick 173061da546Spatrick ConstString 174061da546Spatrick GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override; 175061da546Spatrick 176061da546Spatrick bool 177061da546Spatrick RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, 178061da546Spatrick ScriptedCommandSynchronicity synchronicity, 179061da546Spatrick lldb_private::CommandReturnObject &cmd_retobj, 180061da546Spatrick Status &error, 181061da546Spatrick const lldb_private::ExecutionContext &exe_ctx) override; 182061da546Spatrick 183061da546Spatrick bool RunScriptBasedCommand( 184061da546Spatrick StructuredData::GenericSP impl_obj_sp, llvm::StringRef args, 185061da546Spatrick ScriptedCommandSynchronicity synchronicity, 186061da546Spatrick lldb_private::CommandReturnObject &cmd_retobj, Status &error, 187061da546Spatrick const lldb_private::ExecutionContext &exe_ctx) override; 188061da546Spatrick 189061da546Spatrick Status GenerateFunction(const char *signature, 190061da546Spatrick const StringList &input) override; 191061da546Spatrick 192061da546Spatrick Status GenerateBreakpointCommandCallbackData( 193061da546Spatrick StringList &input, 194061da546Spatrick std::string &output, 195061da546Spatrick bool has_extra_args) override; 196061da546Spatrick 197061da546Spatrick bool GenerateWatchpointCommandCallbackData(StringList &input, 198061da546Spatrick std::string &output) override; 199061da546Spatrick 200061da546Spatrick bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, 201061da546Spatrick StructuredData::ObjectSP &callee_wrapper_sp, 202061da546Spatrick const TypeSummaryOptions &options, 203061da546Spatrick std::string &retval) override; 204061da546Spatrick 205*f6aab3d8Srobert bool FormatterCallbackFunction(const char *function_name, 206*f6aab3d8Srobert lldb::TypeImplSP type_impl_sp) override; 207*f6aab3d8Srobert 208061da546Spatrick bool GetDocumentationForItem(const char *item, std::string &dest) override; 209061da546Spatrick 210061da546Spatrick bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 211061da546Spatrick std::string &dest) override; 212061da546Spatrick 213061da546Spatrick uint32_t 214061da546Spatrick GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override; 215061da546Spatrick 216061da546Spatrick bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 217061da546Spatrick std::string &dest) override; 218061da546Spatrick CheckObjectExists(const char * name)219061da546Spatrick bool CheckObjectExists(const char *name) override { 220061da546Spatrick if (!name || !name[0]) 221061da546Spatrick return false; 222061da546Spatrick std::string temp; 223061da546Spatrick return GetDocumentationForItem(name, temp); 224061da546Spatrick } 225061da546Spatrick 226061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, Process *process, 227061da546Spatrick std::string &output, Status &error) override; 228061da546Spatrick 229061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, Thread *thread, 230061da546Spatrick std::string &output, Status &error) override; 231061da546Spatrick 232061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, Target *target, 233061da546Spatrick std::string &output, Status &error) override; 234061da546Spatrick 235061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame, 236061da546Spatrick std::string &output, Status &error) override; 237061da546Spatrick 238061da546Spatrick bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value, 239061da546Spatrick std::string &output, Status &error) override; 240061da546Spatrick 241be691f3bSpatrick bool LoadScriptingModule(const char *filename, 242be691f3bSpatrick const LoadScriptOptions &options, 243061da546Spatrick lldb_private::Status &error, 244be691f3bSpatrick StructuredData::ObjectSP *module_sp = nullptr, 245be691f3bSpatrick FileSpec extra_search_dir = {}) override; 246061da546Spatrick 247061da546Spatrick bool IsReservedWord(const char *word) override; 248061da546Spatrick 249061da546Spatrick std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override; 250061da546Spatrick 251061da546Spatrick void CollectDataForBreakpointCommandCallback( 252be691f3bSpatrick std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, 253061da546Spatrick CommandReturnObject &result) override; 254061da546Spatrick 255061da546Spatrick void 256061da546Spatrick CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, 257061da546Spatrick CommandReturnObject &result) override; 258061da546Spatrick 259061da546Spatrick /// Set the callback body text into the callback for the breakpoint. 260be691f3bSpatrick Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 261061da546Spatrick const char *callback_body) override; 262061da546Spatrick 263061da546Spatrick Status SetBreakpointCommandCallbackFunction( 264be691f3bSpatrick BreakpointOptions &bp_options, const char *function_name, 265061da546Spatrick StructuredData::ObjectSP extra_args_sp) override; 266061da546Spatrick 267061da546Spatrick /// This one is for deserialization: 268061da546Spatrick Status SetBreakpointCommandCallback( 269be691f3bSpatrick BreakpointOptions &bp_options, 270061da546Spatrick std::unique_ptr<BreakpointOptions::CommandData> &data_up) override; 271061da546Spatrick 272be691f3bSpatrick Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 273061da546Spatrick const char *command_body_text, 274061da546Spatrick StructuredData::ObjectSP extra_args_sp, 275061da546Spatrick bool uses_extra_args); 276061da546Spatrick 277061da546Spatrick /// Set a one-liner as the callback for the watchpoint. 278061da546Spatrick void SetWatchpointCommandCallback(WatchpointOptions *wp_options, 279061da546Spatrick const char *oneliner) override; 280061da546Spatrick GetDictionaryName()281061da546Spatrick const char *GetDictionaryName() { return m_dictionary_name.c_str(); } 282061da546Spatrick GetThreadState()283061da546Spatrick PyThreadState *GetThreadState() { return m_command_thread_state; } 284061da546Spatrick SetThreadState(PyThreadState * s)285061da546Spatrick void SetThreadState(PyThreadState *s) { 286061da546Spatrick if (s) 287061da546Spatrick m_command_thread_state = s; 288061da546Spatrick } 289061da546Spatrick 290061da546Spatrick // IOHandlerDelegate 291061da546Spatrick void IOHandlerActivated(IOHandler &io_handler, bool interactive) override; 292061da546Spatrick 293061da546Spatrick void IOHandlerInputComplete(IOHandler &io_handler, 294061da546Spatrick std::string &data) override; 295061da546Spatrick 296061da546Spatrick static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger); 297061da546Spatrick 298061da546Spatrick // PluginInterface protocol GetPluginName()299*f6aab3d8Srobert llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 300061da546Spatrick 301061da546Spatrick class Locker : public ScriptInterpreterLocker { 302061da546Spatrick public: 303061da546Spatrick enum OnEntry { 304061da546Spatrick AcquireLock = 0x0001, 305061da546Spatrick InitSession = 0x0002, 306061da546Spatrick InitGlobals = 0x0004, 307061da546Spatrick NoSTDIN = 0x0008 308061da546Spatrick }; 309061da546Spatrick 310061da546Spatrick enum OnLeave { 311061da546Spatrick FreeLock = 0x0001, 312061da546Spatrick FreeAcquiredLock = 0x0002, // do not free the lock if we already held it 313061da546Spatrick // when calling constructor 314061da546Spatrick TearDownSession = 0x0004 315061da546Spatrick }; 316061da546Spatrick 317061da546Spatrick Locker(ScriptInterpreterPythonImpl *py_interpreter, 318061da546Spatrick uint16_t on_entry = AcquireLock | InitSession, 319061da546Spatrick uint16_t on_leave = FreeLock | TearDownSession, 320061da546Spatrick lldb::FileSP in = nullptr, lldb::FileSP out = nullptr, 321061da546Spatrick lldb::FileSP err = nullptr); 322061da546Spatrick 323061da546Spatrick ~Locker() override; 324061da546Spatrick 325061da546Spatrick private: 326061da546Spatrick bool DoAcquireLock(); 327061da546Spatrick 328061da546Spatrick bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in, 329061da546Spatrick lldb::FileSP out, lldb::FileSP err); 330061da546Spatrick 331061da546Spatrick bool DoFreeLock(); 332061da546Spatrick 333061da546Spatrick bool DoTearDownSession(); 334061da546Spatrick 335061da546Spatrick bool m_teardown_session; 336061da546Spatrick ScriptInterpreterPythonImpl *m_python_interpreter; 337061da546Spatrick PyGILState_STATE m_GILState; 338061da546Spatrick }; 339061da546Spatrick 340061da546Spatrick static bool BreakpointCallbackFunction(void *baton, 341061da546Spatrick StoppointCallbackContext *context, 342061da546Spatrick lldb::user_id_t break_id, 343061da546Spatrick lldb::user_id_t break_loc_id); 344061da546Spatrick static bool WatchpointCallbackFunction(void *baton, 345061da546Spatrick StoppointCallbackContext *context, 346061da546Spatrick lldb::user_id_t watch_id); 347*f6aab3d8Srobert static void Initialize(); 348061da546Spatrick 349061da546Spatrick class SynchronicityHandler { 350061da546Spatrick private: 351061da546Spatrick lldb::DebuggerSP m_debugger_sp; 352061da546Spatrick ScriptedCommandSynchronicity m_synch_wanted; 353061da546Spatrick bool m_old_asynch; 354061da546Spatrick 355061da546Spatrick public: 356061da546Spatrick SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity); 357061da546Spatrick 358061da546Spatrick ~SynchronicityHandler(); 359061da546Spatrick }; 360061da546Spatrick 361061da546Spatrick enum class AddLocation { Beginning, End }; 362061da546Spatrick 363061da546Spatrick static void AddToSysPath(AddLocation location, std::string path); 364061da546Spatrick 365061da546Spatrick bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, 366061da546Spatrick lldb::FileSP err); 367061da546Spatrick 368061da546Spatrick void LeaveSession(); 369061da546Spatrick IsExecutingPython()370061da546Spatrick uint32_t IsExecutingPython() const { return m_lock_count > 0; } 371061da546Spatrick IncrementLockCount()372061da546Spatrick uint32_t IncrementLockCount() { return ++m_lock_count; } 373061da546Spatrick DecrementLockCount()374061da546Spatrick uint32_t DecrementLockCount() { 375061da546Spatrick if (m_lock_count > 0) 376061da546Spatrick --m_lock_count; 377061da546Spatrick return m_lock_count; 378061da546Spatrick } 379061da546Spatrick 380061da546Spatrick enum ActiveIOHandler { 381061da546Spatrick eIOHandlerNone, 382061da546Spatrick eIOHandlerBreakpoint, 383061da546Spatrick eIOHandlerWatchpoint 384061da546Spatrick }; 385061da546Spatrick 386061da546Spatrick python::PythonModule &GetMainModule(); 387061da546Spatrick 388061da546Spatrick python::PythonDictionary &GetSessionDictionary(); 389061da546Spatrick 390061da546Spatrick python::PythonDictionary &GetSysModuleDictionary(); 391061da546Spatrick 392061da546Spatrick llvm::Expected<unsigned> GetMaxPositionalArgumentsForCallable( 393061da546Spatrick const llvm::StringRef &callable_name) override; 394061da546Spatrick 395061da546Spatrick bool GetEmbeddedInterpreterModuleObjects(); 396061da546Spatrick 397061da546Spatrick bool SetStdHandle(lldb::FileSP file, const char *py_name, 398061da546Spatrick python::PythonObject &save_file, const char *mode); 399061da546Spatrick 400061da546Spatrick python::PythonObject m_saved_stdin; 401061da546Spatrick python::PythonObject m_saved_stdout; 402061da546Spatrick python::PythonObject m_saved_stderr; 403061da546Spatrick python::PythonModule m_main_module; 404061da546Spatrick python::PythonDictionary m_session_dict; 405061da546Spatrick python::PythonDictionary m_sys_module_dict; 406061da546Spatrick python::PythonObject m_run_one_line_function; 407061da546Spatrick python::PythonObject m_run_one_line_str_global; 408061da546Spatrick std::string m_dictionary_name; 409061da546Spatrick ActiveIOHandler m_active_io_handler; 410061da546Spatrick bool m_session_is_active; 411dda28197Spatrick bool m_pty_secondary_is_open; 412061da546Spatrick bool m_valid_session; 413061da546Spatrick uint32_t m_lock_count; 414061da546Spatrick PyThreadState *m_command_thread_state; 415061da546Spatrick }; 416061da546Spatrick 417061da546Spatrick class IOHandlerPythonInterpreter : public IOHandler { 418061da546Spatrick public: IOHandlerPythonInterpreter(Debugger & debugger,ScriptInterpreterPythonImpl * python)419061da546Spatrick IOHandlerPythonInterpreter(Debugger &debugger, 420061da546Spatrick ScriptInterpreterPythonImpl *python) 421061da546Spatrick : IOHandler(debugger, IOHandler::Type::PythonInterpreter), 422061da546Spatrick m_python(python) {} 423061da546Spatrick 424be691f3bSpatrick ~IOHandlerPythonInterpreter() override = default; 425061da546Spatrick GetControlSequence(char ch)426061da546Spatrick ConstString GetControlSequence(char ch) override { 427061da546Spatrick if (ch == 'd') 428061da546Spatrick return ConstString("quit()\n"); 429061da546Spatrick return ConstString(); 430061da546Spatrick } 431061da546Spatrick Run()432061da546Spatrick void Run() override { 433061da546Spatrick if (m_python) { 434061da546Spatrick int stdin_fd = GetInputFD(); 435061da546Spatrick if (stdin_fd >= 0) { 436061da546Spatrick Terminal terminal(stdin_fd); 437*f6aab3d8Srobert TerminalState terminal_state(terminal); 438061da546Spatrick 439*f6aab3d8Srobert if (terminal.IsATerminal()) { 440*f6aab3d8Srobert // FIXME: error handling? 441*f6aab3d8Srobert llvm::consumeError(terminal.SetCanonical(false)); 442*f6aab3d8Srobert llvm::consumeError(terminal.SetEcho(true)); 443061da546Spatrick } 444061da546Spatrick 445061da546Spatrick ScriptInterpreterPythonImpl::Locker locker( 446061da546Spatrick m_python, 447061da546Spatrick ScriptInterpreterPythonImpl::Locker::AcquireLock | 448061da546Spatrick ScriptInterpreterPythonImpl::Locker::InitSession | 449061da546Spatrick ScriptInterpreterPythonImpl::Locker::InitGlobals, 450061da546Spatrick ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock | 451061da546Spatrick ScriptInterpreterPythonImpl::Locker::TearDownSession); 452061da546Spatrick 453061da546Spatrick // The following call drops into the embedded interpreter loop and 454061da546Spatrick // stays there until the user chooses to exit from the Python 455061da546Spatrick // interpreter. This embedded interpreter will, as any Python code that 456061da546Spatrick // performs I/O, unlock the GIL before a system call that can hang, and 457061da546Spatrick // lock it when the syscall has returned. 458061da546Spatrick 459061da546Spatrick // We need to surround the call to the embedded interpreter with calls 460061da546Spatrick // to PyGILState_Ensure and PyGILState_Release (using the Locker 461061da546Spatrick // above). This is because Python has a global lock which must be held 462061da546Spatrick // whenever we want to touch any Python objects. Otherwise, if the user 463061da546Spatrick // calls Python code, the interpreter state will be off, and things 464061da546Spatrick // could hang (it's happened before). 465061da546Spatrick 466061da546Spatrick StreamString run_string; 467061da546Spatrick run_string.Printf("run_python_interpreter (%s)", 468061da546Spatrick m_python->GetDictionaryName()); 469061da546Spatrick PyRun_SimpleString(run_string.GetData()); 470061da546Spatrick } 471061da546Spatrick } 472061da546Spatrick SetIsDone(true); 473061da546Spatrick } 474061da546Spatrick Cancel()475061da546Spatrick void Cancel() override {} 476061da546Spatrick Interrupt()477061da546Spatrick bool Interrupt() override { return m_python->Interrupt(); } 478061da546Spatrick GotEOF()479061da546Spatrick void GotEOF() override {} 480061da546Spatrick 481061da546Spatrick protected: 482061da546Spatrick ScriptInterpreterPythonImpl *m_python; 483061da546Spatrick }; 484061da546Spatrick 485061da546Spatrick } // namespace lldb_private 486061da546Spatrick 487be691f3bSpatrick #endif // LLDB_ENABLE_PYTHON 488be691f3bSpatrick #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 489