163dd5d25SJonas Devlieghere //===-- ScriptInterpreterPythonImpl.h ---------------------------*- C++ -*-===// 263dd5d25SJonas Devlieghere // 363dd5d25SJonas Devlieghere // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 463dd5d25SJonas Devlieghere // See https://llvm.org/LICENSE.txt for license information. 563dd5d25SJonas Devlieghere // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 663dd5d25SJonas Devlieghere // 763dd5d25SJonas Devlieghere //===----------------------------------------------------------------------===// 863dd5d25SJonas Devlieghere 91f6a57c1SMed Ismail Bennani #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 101f6a57c1SMed Ismail Bennani #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 111f6a57c1SMed Ismail Bennani 1259998b7bSJonas Devlieghere #include "lldb/Host/Config.h" 1363dd5d25SJonas Devlieghere 144e26cf2cSJonas Devlieghere #if LLDB_ENABLE_PYTHON 1563dd5d25SJonas Devlieghere 1663dd5d25SJonas Devlieghere #include "lldb-python.h" 1763dd5d25SJonas Devlieghere 1863dd5d25SJonas Devlieghere #include "PythonDataObjects.h" 1963dd5d25SJonas Devlieghere #include "ScriptInterpreterPython.h" 2063dd5d25SJonas Devlieghere 2163dd5d25SJonas Devlieghere #include "lldb/Host/Terminal.h" 2263dd5d25SJonas Devlieghere #include "lldb/Utility/StreamString.h" 2363dd5d25SJonas Devlieghere 2463dd5d25SJonas Devlieghere #include "llvm/ADT/STLExtras.h" 2563dd5d25SJonas Devlieghere #include "llvm/ADT/StringRef.h" 2663dd5d25SJonas Devlieghere 2763dd5d25SJonas Devlieghere namespace lldb_private { 2863dd5d25SJonas Devlieghere class IOHandlerPythonInterpreter; 2963dd5d25SJonas Devlieghere class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { 3063dd5d25SJonas Devlieghere public: 3163dd5d25SJonas Devlieghere friend class IOHandlerPythonInterpreter; 3263dd5d25SJonas Devlieghere 338d1fb843SJonas Devlieghere ScriptInterpreterPythonImpl(Debugger &debugger); 3463dd5d25SJonas Devlieghere 3563dd5d25SJonas Devlieghere ~ScriptInterpreterPythonImpl() override; 3663dd5d25SJonas Devlieghere 3763dd5d25SJonas Devlieghere bool Interrupt() override; 3863dd5d25SJonas Devlieghere 3963dd5d25SJonas Devlieghere bool ExecuteOneLine( 4063dd5d25SJonas Devlieghere llvm::StringRef command, CommandReturnObject *result, 4163dd5d25SJonas Devlieghere const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 4263dd5d25SJonas Devlieghere 4363dd5d25SJonas Devlieghere void ExecuteInterpreterLoop() override; 4463dd5d25SJonas Devlieghere 4563dd5d25SJonas Devlieghere bool ExecuteOneLineWithReturn( 4663dd5d25SJonas Devlieghere llvm::StringRef in_string, 4763dd5d25SJonas Devlieghere ScriptInterpreter::ScriptReturnType return_type, void *ret_value, 4863dd5d25SJonas Devlieghere const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 4963dd5d25SJonas Devlieghere 5063dd5d25SJonas Devlieghere lldb_private::Status ExecuteMultipleLines( 5163dd5d25SJonas Devlieghere const char *in_string, 5263dd5d25SJonas Devlieghere const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 5363dd5d25SJonas Devlieghere 5463dd5d25SJonas Devlieghere Status 5563dd5d25SJonas Devlieghere ExportFunctionDefinitionToInterpreter(StringList &function_def) override; 5663dd5d25SJonas Devlieghere 5763dd5d25SJonas Devlieghere bool GenerateTypeScriptFunction(StringList &input, std::string &output, 5863dd5d25SJonas Devlieghere const void *name_token = nullptr) override; 5963dd5d25SJonas Devlieghere 6063dd5d25SJonas Devlieghere bool GenerateTypeSynthClass(StringList &input, std::string &output, 6163dd5d25SJonas Devlieghere const void *name_token = nullptr) override; 6263dd5d25SJonas Devlieghere 6363dd5d25SJonas Devlieghere bool GenerateTypeSynthClass(const char *oneliner, std::string &output, 6463dd5d25SJonas Devlieghere const void *name_token = nullptr) override; 6563dd5d25SJonas Devlieghere 6663dd5d25SJonas Devlieghere // use this if the function code is just a one-liner script 6763dd5d25SJonas Devlieghere bool GenerateTypeScriptFunction(const char *oneliner, std::string &output, 6863dd5d25SJonas Devlieghere const void *name_token = nullptr) override; 6963dd5d25SJonas Devlieghere 7063dd5d25SJonas Devlieghere bool GenerateScriptAliasFunction(StringList &input, 7163dd5d25SJonas Devlieghere std::string &output) override; 7263dd5d25SJonas Devlieghere 7363dd5d25SJonas Devlieghere StructuredData::ObjectSP 7463dd5d25SJonas Devlieghere CreateSyntheticScriptedProvider(const char *class_name, 7563dd5d25SJonas Devlieghere lldb::ValueObjectSP valobj) override; 7663dd5d25SJonas Devlieghere 7763dd5d25SJonas Devlieghere StructuredData::GenericSP 7863dd5d25SJonas Devlieghere CreateScriptCommandObject(const char *class_name) override; 7963dd5d25SJonas Devlieghere 8063dd5d25SJonas Devlieghere StructuredData::ObjectSP 8163dd5d25SJonas Devlieghere CreateScriptedThreadPlan(const char *class_name, 8227a14f19SJim Ingham StructuredDataImpl *args_data, 8393c98346SJim Ingham std::string &error_str, 8463dd5d25SJonas Devlieghere lldb::ThreadPlanSP thread_plan) override; 8563dd5d25SJonas Devlieghere 8663dd5d25SJonas Devlieghere bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, 8763dd5d25SJonas Devlieghere Event *event, 8863dd5d25SJonas Devlieghere bool &script_error) override; 8963dd5d25SJonas Devlieghere 9063dd5d25SJonas Devlieghere bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, 9163dd5d25SJonas Devlieghere Event *event, bool &script_error) override; 9263dd5d25SJonas Devlieghere 9363dd5d25SJonas Devlieghere bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp, 9463dd5d25SJonas Devlieghere bool &script_error) override; 9563dd5d25SJonas Devlieghere 9663dd5d25SJonas Devlieghere lldb::StateType 9763dd5d25SJonas Devlieghere ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, 9863dd5d25SJonas Devlieghere bool &script_error) override; 9963dd5d25SJonas Devlieghere 10063dd5d25SJonas Devlieghere StructuredData::GenericSP 10163dd5d25SJonas Devlieghere CreateScriptedBreakpointResolver(const char *class_name, 10263dd5d25SJonas Devlieghere StructuredDataImpl *args_data, 10363dd5d25SJonas Devlieghere lldb::BreakpointSP &bkpt_sp) override; 10463dd5d25SJonas Devlieghere bool ScriptedBreakpointResolverSearchCallback( 10563dd5d25SJonas Devlieghere StructuredData::GenericSP implementor_sp, 10663dd5d25SJonas Devlieghere SymbolContext *sym_ctx) override; 10763dd5d25SJonas Devlieghere 10863dd5d25SJonas Devlieghere lldb::SearchDepth ScriptedBreakpointResolverSearchDepth( 10963dd5d25SJonas Devlieghere StructuredData::GenericSP implementor_sp) override; 11063dd5d25SJonas Devlieghere 11163dd5d25SJonas Devlieghere StructuredData::GenericSP 1121b1d9815SJim Ingham CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, 1131b1d9815SJim Ingham StructuredDataImpl *args_data, Status &error) override; 1141b1d9815SJim Ingham 1151b1d9815SJim Ingham bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp, 1161b1d9815SJim Ingham ExecutionContext &exc_ctx, 1171b1d9815SJim Ingham lldb::StreamSP stream_sp) override; 1181b1d9815SJim Ingham 1191b1d9815SJim Ingham StructuredData::GenericSP 12063dd5d25SJonas Devlieghere CreateFrameRecognizer(const char *class_name) override; 12163dd5d25SJonas Devlieghere 12263dd5d25SJonas Devlieghere lldb::ValueObjectListSP 12363dd5d25SJonas Devlieghere GetRecognizedArguments(const StructuredData::ObjectSP &implementor, 12463dd5d25SJonas Devlieghere lldb::StackFrameSP frame_sp) override; 12563dd5d25SJonas Devlieghere 12663dd5d25SJonas Devlieghere StructuredData::GenericSP 12763dd5d25SJonas Devlieghere OSPlugin_CreatePluginObject(const char *class_name, 12863dd5d25SJonas Devlieghere lldb::ProcessSP process_sp) override; 12963dd5d25SJonas Devlieghere 13063dd5d25SJonas Devlieghere StructuredData::DictionarySP 13163dd5d25SJonas Devlieghere OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 13263dd5d25SJonas Devlieghere 13363dd5d25SJonas Devlieghere StructuredData::ArraySP 13463dd5d25SJonas Devlieghere OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 13563dd5d25SJonas Devlieghere 13663dd5d25SJonas Devlieghere StructuredData::StringSP 13763dd5d25SJonas Devlieghere OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, 13863dd5d25SJonas Devlieghere lldb::tid_t thread_id) override; 13963dd5d25SJonas Devlieghere 14063dd5d25SJonas Devlieghere StructuredData::DictionarySP 14163dd5d25SJonas Devlieghere OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, 14263dd5d25SJonas Devlieghere lldb::tid_t tid, lldb::addr_t context) override; 14363dd5d25SJonas Devlieghere 14463dd5d25SJonas Devlieghere StructuredData::ObjectSP 14563dd5d25SJonas Devlieghere LoadPluginModule(const FileSpec &file_spec, 14663dd5d25SJonas Devlieghere lldb_private::Status &error) override; 14763dd5d25SJonas Devlieghere 14863dd5d25SJonas Devlieghere StructuredData::DictionarySP 14963dd5d25SJonas Devlieghere GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, 15063dd5d25SJonas Devlieghere const char *setting_name, 15163dd5d25SJonas Devlieghere lldb_private::Status &error) override; 15263dd5d25SJonas Devlieghere 15363dd5d25SJonas Devlieghere size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, 15463dd5d25SJonas Devlieghere uint32_t max) override; 15563dd5d25SJonas Devlieghere 15663dd5d25SJonas Devlieghere lldb::ValueObjectSP 15763dd5d25SJonas Devlieghere GetChildAtIndex(const StructuredData::ObjectSP &implementor, 15863dd5d25SJonas Devlieghere uint32_t idx) override; 15963dd5d25SJonas Devlieghere 16063dd5d25SJonas Devlieghere int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, 16163dd5d25SJonas Devlieghere const char *child_name) override; 16263dd5d25SJonas Devlieghere 16363dd5d25SJonas Devlieghere bool UpdateSynthProviderInstance( 16463dd5d25SJonas Devlieghere const StructuredData::ObjectSP &implementor) override; 16563dd5d25SJonas Devlieghere 16663dd5d25SJonas Devlieghere bool MightHaveChildrenSynthProviderInstance( 16763dd5d25SJonas Devlieghere const StructuredData::ObjectSP &implementor) override; 16863dd5d25SJonas Devlieghere 16963dd5d25SJonas Devlieghere lldb::ValueObjectSP 17063dd5d25SJonas Devlieghere GetSyntheticValue(const StructuredData::ObjectSP &implementor) override; 17163dd5d25SJonas Devlieghere 17263dd5d25SJonas Devlieghere ConstString 17363dd5d25SJonas Devlieghere GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override; 17463dd5d25SJonas Devlieghere 17563dd5d25SJonas Devlieghere bool 17663dd5d25SJonas Devlieghere RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, 17763dd5d25SJonas Devlieghere ScriptedCommandSynchronicity synchronicity, 17863dd5d25SJonas Devlieghere lldb_private::CommandReturnObject &cmd_retobj, 17963dd5d25SJonas Devlieghere Status &error, 18063dd5d25SJonas Devlieghere const lldb_private::ExecutionContext &exe_ctx) override; 18163dd5d25SJonas Devlieghere 18263dd5d25SJonas Devlieghere bool RunScriptBasedCommand( 18363dd5d25SJonas Devlieghere StructuredData::GenericSP impl_obj_sp, llvm::StringRef args, 18463dd5d25SJonas Devlieghere ScriptedCommandSynchronicity synchronicity, 18563dd5d25SJonas Devlieghere lldb_private::CommandReturnObject &cmd_retobj, Status &error, 18663dd5d25SJonas Devlieghere const lldb_private::ExecutionContext &exe_ctx) override; 18763dd5d25SJonas Devlieghere 18863dd5d25SJonas Devlieghere Status GenerateFunction(const char *signature, 18963dd5d25SJonas Devlieghere const StringList &input) override; 19063dd5d25SJonas Devlieghere 191738af7a6SJim Ingham Status GenerateBreakpointCommandCallbackData( 192738af7a6SJim Ingham StringList &input, 193738af7a6SJim Ingham std::string &output, 194738af7a6SJim Ingham bool has_extra_args) override; 19563dd5d25SJonas Devlieghere 19663dd5d25SJonas Devlieghere bool GenerateWatchpointCommandCallbackData(StringList &input, 19763dd5d25SJonas Devlieghere std::string &output) override; 19863dd5d25SJonas Devlieghere 19963dd5d25SJonas Devlieghere bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, 20063dd5d25SJonas Devlieghere StructuredData::ObjectSP &callee_wrapper_sp, 20163dd5d25SJonas Devlieghere const TypeSummaryOptions &options, 20263dd5d25SJonas Devlieghere std::string &retval) override; 20363dd5d25SJonas Devlieghere 20463dd5d25SJonas Devlieghere bool GetDocumentationForItem(const char *item, std::string &dest) override; 20563dd5d25SJonas Devlieghere 20663dd5d25SJonas Devlieghere bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 20763dd5d25SJonas Devlieghere std::string &dest) override; 20863dd5d25SJonas Devlieghere 20963dd5d25SJonas Devlieghere uint32_t 21063dd5d25SJonas Devlieghere GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override; 21163dd5d25SJonas Devlieghere 21263dd5d25SJonas Devlieghere bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 21363dd5d25SJonas Devlieghere std::string &dest) override; 21463dd5d25SJonas Devlieghere 21563dd5d25SJonas Devlieghere bool CheckObjectExists(const char *name) override { 21663dd5d25SJonas Devlieghere if (!name || !name[0]) 21763dd5d25SJonas Devlieghere return false; 21863dd5d25SJonas Devlieghere std::string temp; 21963dd5d25SJonas Devlieghere return GetDocumentationForItem(name, temp); 22063dd5d25SJonas Devlieghere } 22163dd5d25SJonas Devlieghere 22263dd5d25SJonas Devlieghere bool RunScriptFormatKeyword(const char *impl_function, Process *process, 22363dd5d25SJonas Devlieghere std::string &output, Status &error) override; 22463dd5d25SJonas Devlieghere 22563dd5d25SJonas Devlieghere bool RunScriptFormatKeyword(const char *impl_function, Thread *thread, 22663dd5d25SJonas Devlieghere std::string &output, Status &error) override; 22763dd5d25SJonas Devlieghere 22863dd5d25SJonas Devlieghere bool RunScriptFormatKeyword(const char *impl_function, Target *target, 22963dd5d25SJonas Devlieghere std::string &output, Status &error) override; 23063dd5d25SJonas Devlieghere 23163dd5d25SJonas Devlieghere bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame, 23263dd5d25SJonas Devlieghere std::string &output, Status &error) override; 23363dd5d25SJonas Devlieghere 23463dd5d25SJonas Devlieghere bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value, 23563dd5d25SJonas Devlieghere std::string &output, Status &error) override; 23663dd5d25SJonas Devlieghere 23700bb397bSJonas Devlieghere bool LoadScriptingModule(const char *filename, bool init_session, 23863dd5d25SJonas Devlieghere lldb_private::Status &error, 23900bb397bSJonas Devlieghere StructuredData::ObjectSP *module_sp = nullptr, 24000bb397bSJonas Devlieghere FileSpec extra_search_dir = {}) override; 24163dd5d25SJonas Devlieghere 24263dd5d25SJonas Devlieghere bool IsReservedWord(const char *word) override; 24363dd5d25SJonas Devlieghere 24463dd5d25SJonas Devlieghere std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override; 24563dd5d25SJonas Devlieghere 24663dd5d25SJonas Devlieghere void CollectDataForBreakpointCommandCallback( 247cfb96d84SJim Ingham std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, 24863dd5d25SJonas Devlieghere CommandReturnObject &result) override; 24963dd5d25SJonas Devlieghere 25063dd5d25SJonas Devlieghere void 25163dd5d25SJonas Devlieghere CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, 25263dd5d25SJonas Devlieghere CommandReturnObject &result) override; 25363dd5d25SJonas Devlieghere 25463dd5d25SJonas Devlieghere /// Set the callback body text into the callback for the breakpoint. 255cfb96d84SJim Ingham Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 25663dd5d25SJonas Devlieghere const char *callback_body) override; 25763dd5d25SJonas Devlieghere 258738af7a6SJim Ingham Status SetBreakpointCommandCallbackFunction( 259cfb96d84SJim Ingham BreakpointOptions &bp_options, const char *function_name, 260738af7a6SJim Ingham StructuredData::ObjectSP extra_args_sp) override; 26163dd5d25SJonas Devlieghere 26263dd5d25SJonas Devlieghere /// This one is for deserialization: 26363dd5d25SJonas Devlieghere Status SetBreakpointCommandCallback( 264cfb96d84SJim Ingham BreakpointOptions &bp_options, 26563dd5d25SJonas Devlieghere std::unique_ptr<BreakpointOptions::CommandData> &data_up) override; 26663dd5d25SJonas Devlieghere 267cfb96d84SJim Ingham Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 268738af7a6SJim Ingham const char *command_body_text, 269738af7a6SJim Ingham StructuredData::ObjectSP extra_args_sp, 270738af7a6SJim Ingham bool uses_extra_args); 271738af7a6SJim Ingham 27263dd5d25SJonas Devlieghere /// Set a one-liner as the callback for the watchpoint. 27363dd5d25SJonas Devlieghere void SetWatchpointCommandCallback(WatchpointOptions *wp_options, 27463dd5d25SJonas Devlieghere const char *oneliner) override; 27563dd5d25SJonas Devlieghere 27663dd5d25SJonas Devlieghere const char *GetDictionaryName() { return m_dictionary_name.c_str(); } 27763dd5d25SJonas Devlieghere 27863dd5d25SJonas Devlieghere PyThreadState *GetThreadState() { return m_command_thread_state; } 27963dd5d25SJonas Devlieghere 28063dd5d25SJonas Devlieghere void SetThreadState(PyThreadState *s) { 28163dd5d25SJonas Devlieghere if (s) 28263dd5d25SJonas Devlieghere m_command_thread_state = s; 28363dd5d25SJonas Devlieghere } 28463dd5d25SJonas Devlieghere 28563dd5d25SJonas Devlieghere // IOHandlerDelegate 28663dd5d25SJonas Devlieghere void IOHandlerActivated(IOHandler &io_handler, bool interactive) override; 28763dd5d25SJonas Devlieghere 28863dd5d25SJonas Devlieghere void IOHandlerInputComplete(IOHandler &io_handler, 28963dd5d25SJonas Devlieghere std::string &data) override; 29063dd5d25SJonas Devlieghere 2918d1fb843SJonas Devlieghere static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger); 29263dd5d25SJonas Devlieghere 29363dd5d25SJonas Devlieghere // PluginInterface protocol 29463dd5d25SJonas Devlieghere lldb_private::ConstString GetPluginName() override; 29563dd5d25SJonas Devlieghere 29663dd5d25SJonas Devlieghere uint32_t GetPluginVersion() override; 29763dd5d25SJonas Devlieghere 29863dd5d25SJonas Devlieghere class Locker : public ScriptInterpreterLocker { 29963dd5d25SJonas Devlieghere public: 30063dd5d25SJonas Devlieghere enum OnEntry { 30163dd5d25SJonas Devlieghere AcquireLock = 0x0001, 30263dd5d25SJonas Devlieghere InitSession = 0x0002, 30363dd5d25SJonas Devlieghere InitGlobals = 0x0004, 30463dd5d25SJonas Devlieghere NoSTDIN = 0x0008 30563dd5d25SJonas Devlieghere }; 30663dd5d25SJonas Devlieghere 30763dd5d25SJonas Devlieghere enum OnLeave { 30863dd5d25SJonas Devlieghere FreeLock = 0x0001, 30963dd5d25SJonas Devlieghere FreeAcquiredLock = 0x0002, // do not free the lock if we already held it 31063dd5d25SJonas Devlieghere // when calling constructor 31163dd5d25SJonas Devlieghere TearDownSession = 0x0004 31263dd5d25SJonas Devlieghere }; 31363dd5d25SJonas Devlieghere 314b07823f3SLawrence D'Anna Locker(ScriptInterpreterPythonImpl *py_interpreter, 31563dd5d25SJonas Devlieghere uint16_t on_entry = AcquireLock | InitSession, 316b07823f3SLawrence D'Anna uint16_t on_leave = FreeLock | TearDownSession, 317b07823f3SLawrence D'Anna lldb::FileSP in = nullptr, lldb::FileSP out = nullptr, 318b07823f3SLawrence D'Anna lldb::FileSP err = nullptr); 31963dd5d25SJonas Devlieghere 32063dd5d25SJonas Devlieghere ~Locker() override; 32163dd5d25SJonas Devlieghere 32263dd5d25SJonas Devlieghere private: 32363dd5d25SJonas Devlieghere bool DoAcquireLock(); 32463dd5d25SJonas Devlieghere 325b07823f3SLawrence D'Anna bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in, 326b07823f3SLawrence D'Anna lldb::FileSP out, lldb::FileSP err); 32763dd5d25SJonas Devlieghere 32863dd5d25SJonas Devlieghere bool DoFreeLock(); 32963dd5d25SJonas Devlieghere 33063dd5d25SJonas Devlieghere bool DoTearDownSession(); 33163dd5d25SJonas Devlieghere 33263dd5d25SJonas Devlieghere bool m_teardown_session; 33363dd5d25SJonas Devlieghere ScriptInterpreterPythonImpl *m_python_interpreter; 33463dd5d25SJonas Devlieghere PyGILState_STATE m_GILState; 33563dd5d25SJonas Devlieghere }; 33663dd5d25SJonas Devlieghere 33763dd5d25SJonas Devlieghere static bool BreakpointCallbackFunction(void *baton, 33863dd5d25SJonas Devlieghere StoppointCallbackContext *context, 33963dd5d25SJonas Devlieghere lldb::user_id_t break_id, 34063dd5d25SJonas Devlieghere lldb::user_id_t break_loc_id); 34163dd5d25SJonas Devlieghere static bool WatchpointCallbackFunction(void *baton, 34263dd5d25SJonas Devlieghere StoppointCallbackContext *context, 34363dd5d25SJonas Devlieghere lldb::user_id_t watch_id); 34463dd5d25SJonas Devlieghere static void InitializePrivate(); 34563dd5d25SJonas Devlieghere 34663dd5d25SJonas Devlieghere class SynchronicityHandler { 34763dd5d25SJonas Devlieghere private: 34863dd5d25SJonas Devlieghere lldb::DebuggerSP m_debugger_sp; 34963dd5d25SJonas Devlieghere ScriptedCommandSynchronicity m_synch_wanted; 35063dd5d25SJonas Devlieghere bool m_old_asynch; 35163dd5d25SJonas Devlieghere 35263dd5d25SJonas Devlieghere public: 35363dd5d25SJonas Devlieghere SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity); 35463dd5d25SJonas Devlieghere 35563dd5d25SJonas Devlieghere ~SynchronicityHandler(); 35663dd5d25SJonas Devlieghere }; 35763dd5d25SJonas Devlieghere 35863dd5d25SJonas Devlieghere enum class AddLocation { Beginning, End }; 35963dd5d25SJonas Devlieghere 36063dd5d25SJonas Devlieghere static void AddToSysPath(AddLocation location, std::string path); 36163dd5d25SJonas Devlieghere 362b07823f3SLawrence D'Anna bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, 363b07823f3SLawrence D'Anna lldb::FileSP err); 36463dd5d25SJonas Devlieghere 36563dd5d25SJonas Devlieghere void LeaveSession(); 36663dd5d25SJonas Devlieghere 36763dd5d25SJonas Devlieghere uint32_t IsExecutingPython() const { return m_lock_count > 0; } 36863dd5d25SJonas Devlieghere 36963dd5d25SJonas Devlieghere uint32_t IncrementLockCount() { return ++m_lock_count; } 37063dd5d25SJonas Devlieghere 37163dd5d25SJonas Devlieghere uint32_t DecrementLockCount() { 37263dd5d25SJonas Devlieghere if (m_lock_count > 0) 37363dd5d25SJonas Devlieghere --m_lock_count; 37463dd5d25SJonas Devlieghere return m_lock_count; 37563dd5d25SJonas Devlieghere } 37663dd5d25SJonas Devlieghere 37763dd5d25SJonas Devlieghere enum ActiveIOHandler { 37863dd5d25SJonas Devlieghere eIOHandlerNone, 37963dd5d25SJonas Devlieghere eIOHandlerBreakpoint, 38063dd5d25SJonas Devlieghere eIOHandlerWatchpoint 38163dd5d25SJonas Devlieghere }; 38263dd5d25SJonas Devlieghere 38304edd189SLawrence D'Anna python::PythonModule &GetMainModule(); 38463dd5d25SJonas Devlieghere 38504edd189SLawrence D'Anna python::PythonDictionary &GetSessionDictionary(); 38663dd5d25SJonas Devlieghere 38704edd189SLawrence D'Anna python::PythonDictionary &GetSysModuleDictionary(); 38863dd5d25SJonas Devlieghere 389a69bbe02SLawrence D'Anna llvm::Expected<unsigned> GetMaxPositionalArgumentsForCallable( 390a69bbe02SLawrence D'Anna const llvm::StringRef &callable_name) override; 391738af7a6SJim Ingham 39263dd5d25SJonas Devlieghere bool GetEmbeddedInterpreterModuleObjects(); 39363dd5d25SJonas Devlieghere 394b07823f3SLawrence D'Anna bool SetStdHandle(lldb::FileSP file, const char *py_name, 39504edd189SLawrence D'Anna python::PythonObject &save_file, const char *mode); 39663dd5d25SJonas Devlieghere 39704edd189SLawrence D'Anna python::PythonObject m_saved_stdin; 39804edd189SLawrence D'Anna python::PythonObject m_saved_stdout; 39904edd189SLawrence D'Anna python::PythonObject m_saved_stderr; 40004edd189SLawrence D'Anna python::PythonModule m_main_module; 40104edd189SLawrence D'Anna python::PythonDictionary m_session_dict; 40204edd189SLawrence D'Anna python::PythonDictionary m_sys_module_dict; 40304edd189SLawrence D'Anna python::PythonObject m_run_one_line_function; 40404edd189SLawrence D'Anna python::PythonObject m_run_one_line_str_global; 40563dd5d25SJonas Devlieghere std::string m_dictionary_name; 40663dd5d25SJonas Devlieghere ActiveIOHandler m_active_io_handler; 40763dd5d25SJonas Devlieghere bool m_session_is_active; 40864ec505dSJonas Devlieghere bool m_pty_secondary_is_open; 40963dd5d25SJonas Devlieghere bool m_valid_session; 41063dd5d25SJonas Devlieghere uint32_t m_lock_count; 41163dd5d25SJonas Devlieghere PyThreadState *m_command_thread_state; 41263dd5d25SJonas Devlieghere }; 41363dd5d25SJonas Devlieghere 41463dd5d25SJonas Devlieghere class IOHandlerPythonInterpreter : public IOHandler { 41563dd5d25SJonas Devlieghere public: 41663dd5d25SJonas Devlieghere IOHandlerPythonInterpreter(Debugger &debugger, 41763dd5d25SJonas Devlieghere ScriptInterpreterPythonImpl *python) 41863dd5d25SJonas Devlieghere : IOHandler(debugger, IOHandler::Type::PythonInterpreter), 41963dd5d25SJonas Devlieghere m_python(python) {} 42063dd5d25SJonas Devlieghere 421*fd2433e1SJonas Devlieghere ~IOHandlerPythonInterpreter() override = default; 42263dd5d25SJonas Devlieghere 42363dd5d25SJonas Devlieghere ConstString GetControlSequence(char ch) override { 42463dd5d25SJonas Devlieghere if (ch == 'd') 42563dd5d25SJonas Devlieghere return ConstString("quit()\n"); 42663dd5d25SJonas Devlieghere return ConstString(); 42763dd5d25SJonas Devlieghere } 42863dd5d25SJonas Devlieghere 42963dd5d25SJonas Devlieghere void Run() override { 43063dd5d25SJonas Devlieghere if (m_python) { 43163dd5d25SJonas Devlieghere int stdin_fd = GetInputFD(); 43263dd5d25SJonas Devlieghere if (stdin_fd >= 0) { 43363dd5d25SJonas Devlieghere Terminal terminal(stdin_fd); 43463dd5d25SJonas Devlieghere TerminalState terminal_state; 43563dd5d25SJonas Devlieghere const bool is_a_tty = terminal.IsATerminal(); 43663dd5d25SJonas Devlieghere 43763dd5d25SJonas Devlieghere if (is_a_tty) { 43863dd5d25SJonas Devlieghere terminal_state.Save(stdin_fd, false); 43963dd5d25SJonas Devlieghere terminal.SetCanonical(false); 44063dd5d25SJonas Devlieghere terminal.SetEcho(true); 44163dd5d25SJonas Devlieghere } 44263dd5d25SJonas Devlieghere 44363dd5d25SJonas Devlieghere ScriptInterpreterPythonImpl::Locker locker( 44463dd5d25SJonas Devlieghere m_python, 44563dd5d25SJonas Devlieghere ScriptInterpreterPythonImpl::Locker::AcquireLock | 44663dd5d25SJonas Devlieghere ScriptInterpreterPythonImpl::Locker::InitSession | 44763dd5d25SJonas Devlieghere ScriptInterpreterPythonImpl::Locker::InitGlobals, 44863dd5d25SJonas Devlieghere ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock | 44963dd5d25SJonas Devlieghere ScriptInterpreterPythonImpl::Locker::TearDownSession); 45063dd5d25SJonas Devlieghere 45163dd5d25SJonas Devlieghere // The following call drops into the embedded interpreter loop and 45263dd5d25SJonas Devlieghere // stays there until the user chooses to exit from the Python 45363dd5d25SJonas Devlieghere // interpreter. This embedded interpreter will, as any Python code that 45463dd5d25SJonas Devlieghere // performs I/O, unlock the GIL before a system call that can hang, and 45563dd5d25SJonas Devlieghere // lock it when the syscall has returned. 45663dd5d25SJonas Devlieghere 45763dd5d25SJonas Devlieghere // We need to surround the call to the embedded interpreter with calls 45863dd5d25SJonas Devlieghere // to PyGILState_Ensure and PyGILState_Release (using the Locker 45963dd5d25SJonas Devlieghere // above). This is because Python has a global lock which must be held 46063dd5d25SJonas Devlieghere // whenever we want to touch any Python objects. Otherwise, if the user 46163dd5d25SJonas Devlieghere // calls Python code, the interpreter state will be off, and things 46263dd5d25SJonas Devlieghere // could hang (it's happened before). 46363dd5d25SJonas Devlieghere 46463dd5d25SJonas Devlieghere StreamString run_string; 46563dd5d25SJonas Devlieghere run_string.Printf("run_python_interpreter (%s)", 46663dd5d25SJonas Devlieghere m_python->GetDictionaryName()); 46763dd5d25SJonas Devlieghere PyRun_SimpleString(run_string.GetData()); 46863dd5d25SJonas Devlieghere 46963dd5d25SJonas Devlieghere if (is_a_tty) 47063dd5d25SJonas Devlieghere terminal_state.Restore(); 47163dd5d25SJonas Devlieghere } 47263dd5d25SJonas Devlieghere } 47363dd5d25SJonas Devlieghere SetIsDone(true); 47463dd5d25SJonas Devlieghere } 47563dd5d25SJonas Devlieghere 47663dd5d25SJonas Devlieghere void Cancel() override {} 47763dd5d25SJonas Devlieghere 47863dd5d25SJonas Devlieghere bool Interrupt() override { return m_python->Interrupt(); } 47963dd5d25SJonas Devlieghere 48063dd5d25SJonas Devlieghere void GotEOF() override {} 48163dd5d25SJonas Devlieghere 48263dd5d25SJonas Devlieghere protected: 48363dd5d25SJonas Devlieghere ScriptInterpreterPythonImpl *m_python; 48463dd5d25SJonas Devlieghere }; 48563dd5d25SJonas Devlieghere 48663dd5d25SJonas Devlieghere } // namespace lldb_private 48763dd5d25SJonas Devlieghere 4881f6a57c1SMed Ismail Bennani #endif // LLDB_ENABLE_PYTHON 4891f6a57c1SMed Ismail Bennani #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 490