15f29bb8aSDimitry Andric //===-- ScriptInterpreterPythonImpl.h ---------------------------*- C++ -*-===// 25f29bb8aSDimitry Andric // 35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65f29bb8aSDimitry Andric // 75f29bb8aSDimitry Andric //===----------------------------------------------------------------------===// 85f29bb8aSDimitry Andric 9344a3780SDimitry Andric #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 10344a3780SDimitry Andric #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 11344a3780SDimitry Andric 12706b4fc4SDimitry Andric #include "lldb/Host/Config.h" 135f29bb8aSDimitry Andric 14706b4fc4SDimitry Andric #if LLDB_ENABLE_PYTHON 155f29bb8aSDimitry Andric 165f29bb8aSDimitry Andric #include "lldb-python.h" 175f29bb8aSDimitry Andric 185f29bb8aSDimitry Andric #include "PythonDataObjects.h" 195f29bb8aSDimitry Andric #include "ScriptInterpreterPython.h" 205f29bb8aSDimitry Andric 215f29bb8aSDimitry Andric #include "lldb/Host/Terminal.h" 225f29bb8aSDimitry Andric #include "lldb/Utility/StreamString.h" 235f29bb8aSDimitry Andric 245f29bb8aSDimitry Andric #include "llvm/ADT/STLExtras.h" 255f29bb8aSDimitry Andric #include "llvm/ADT/StringRef.h" 265f29bb8aSDimitry Andric 275f29bb8aSDimitry Andric namespace lldb_private { 285f29bb8aSDimitry Andric class IOHandlerPythonInterpreter; 295f29bb8aSDimitry Andric class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { 305f29bb8aSDimitry Andric public: 315f29bb8aSDimitry Andric friend class IOHandlerPythonInterpreter; 325f29bb8aSDimitry Andric 335f29bb8aSDimitry Andric ScriptInterpreterPythonImpl(Debugger &debugger); 345f29bb8aSDimitry Andric 355f29bb8aSDimitry Andric ~ScriptInterpreterPythonImpl() override; 365f29bb8aSDimitry Andric 375f29bb8aSDimitry Andric bool Interrupt() override; 385f29bb8aSDimitry Andric 395f29bb8aSDimitry Andric bool ExecuteOneLine( 405f29bb8aSDimitry Andric llvm::StringRef command, CommandReturnObject *result, 415f29bb8aSDimitry Andric const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 425f29bb8aSDimitry Andric 435f29bb8aSDimitry Andric void ExecuteInterpreterLoop() override; 445f29bb8aSDimitry Andric 455f29bb8aSDimitry Andric bool ExecuteOneLineWithReturn( 465f29bb8aSDimitry Andric llvm::StringRef in_string, 475f29bb8aSDimitry Andric ScriptInterpreter::ScriptReturnType return_type, void *ret_value, 485f29bb8aSDimitry Andric const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 495f29bb8aSDimitry Andric 505f29bb8aSDimitry Andric lldb_private::Status ExecuteMultipleLines( 515f29bb8aSDimitry Andric const char *in_string, 525f29bb8aSDimitry Andric const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 535f29bb8aSDimitry Andric 545f29bb8aSDimitry Andric Status 555f29bb8aSDimitry Andric ExportFunctionDefinitionToInterpreter(StringList &function_def) override; 565f29bb8aSDimitry Andric 575f29bb8aSDimitry Andric bool GenerateTypeScriptFunction(StringList &input, std::string &output, 585f29bb8aSDimitry Andric const void *name_token = nullptr) override; 595f29bb8aSDimitry Andric 605f29bb8aSDimitry Andric bool GenerateTypeSynthClass(StringList &input, std::string &output, 615f29bb8aSDimitry Andric const void *name_token = nullptr) override; 625f29bb8aSDimitry Andric 635f29bb8aSDimitry Andric bool GenerateTypeSynthClass(const char *oneliner, std::string &output, 645f29bb8aSDimitry Andric const void *name_token = nullptr) override; 655f29bb8aSDimitry Andric 665f29bb8aSDimitry Andric // use this if the function code is just a one-liner script 675f29bb8aSDimitry Andric bool GenerateTypeScriptFunction(const char *oneliner, std::string &output, 685f29bb8aSDimitry Andric const void *name_token = nullptr) override; 695f29bb8aSDimitry Andric 705f29bb8aSDimitry Andric bool GenerateScriptAliasFunction(StringList &input, 715f29bb8aSDimitry Andric std::string &output) override; 725f29bb8aSDimitry Andric 735f29bb8aSDimitry Andric StructuredData::ObjectSP 745f29bb8aSDimitry Andric CreateSyntheticScriptedProvider(const char *class_name, 755f29bb8aSDimitry Andric lldb::ValueObjectSP valobj) override; 765f29bb8aSDimitry Andric 775f29bb8aSDimitry Andric StructuredData::GenericSP 785f29bb8aSDimitry Andric CreateScriptCommandObject(const char *class_name) override; 795f29bb8aSDimitry Andric 805f29bb8aSDimitry Andric StructuredData::ObjectSP 817fa27ce4SDimitry Andric CreateStructuredDataFromScriptObject(ScriptObject obj) override; 827fa27ce4SDimitry Andric 835f29bb8aSDimitry Andric StructuredData::GenericSP 845f29bb8aSDimitry Andric CreateScriptedBreakpointResolver(const char *class_name, 8577fc4c14SDimitry Andric const StructuredDataImpl &args_data, 865f29bb8aSDimitry Andric lldb::BreakpointSP &bkpt_sp) override; 875f29bb8aSDimitry Andric bool ScriptedBreakpointResolverSearchCallback( 885f29bb8aSDimitry Andric StructuredData::GenericSP implementor_sp, 895f29bb8aSDimitry Andric SymbolContext *sym_ctx) override; 905f29bb8aSDimitry Andric 915f29bb8aSDimitry Andric lldb::SearchDepth ScriptedBreakpointResolverSearchDepth( 925f29bb8aSDimitry Andric StructuredData::GenericSP implementor_sp) override; 935f29bb8aSDimitry Andric 945f29bb8aSDimitry Andric StructuredData::GenericSP 95b60736ecSDimitry Andric CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, 9677fc4c14SDimitry Andric const StructuredDataImpl &args_data, 9777fc4c14SDimitry Andric Status &error) override; 98b60736ecSDimitry Andric 99b60736ecSDimitry Andric bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp, 100b60736ecSDimitry Andric ExecutionContext &exc_ctx, 101b60736ecSDimitry Andric lldb::StreamSP stream_sp) override; 102b60736ecSDimitry Andric 103b60736ecSDimitry Andric StructuredData::GenericSP 1045f29bb8aSDimitry Andric CreateFrameRecognizer(const char *class_name) override; 1055f29bb8aSDimitry Andric 1065f29bb8aSDimitry Andric lldb::ValueObjectListSP 1075f29bb8aSDimitry Andric GetRecognizedArguments(const StructuredData::ObjectSP &implementor, 1085f29bb8aSDimitry Andric lldb::StackFrameSP frame_sp) override; 1095f29bb8aSDimitry Andric 1107fa27ce4SDimitry Andric lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override; 1117fa27ce4SDimitry Andric 112b1c73532SDimitry Andric lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override; 1135f29bb8aSDimitry Andric 114ac9a064cSDimitry Andric lldb::ScriptedThreadPlanInterfaceSP 115ac9a064cSDimitry Andric CreateScriptedThreadPlanInterface() override; 116ac9a064cSDimitry Andric 117b1c73532SDimitry Andric lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override; 1185f29bb8aSDimitry Andric 1195f29bb8aSDimitry Andric StructuredData::ObjectSP 1205f29bb8aSDimitry Andric LoadPluginModule(const FileSpec &file_spec, 1215f29bb8aSDimitry Andric lldb_private::Status &error) override; 1225f29bb8aSDimitry Andric 1235f29bb8aSDimitry Andric StructuredData::DictionarySP 1245f29bb8aSDimitry Andric GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, 1255f29bb8aSDimitry Andric const char *setting_name, 1265f29bb8aSDimitry Andric lldb_private::Status &error) override; 1275f29bb8aSDimitry Andric 1285f29bb8aSDimitry Andric size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, 1295f29bb8aSDimitry Andric uint32_t max) override; 1305f29bb8aSDimitry Andric 1315f29bb8aSDimitry Andric lldb::ValueObjectSP 1325f29bb8aSDimitry Andric GetChildAtIndex(const StructuredData::ObjectSP &implementor, 1335f29bb8aSDimitry Andric uint32_t idx) override; 1345f29bb8aSDimitry Andric 1355f29bb8aSDimitry Andric int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, 1365f29bb8aSDimitry Andric const char *child_name) override; 1375f29bb8aSDimitry Andric 1385f29bb8aSDimitry Andric bool UpdateSynthProviderInstance( 1395f29bb8aSDimitry Andric const StructuredData::ObjectSP &implementor) override; 1405f29bb8aSDimitry Andric 1415f29bb8aSDimitry Andric bool MightHaveChildrenSynthProviderInstance( 1425f29bb8aSDimitry Andric const StructuredData::ObjectSP &implementor) override; 1435f29bb8aSDimitry Andric 1445f29bb8aSDimitry Andric lldb::ValueObjectSP 1455f29bb8aSDimitry Andric GetSyntheticValue(const StructuredData::ObjectSP &implementor) override; 1465f29bb8aSDimitry Andric 1475f29bb8aSDimitry Andric ConstString 1485f29bb8aSDimitry Andric GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override; 1495f29bb8aSDimitry Andric 1505f29bb8aSDimitry Andric bool 1515f29bb8aSDimitry Andric RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, 1525f29bb8aSDimitry Andric ScriptedCommandSynchronicity synchronicity, 1535f29bb8aSDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, 1545f29bb8aSDimitry Andric Status &error, 1555f29bb8aSDimitry Andric const lldb_private::ExecutionContext &exe_ctx) override; 1565f29bb8aSDimitry Andric 1575f29bb8aSDimitry Andric bool RunScriptBasedCommand( 1585f29bb8aSDimitry Andric StructuredData::GenericSP impl_obj_sp, llvm::StringRef args, 1595f29bb8aSDimitry Andric ScriptedCommandSynchronicity synchronicity, 1605f29bb8aSDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, Status &error, 1615f29bb8aSDimitry Andric const lldb_private::ExecutionContext &exe_ctx) override; 1625f29bb8aSDimitry Andric 163ac9a064cSDimitry Andric bool RunScriptBasedParsedCommand( 164ac9a064cSDimitry Andric StructuredData::GenericSP impl_obj_sp, Args &args, 165ac9a064cSDimitry Andric ScriptedCommandSynchronicity synchronicity, 166ac9a064cSDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, Status &error, 167ac9a064cSDimitry Andric const lldb_private::ExecutionContext &exe_ctx) override; 168ac9a064cSDimitry Andric 169ac9a064cSDimitry Andric std::optional<std::string> 170ac9a064cSDimitry Andric GetRepeatCommandForScriptedCommand(StructuredData::GenericSP impl_obj_sp, 171ac9a064cSDimitry Andric Args &args) override; 172ac9a064cSDimitry Andric 1737fa27ce4SDimitry Andric Status GenerateFunction(const char *signature, const StringList &input, 1747fa27ce4SDimitry Andric bool is_callback) override; 1755f29bb8aSDimitry Andric 1767fa27ce4SDimitry Andric Status GenerateBreakpointCommandCallbackData(StringList &input, 177706b4fc4SDimitry Andric std::string &output, 1787fa27ce4SDimitry Andric bool has_extra_args, 1797fa27ce4SDimitry Andric bool is_callback) override; 1805f29bb8aSDimitry Andric 1815f29bb8aSDimitry Andric bool GenerateWatchpointCommandCallbackData(StringList &input, 1827fa27ce4SDimitry Andric std::string &output, 1837fa27ce4SDimitry Andric bool is_callback) override; 1845f29bb8aSDimitry Andric 1855f29bb8aSDimitry Andric bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, 1865f29bb8aSDimitry Andric StructuredData::ObjectSP &callee_wrapper_sp, 1875f29bb8aSDimitry Andric const TypeSummaryOptions &options, 1885f29bb8aSDimitry Andric std::string &retval) override; 1895f29bb8aSDimitry Andric 190e3b55780SDimitry Andric bool FormatterCallbackFunction(const char *function_name, 191e3b55780SDimitry Andric lldb::TypeImplSP type_impl_sp) override; 192e3b55780SDimitry Andric 1935f29bb8aSDimitry Andric bool GetDocumentationForItem(const char *item, std::string &dest) override; 1945f29bb8aSDimitry Andric 1955f29bb8aSDimitry Andric bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 1965f29bb8aSDimitry Andric std::string &dest) override; 1975f29bb8aSDimitry Andric 1985f29bb8aSDimitry Andric uint32_t 1995f29bb8aSDimitry Andric GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override; 2005f29bb8aSDimitry Andric 2015f29bb8aSDimitry Andric bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 2025f29bb8aSDimitry Andric std::string &dest) override; 2035f29bb8aSDimitry Andric 204ac9a064cSDimitry Andric StructuredData::ObjectSP 205ac9a064cSDimitry Andric GetOptionsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override; 206ac9a064cSDimitry Andric 207ac9a064cSDimitry Andric StructuredData::ObjectSP 208ac9a064cSDimitry Andric GetArgumentsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override; 209ac9a064cSDimitry Andric 210ac9a064cSDimitry Andric bool SetOptionValueForCommandObject(StructuredData::GenericSP cmd_obj_sp, 211ac9a064cSDimitry Andric ExecutionContext *exe_ctx, 212ac9a064cSDimitry Andric llvm::StringRef long_option, 213ac9a064cSDimitry Andric llvm::StringRef value) override; 214ac9a064cSDimitry Andric 215ac9a064cSDimitry Andric void OptionParsingStartedForCommandObject( 216ac9a064cSDimitry Andric StructuredData::GenericSP cmd_obj_sp) override; 217ac9a064cSDimitry Andric CheckObjectExists(const char * name)2185f29bb8aSDimitry Andric bool CheckObjectExists(const char *name) override { 2195f29bb8aSDimitry Andric if (!name || !name[0]) 2205f29bb8aSDimitry Andric return false; 2215f29bb8aSDimitry Andric std::string temp; 2225f29bb8aSDimitry Andric return GetDocumentationForItem(name, temp); 2235f29bb8aSDimitry Andric } 2245f29bb8aSDimitry Andric 2255f29bb8aSDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, Process *process, 2265f29bb8aSDimitry Andric std::string &output, Status &error) override; 2275f29bb8aSDimitry Andric 2285f29bb8aSDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, Thread *thread, 2295f29bb8aSDimitry Andric std::string &output, Status &error) override; 2305f29bb8aSDimitry Andric 2315f29bb8aSDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, Target *target, 2325f29bb8aSDimitry Andric std::string &output, Status &error) override; 2335f29bb8aSDimitry Andric 2345f29bb8aSDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame, 2355f29bb8aSDimitry Andric std::string &output, Status &error) override; 2365f29bb8aSDimitry Andric 2375f29bb8aSDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value, 2385f29bb8aSDimitry Andric std::string &output, Status &error) override; 2395f29bb8aSDimitry Andric 240344a3780SDimitry Andric bool LoadScriptingModule(const char *filename, 241344a3780SDimitry Andric const LoadScriptOptions &options, 2425f29bb8aSDimitry Andric lldb_private::Status &error, 243b60736ecSDimitry Andric StructuredData::ObjectSP *module_sp = nullptr, 244b60736ecSDimitry Andric FileSpec extra_search_dir = {}) override; 2455f29bb8aSDimitry Andric 2465f29bb8aSDimitry Andric bool IsReservedWord(const char *word) override; 2475f29bb8aSDimitry Andric 2485f29bb8aSDimitry Andric std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override; 2495f29bb8aSDimitry Andric 2505f29bb8aSDimitry Andric void CollectDataForBreakpointCommandCallback( 251344a3780SDimitry Andric std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, 2525f29bb8aSDimitry Andric CommandReturnObject &result) override; 2535f29bb8aSDimitry Andric 2545f29bb8aSDimitry Andric void 2555f29bb8aSDimitry Andric CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, 2565f29bb8aSDimitry Andric CommandReturnObject &result) override; 2575f29bb8aSDimitry Andric 2585f29bb8aSDimitry Andric /// Set the callback body text into the callback for the breakpoint. 259344a3780SDimitry Andric Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 2607fa27ce4SDimitry Andric const char *callback_body, 2617fa27ce4SDimitry Andric bool is_callback) override; 2625f29bb8aSDimitry Andric 263706b4fc4SDimitry Andric Status SetBreakpointCommandCallbackFunction( 264344a3780SDimitry Andric BreakpointOptions &bp_options, const char *function_name, 265706b4fc4SDimitry Andric StructuredData::ObjectSP extra_args_sp) override; 2665f29bb8aSDimitry Andric 2675f29bb8aSDimitry Andric /// This one is for deserialization: 2685f29bb8aSDimitry Andric Status SetBreakpointCommandCallback( 269344a3780SDimitry Andric BreakpointOptions &bp_options, 2705f29bb8aSDimitry Andric std::unique_ptr<BreakpointOptions::CommandData> &data_up) override; 2715f29bb8aSDimitry Andric 272344a3780SDimitry Andric Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 273706b4fc4SDimitry Andric const char *command_body_text, 274706b4fc4SDimitry Andric StructuredData::ObjectSP extra_args_sp, 2757fa27ce4SDimitry Andric bool uses_extra_args, 2767fa27ce4SDimitry Andric bool is_callback); 277706b4fc4SDimitry Andric 2785f29bb8aSDimitry Andric /// Set a one-liner as the callback for the watchpoint. 2795f29bb8aSDimitry Andric void SetWatchpointCommandCallback(WatchpointOptions *wp_options, 2807fa27ce4SDimitry Andric const char *user_input, 2817fa27ce4SDimitry Andric bool is_callback) override; 2825f29bb8aSDimitry Andric GetDictionaryName()2835f29bb8aSDimitry Andric const char *GetDictionaryName() { return m_dictionary_name.c_str(); } 2845f29bb8aSDimitry Andric GetThreadState()2855f29bb8aSDimitry Andric PyThreadState *GetThreadState() { return m_command_thread_state; } 2865f29bb8aSDimitry Andric SetThreadState(PyThreadState * s)2875f29bb8aSDimitry Andric void SetThreadState(PyThreadState *s) { 2885f29bb8aSDimitry Andric if (s) 2895f29bb8aSDimitry Andric m_command_thread_state = s; 2905f29bb8aSDimitry Andric } 2915f29bb8aSDimitry Andric 2925f29bb8aSDimitry Andric // IOHandlerDelegate 2935f29bb8aSDimitry Andric void IOHandlerActivated(IOHandler &io_handler, bool interactive) override; 2945f29bb8aSDimitry Andric 2955f29bb8aSDimitry Andric void IOHandlerInputComplete(IOHandler &io_handler, 2965f29bb8aSDimitry Andric std::string &data) override; 2975f29bb8aSDimitry Andric 2985f29bb8aSDimitry Andric static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger); 2995f29bb8aSDimitry Andric 3005f29bb8aSDimitry Andric // PluginInterface protocol GetPluginName()301c0981da4SDimitry Andric llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 3025f29bb8aSDimitry Andric 3035f29bb8aSDimitry Andric class Locker : public ScriptInterpreterLocker { 3045f29bb8aSDimitry Andric public: 3055f29bb8aSDimitry Andric enum OnEntry { 3065f29bb8aSDimitry Andric AcquireLock = 0x0001, 3075f29bb8aSDimitry Andric InitSession = 0x0002, 3085f29bb8aSDimitry Andric InitGlobals = 0x0004, 3095f29bb8aSDimitry Andric NoSTDIN = 0x0008 3105f29bb8aSDimitry Andric }; 3115f29bb8aSDimitry Andric 3125f29bb8aSDimitry Andric enum OnLeave { 3135f29bb8aSDimitry Andric FreeLock = 0x0001, 3145f29bb8aSDimitry Andric FreeAcquiredLock = 0x0002, // do not free the lock if we already held it 3155f29bb8aSDimitry Andric // when calling constructor 3165f29bb8aSDimitry Andric TearDownSession = 0x0004 3175f29bb8aSDimitry Andric }; 3185f29bb8aSDimitry Andric 319ead24645SDimitry Andric Locker(ScriptInterpreterPythonImpl *py_interpreter, 3205f29bb8aSDimitry Andric uint16_t on_entry = AcquireLock | InitSession, 321ead24645SDimitry Andric uint16_t on_leave = FreeLock | TearDownSession, 322ead24645SDimitry Andric lldb::FileSP in = nullptr, lldb::FileSP out = nullptr, 323ead24645SDimitry Andric lldb::FileSP err = nullptr); 3245f29bb8aSDimitry Andric 3255f29bb8aSDimitry Andric ~Locker() override; 3265f29bb8aSDimitry Andric 3275f29bb8aSDimitry Andric private: 3285f29bb8aSDimitry Andric bool DoAcquireLock(); 3295f29bb8aSDimitry Andric 330ead24645SDimitry Andric bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in, 331ead24645SDimitry Andric lldb::FileSP out, lldb::FileSP err); 3325f29bb8aSDimitry Andric 3335f29bb8aSDimitry Andric bool DoFreeLock(); 3345f29bb8aSDimitry Andric 3355f29bb8aSDimitry Andric bool DoTearDownSession(); 3365f29bb8aSDimitry Andric 3375f29bb8aSDimitry Andric bool m_teardown_session; 3385f29bb8aSDimitry Andric ScriptInterpreterPythonImpl *m_python_interpreter; 3395f29bb8aSDimitry Andric PyGILState_STATE m_GILState; 3405f29bb8aSDimitry Andric }; 3415f29bb8aSDimitry Andric 3425f29bb8aSDimitry Andric static bool BreakpointCallbackFunction(void *baton, 3435f29bb8aSDimitry Andric StoppointCallbackContext *context, 3445f29bb8aSDimitry Andric lldb::user_id_t break_id, 3455f29bb8aSDimitry Andric lldb::user_id_t break_loc_id); 3465f29bb8aSDimitry Andric static bool WatchpointCallbackFunction(void *baton, 3475f29bb8aSDimitry Andric StoppointCallbackContext *context, 3485f29bb8aSDimitry Andric lldb::user_id_t watch_id); 3496f8fc217SDimitry Andric static void Initialize(); 3505f29bb8aSDimitry Andric 3515f29bb8aSDimitry Andric class SynchronicityHandler { 3525f29bb8aSDimitry Andric private: 3535f29bb8aSDimitry Andric lldb::DebuggerSP m_debugger_sp; 3545f29bb8aSDimitry Andric ScriptedCommandSynchronicity m_synch_wanted; 3555f29bb8aSDimitry Andric bool m_old_asynch; 3565f29bb8aSDimitry Andric 3575f29bb8aSDimitry Andric public: 3585f29bb8aSDimitry Andric SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity); 3595f29bb8aSDimitry Andric 3605f29bb8aSDimitry Andric ~SynchronicityHandler(); 3615f29bb8aSDimitry Andric }; 3625f29bb8aSDimitry Andric 3635f29bb8aSDimitry Andric enum class AddLocation { Beginning, End }; 3645f29bb8aSDimitry Andric 3655f29bb8aSDimitry Andric static void AddToSysPath(AddLocation location, std::string path); 3665f29bb8aSDimitry Andric 367ead24645SDimitry Andric bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, 368ead24645SDimitry Andric lldb::FileSP err); 3695f29bb8aSDimitry Andric 3705f29bb8aSDimitry Andric void LeaveSession(); 3715f29bb8aSDimitry Andric IsExecutingPython()3727fa27ce4SDimitry Andric uint32_t IsExecutingPython() { 3737fa27ce4SDimitry Andric std::lock_guard<std::mutex> guard(m_mutex); 3747fa27ce4SDimitry Andric return m_lock_count > 0; 3757fa27ce4SDimitry Andric } 3765f29bb8aSDimitry Andric IncrementLockCount()3777fa27ce4SDimitry Andric uint32_t IncrementLockCount() { 3787fa27ce4SDimitry Andric std::lock_guard<std::mutex> guard(m_mutex); 3797fa27ce4SDimitry Andric return ++m_lock_count; 3807fa27ce4SDimitry Andric } 3815f29bb8aSDimitry Andric DecrementLockCount()3825f29bb8aSDimitry Andric uint32_t DecrementLockCount() { 3837fa27ce4SDimitry Andric std::lock_guard<std::mutex> guard(m_mutex); 3845f29bb8aSDimitry Andric if (m_lock_count > 0) 3855f29bb8aSDimitry Andric --m_lock_count; 3865f29bb8aSDimitry Andric return m_lock_count; 3875f29bb8aSDimitry Andric } 3885f29bb8aSDimitry Andric 3895f29bb8aSDimitry Andric enum ActiveIOHandler { 3905f29bb8aSDimitry Andric eIOHandlerNone, 3915f29bb8aSDimitry Andric eIOHandlerBreakpoint, 3925f29bb8aSDimitry Andric eIOHandlerWatchpoint 3935f29bb8aSDimitry Andric }; 3945f29bb8aSDimitry Andric 395ead24645SDimitry Andric python::PythonModule &GetMainModule(); 3965f29bb8aSDimitry Andric 397ead24645SDimitry Andric python::PythonDictionary &GetSessionDictionary(); 3985f29bb8aSDimitry Andric 399ead24645SDimitry Andric python::PythonDictionary &GetSysModuleDictionary(); 4005f29bb8aSDimitry Andric 401706b4fc4SDimitry Andric llvm::Expected<unsigned> GetMaxPositionalArgumentsForCallable( 402706b4fc4SDimitry Andric const llvm::StringRef &callable_name) override; 403706b4fc4SDimitry Andric 4045f29bb8aSDimitry Andric bool GetEmbeddedInterpreterModuleObjects(); 4055f29bb8aSDimitry Andric 406ead24645SDimitry Andric bool SetStdHandle(lldb::FileSP file, const char *py_name, 407ead24645SDimitry Andric python::PythonObject &save_file, const char *mode); 4085f29bb8aSDimitry Andric 409ead24645SDimitry Andric python::PythonObject m_saved_stdin; 410ead24645SDimitry Andric python::PythonObject m_saved_stdout; 411ead24645SDimitry Andric python::PythonObject m_saved_stderr; 412ead24645SDimitry Andric python::PythonModule m_main_module; 413ead24645SDimitry Andric python::PythonDictionary m_session_dict; 414ead24645SDimitry Andric python::PythonDictionary m_sys_module_dict; 415ead24645SDimitry Andric python::PythonObject m_run_one_line_function; 416ead24645SDimitry Andric python::PythonObject m_run_one_line_str_global; 4175f29bb8aSDimitry Andric std::string m_dictionary_name; 4185f29bb8aSDimitry Andric ActiveIOHandler m_active_io_handler; 4195f29bb8aSDimitry Andric bool m_session_is_active; 420cfca06d7SDimitry Andric bool m_pty_secondary_is_open; 4215f29bb8aSDimitry Andric bool m_valid_session; 4225f29bb8aSDimitry Andric uint32_t m_lock_count; 4237fa27ce4SDimitry Andric std::mutex m_mutex; 4245f29bb8aSDimitry Andric PyThreadState *m_command_thread_state; 4255f29bb8aSDimitry Andric }; 4265f29bb8aSDimitry Andric 4275f29bb8aSDimitry Andric class IOHandlerPythonInterpreter : public IOHandler { 4285f29bb8aSDimitry Andric public: IOHandlerPythonInterpreter(Debugger & debugger,ScriptInterpreterPythonImpl * python)4295f29bb8aSDimitry Andric IOHandlerPythonInterpreter(Debugger &debugger, 4305f29bb8aSDimitry Andric ScriptInterpreterPythonImpl *python) 4315f29bb8aSDimitry Andric : IOHandler(debugger, IOHandler::Type::PythonInterpreter), 4325f29bb8aSDimitry Andric m_python(python) {} 4335f29bb8aSDimitry Andric 434344a3780SDimitry Andric ~IOHandlerPythonInterpreter() override = default; 4355f29bb8aSDimitry Andric GetControlSequence(char ch)4367fa27ce4SDimitry Andric llvm::StringRef GetControlSequence(char ch) override { 4377fa27ce4SDimitry Andric static constexpr llvm::StringLiteral control_sequence("quit()\n"); 4385f29bb8aSDimitry Andric if (ch == 'd') 4397fa27ce4SDimitry Andric return control_sequence; 4407fa27ce4SDimitry Andric return {}; 4415f29bb8aSDimitry Andric } 4425f29bb8aSDimitry Andric Run()4435f29bb8aSDimitry Andric void Run() override { 4445f29bb8aSDimitry Andric if (m_python) { 4455f29bb8aSDimitry Andric int stdin_fd = GetInputFD(); 4465f29bb8aSDimitry Andric if (stdin_fd >= 0) { 4475f29bb8aSDimitry Andric Terminal terminal(stdin_fd); 448c0981da4SDimitry Andric TerminalState terminal_state(terminal); 4495f29bb8aSDimitry Andric 450c0981da4SDimitry Andric if (terminal.IsATerminal()) { 451c0981da4SDimitry Andric // FIXME: error handling? 452c0981da4SDimitry Andric llvm::consumeError(terminal.SetCanonical(false)); 453c0981da4SDimitry Andric llvm::consumeError(terminal.SetEcho(true)); 4545f29bb8aSDimitry Andric } 4555f29bb8aSDimitry Andric 4565f29bb8aSDimitry Andric ScriptInterpreterPythonImpl::Locker locker( 4575f29bb8aSDimitry Andric m_python, 4585f29bb8aSDimitry Andric ScriptInterpreterPythonImpl::Locker::AcquireLock | 4595f29bb8aSDimitry Andric ScriptInterpreterPythonImpl::Locker::InitSession | 4605f29bb8aSDimitry Andric ScriptInterpreterPythonImpl::Locker::InitGlobals, 4615f29bb8aSDimitry Andric ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock | 4625f29bb8aSDimitry Andric ScriptInterpreterPythonImpl::Locker::TearDownSession); 4635f29bb8aSDimitry Andric 4645f29bb8aSDimitry Andric // The following call drops into the embedded interpreter loop and 4655f29bb8aSDimitry Andric // stays there until the user chooses to exit from the Python 4665f29bb8aSDimitry Andric // interpreter. This embedded interpreter will, as any Python code that 4675f29bb8aSDimitry Andric // performs I/O, unlock the GIL before a system call that can hang, and 4685f29bb8aSDimitry Andric // lock it when the syscall has returned. 4695f29bb8aSDimitry Andric 4705f29bb8aSDimitry Andric // We need to surround the call to the embedded interpreter with calls 4715f29bb8aSDimitry Andric // to PyGILState_Ensure and PyGILState_Release (using the Locker 4725f29bb8aSDimitry Andric // above). This is because Python has a global lock which must be held 4735f29bb8aSDimitry Andric // whenever we want to touch any Python objects. Otherwise, if the user 4745f29bb8aSDimitry Andric // calls Python code, the interpreter state will be off, and things 4755f29bb8aSDimitry Andric // could hang (it's happened before). 4765f29bb8aSDimitry Andric 4775f29bb8aSDimitry Andric StreamString run_string; 4785f29bb8aSDimitry Andric run_string.Printf("run_python_interpreter (%s)", 4795f29bb8aSDimitry Andric m_python->GetDictionaryName()); 4805f29bb8aSDimitry Andric PyRun_SimpleString(run_string.GetData()); 4815f29bb8aSDimitry Andric } 4825f29bb8aSDimitry Andric } 4835f29bb8aSDimitry Andric SetIsDone(true); 4845f29bb8aSDimitry Andric } 4855f29bb8aSDimitry Andric Cancel()4865f29bb8aSDimitry Andric void Cancel() override {} 4875f29bb8aSDimitry Andric Interrupt()4885f29bb8aSDimitry Andric bool Interrupt() override { return m_python->Interrupt(); } 4895f29bb8aSDimitry Andric GotEOF()4905f29bb8aSDimitry Andric void GotEOF() override {} 4915f29bb8aSDimitry Andric 4925f29bb8aSDimitry Andric protected: 4935f29bb8aSDimitry Andric ScriptInterpreterPythonImpl *m_python; 4945f29bb8aSDimitry Andric }; 4955f29bb8aSDimitry Andric 4965f29bb8aSDimitry Andric } // namespace lldb_private 4975f29bb8aSDimitry Andric 498344a3780SDimitry Andric #endif // LLDB_ENABLE_PYTHON 499344a3780SDimitry Andric #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 500