10b57cec5SDimitry Andric //===-- ScriptInterpreterPythonImpl.h ---------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 9fe6060f1SDimitry Andric #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 10fe6060f1SDimitry Andric #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 11fe6060f1SDimitry Andric 12480093f4SDimitry Andric #include "lldb/Host/Config.h" 130b57cec5SDimitry Andric 14480093f4SDimitry Andric #if LLDB_ENABLE_PYTHON 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "lldb-python.h" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "PythonDataObjects.h" 190b57cec5SDimitry Andric #include "ScriptInterpreterPython.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric #include "lldb/Host/Terminal.h" 220b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h" 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 250b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric namespace lldb_private { 280b57cec5SDimitry Andric class IOHandlerPythonInterpreter; 290b57cec5SDimitry Andric class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { 300b57cec5SDimitry Andric public: 310b57cec5SDimitry Andric friend class IOHandlerPythonInterpreter; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric ScriptInterpreterPythonImpl(Debugger &debugger); 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric ~ScriptInterpreterPythonImpl() override; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric bool Interrupt() override; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric bool ExecuteOneLine( 400b57cec5SDimitry Andric llvm::StringRef command, CommandReturnObject *result, 410b57cec5SDimitry Andric const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric void ExecuteInterpreterLoop() override; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric bool ExecuteOneLineWithReturn( 460b57cec5SDimitry Andric llvm::StringRef in_string, 470b57cec5SDimitry Andric ScriptInterpreter::ScriptReturnType return_type, void *ret_value, 480b57cec5SDimitry Andric const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric lldb_private::Status ExecuteMultipleLines( 510b57cec5SDimitry Andric const char *in_string, 520b57cec5SDimitry Andric const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric Status 550b57cec5SDimitry Andric ExportFunctionDefinitionToInterpreter(StringList &function_def) override; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric bool GenerateTypeScriptFunction(StringList &input, std::string &output, 580b57cec5SDimitry Andric const void *name_token = nullptr) override; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric bool GenerateTypeSynthClass(StringList &input, std::string &output, 610b57cec5SDimitry Andric const void *name_token = nullptr) override; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric bool GenerateTypeSynthClass(const char *oneliner, std::string &output, 640b57cec5SDimitry Andric const void *name_token = nullptr) override; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric // use this if the function code is just a one-liner script 670b57cec5SDimitry Andric bool GenerateTypeScriptFunction(const char *oneliner, std::string &output, 680b57cec5SDimitry Andric const void *name_token = nullptr) override; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric bool GenerateScriptAliasFunction(StringList &input, 710b57cec5SDimitry Andric std::string &output) override; 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric StructuredData::ObjectSP 740b57cec5SDimitry Andric CreateSyntheticScriptedProvider(const char *class_name, 750b57cec5SDimitry Andric lldb::ValueObjectSP valobj) override; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric StructuredData::GenericSP 780b57cec5SDimitry Andric CreateScriptCommandObject(const char *class_name) override; 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric StructuredData::ObjectSP 810b57cec5SDimitry Andric CreateScriptedThreadPlan(const char *class_name, 820eae32dcSDimitry Andric const StructuredDataImpl &args_data, 839dba64beSDimitry Andric std::string &error_str, 840b57cec5SDimitry Andric lldb::ThreadPlanSP thread_plan) override; 850b57cec5SDimitry Andric 86*fe013be4SDimitry Andric StructuredData::ObjectSP 87*fe013be4SDimitry Andric CreateStructuredDataFromScriptObject(ScriptObject obj) override; 88*fe013be4SDimitry Andric 890b57cec5SDimitry Andric bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, 900b57cec5SDimitry Andric Event *event, 910b57cec5SDimitry Andric bool &script_error) override; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, 940b57cec5SDimitry Andric Event *event, bool &script_error) override; 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp, 970b57cec5SDimitry Andric bool &script_error) override; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric lldb::StateType 1000b57cec5SDimitry Andric ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, 1010b57cec5SDimitry Andric bool &script_error) override; 1020b57cec5SDimitry Andric 103*fe013be4SDimitry Andric bool 104*fe013be4SDimitry Andric ScriptedThreadPlanGetStopDescription(StructuredData::ObjectSP implementor_sp, 105*fe013be4SDimitry Andric lldb_private::Stream *s, 106*fe013be4SDimitry Andric bool &script_error) override; 107*fe013be4SDimitry Andric 1080b57cec5SDimitry Andric StructuredData::GenericSP 1090b57cec5SDimitry Andric CreateScriptedBreakpointResolver(const char *class_name, 1100eae32dcSDimitry Andric const StructuredDataImpl &args_data, 1110b57cec5SDimitry Andric lldb::BreakpointSP &bkpt_sp) override; 1120b57cec5SDimitry Andric bool ScriptedBreakpointResolverSearchCallback( 1130b57cec5SDimitry Andric StructuredData::GenericSP implementor_sp, 1140b57cec5SDimitry Andric SymbolContext *sym_ctx) override; 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric lldb::SearchDepth ScriptedBreakpointResolverSearchDepth( 1170b57cec5SDimitry Andric StructuredData::GenericSP implementor_sp) override; 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric StructuredData::GenericSP 120e8d8bef9SDimitry Andric CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, 1210eae32dcSDimitry Andric const StructuredDataImpl &args_data, 1220eae32dcSDimitry Andric Status &error) override; 123e8d8bef9SDimitry Andric 124e8d8bef9SDimitry Andric bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp, 125e8d8bef9SDimitry Andric ExecutionContext &exc_ctx, 126e8d8bef9SDimitry Andric lldb::StreamSP stream_sp) override; 127e8d8bef9SDimitry Andric 128e8d8bef9SDimitry Andric StructuredData::GenericSP 1290b57cec5SDimitry Andric CreateFrameRecognizer(const char *class_name) override; 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric lldb::ValueObjectListSP 1320b57cec5SDimitry Andric GetRecognizedArguments(const StructuredData::ObjectSP &implementor, 1330b57cec5SDimitry Andric lldb::StackFrameSP frame_sp) override; 1340b57cec5SDimitry Andric 135*fe013be4SDimitry Andric lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override; 136*fe013be4SDimitry Andric 1370b57cec5SDimitry Andric StructuredData::GenericSP 1380b57cec5SDimitry Andric OSPlugin_CreatePluginObject(const char *class_name, 1390b57cec5SDimitry Andric lldb::ProcessSP process_sp) override; 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric StructuredData::DictionarySP 1420b57cec5SDimitry Andric OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric StructuredData::ArraySP 1450b57cec5SDimitry Andric OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric StructuredData::StringSP 1480b57cec5SDimitry Andric OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, 1490b57cec5SDimitry Andric lldb::tid_t thread_id) override; 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric StructuredData::DictionarySP 1520b57cec5SDimitry Andric OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, 1530b57cec5SDimitry Andric lldb::tid_t tid, lldb::addr_t context) override; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric StructuredData::ObjectSP 1560b57cec5SDimitry Andric LoadPluginModule(const FileSpec &file_spec, 1570b57cec5SDimitry Andric lldb_private::Status &error) override; 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric StructuredData::DictionarySP 1600b57cec5SDimitry Andric GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, 1610b57cec5SDimitry Andric const char *setting_name, 1620b57cec5SDimitry Andric lldb_private::Status &error) override; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, 1650b57cec5SDimitry Andric uint32_t max) override; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric lldb::ValueObjectSP 1680b57cec5SDimitry Andric GetChildAtIndex(const StructuredData::ObjectSP &implementor, 1690b57cec5SDimitry Andric uint32_t idx) override; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, 1720b57cec5SDimitry Andric const char *child_name) override; 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric bool UpdateSynthProviderInstance( 1750b57cec5SDimitry Andric const StructuredData::ObjectSP &implementor) override; 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric bool MightHaveChildrenSynthProviderInstance( 1780b57cec5SDimitry Andric const StructuredData::ObjectSP &implementor) override; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric lldb::ValueObjectSP 1810b57cec5SDimitry Andric GetSyntheticValue(const StructuredData::ObjectSP &implementor) override; 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric ConstString 1840b57cec5SDimitry Andric GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric bool 1870b57cec5SDimitry Andric RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, 1880b57cec5SDimitry Andric ScriptedCommandSynchronicity synchronicity, 1890b57cec5SDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, 1900b57cec5SDimitry Andric Status &error, 1910b57cec5SDimitry Andric const lldb_private::ExecutionContext &exe_ctx) override; 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric bool RunScriptBasedCommand( 1940b57cec5SDimitry Andric StructuredData::GenericSP impl_obj_sp, llvm::StringRef args, 1950b57cec5SDimitry Andric ScriptedCommandSynchronicity synchronicity, 1960b57cec5SDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, Status &error, 1970b57cec5SDimitry Andric const lldb_private::ExecutionContext &exe_ctx) override; 1980b57cec5SDimitry Andric 199*fe013be4SDimitry Andric Status GenerateFunction(const char *signature, const StringList &input, 200*fe013be4SDimitry Andric bool is_callback) override; 2010b57cec5SDimitry Andric 202*fe013be4SDimitry Andric Status GenerateBreakpointCommandCallbackData(StringList &input, 203480093f4SDimitry Andric std::string &output, 204*fe013be4SDimitry Andric bool has_extra_args, 205*fe013be4SDimitry Andric bool is_callback) override; 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric bool GenerateWatchpointCommandCallbackData(StringList &input, 208*fe013be4SDimitry Andric std::string &output, 209*fe013be4SDimitry Andric bool is_callback) override; 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, 2120b57cec5SDimitry Andric StructuredData::ObjectSP &callee_wrapper_sp, 2130b57cec5SDimitry Andric const TypeSummaryOptions &options, 2140b57cec5SDimitry Andric std::string &retval) override; 2150b57cec5SDimitry Andric 216bdd1243dSDimitry Andric bool FormatterCallbackFunction(const char *function_name, 217bdd1243dSDimitry Andric lldb::TypeImplSP type_impl_sp) override; 218bdd1243dSDimitry Andric 2190b57cec5SDimitry Andric bool GetDocumentationForItem(const char *item, std::string &dest) override; 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 2220b57cec5SDimitry Andric std::string &dest) override; 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric uint32_t 2250b57cec5SDimitry Andric GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override; 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 2280b57cec5SDimitry Andric std::string &dest) override; 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric bool CheckObjectExists(const char *name) override { 2310b57cec5SDimitry Andric if (!name || !name[0]) 2320b57cec5SDimitry Andric return false; 2330b57cec5SDimitry Andric std::string temp; 2340b57cec5SDimitry Andric return GetDocumentationForItem(name, temp); 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, Process *process, 2380b57cec5SDimitry Andric std::string &output, Status &error) override; 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, Thread *thread, 2410b57cec5SDimitry Andric std::string &output, Status &error) override; 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, Target *target, 2440b57cec5SDimitry Andric std::string &output, Status &error) override; 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame, 2470b57cec5SDimitry Andric std::string &output, Status &error) override; 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value, 2500b57cec5SDimitry Andric std::string &output, Status &error) override; 2510b57cec5SDimitry Andric 252fe6060f1SDimitry Andric bool LoadScriptingModule(const char *filename, 253fe6060f1SDimitry Andric const LoadScriptOptions &options, 2540b57cec5SDimitry Andric lldb_private::Status &error, 255e8d8bef9SDimitry Andric StructuredData::ObjectSP *module_sp = nullptr, 256e8d8bef9SDimitry Andric FileSpec extra_search_dir = {}) override; 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric bool IsReservedWord(const char *word) override; 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric void CollectDataForBreakpointCommandCallback( 263fe6060f1SDimitry Andric std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, 2640b57cec5SDimitry Andric CommandReturnObject &result) override; 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric void 2670b57cec5SDimitry Andric CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, 2680b57cec5SDimitry Andric CommandReturnObject &result) override; 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric /// Set the callback body text into the callback for the breakpoint. 271fe6060f1SDimitry Andric Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 272*fe013be4SDimitry Andric const char *callback_body, 273*fe013be4SDimitry Andric bool is_callback) override; 2740b57cec5SDimitry Andric 275480093f4SDimitry Andric Status SetBreakpointCommandCallbackFunction( 276fe6060f1SDimitry Andric BreakpointOptions &bp_options, const char *function_name, 277480093f4SDimitry Andric StructuredData::ObjectSP extra_args_sp) override; 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric /// This one is for deserialization: 2800b57cec5SDimitry Andric Status SetBreakpointCommandCallback( 281fe6060f1SDimitry Andric BreakpointOptions &bp_options, 2820b57cec5SDimitry Andric std::unique_ptr<BreakpointOptions::CommandData> &data_up) override; 2830b57cec5SDimitry Andric 284fe6060f1SDimitry Andric Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 285480093f4SDimitry Andric const char *command_body_text, 286480093f4SDimitry Andric StructuredData::ObjectSP extra_args_sp, 287*fe013be4SDimitry Andric bool uses_extra_args, 288*fe013be4SDimitry Andric bool is_callback); 289480093f4SDimitry Andric 2900b57cec5SDimitry Andric /// Set a one-liner as the callback for the watchpoint. 2910b57cec5SDimitry Andric void SetWatchpointCommandCallback(WatchpointOptions *wp_options, 292*fe013be4SDimitry Andric const char *user_input, 293*fe013be4SDimitry Andric bool is_callback) override; 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric const char *GetDictionaryName() { return m_dictionary_name.c_str(); } 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric PyThreadState *GetThreadState() { return m_command_thread_state; } 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric void SetThreadState(PyThreadState *s) { 3000b57cec5SDimitry Andric if (s) 3010b57cec5SDimitry Andric m_command_thread_state = s; 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric // IOHandlerDelegate 3050b57cec5SDimitry Andric void IOHandlerActivated(IOHandler &io_handler, bool interactive) override; 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric void IOHandlerInputComplete(IOHandler &io_handler, 3080b57cec5SDimitry Andric std::string &data) override; 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger); 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric // PluginInterface protocol 313349cc55cSDimitry Andric llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric class Locker : public ScriptInterpreterLocker { 3160b57cec5SDimitry Andric public: 3170b57cec5SDimitry Andric enum OnEntry { 3180b57cec5SDimitry Andric AcquireLock = 0x0001, 3190b57cec5SDimitry Andric InitSession = 0x0002, 3200b57cec5SDimitry Andric InitGlobals = 0x0004, 3210b57cec5SDimitry Andric NoSTDIN = 0x0008 3220b57cec5SDimitry Andric }; 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric enum OnLeave { 3250b57cec5SDimitry Andric FreeLock = 0x0001, 3260b57cec5SDimitry Andric FreeAcquiredLock = 0x0002, // do not free the lock if we already held it 3270b57cec5SDimitry Andric // when calling constructor 3280b57cec5SDimitry Andric TearDownSession = 0x0004 3290b57cec5SDimitry Andric }; 3300b57cec5SDimitry Andric 3319dba64beSDimitry Andric Locker(ScriptInterpreterPythonImpl *py_interpreter, 3320b57cec5SDimitry Andric uint16_t on_entry = AcquireLock | InitSession, 3339dba64beSDimitry Andric uint16_t on_leave = FreeLock | TearDownSession, 3349dba64beSDimitry Andric lldb::FileSP in = nullptr, lldb::FileSP out = nullptr, 3359dba64beSDimitry Andric lldb::FileSP err = nullptr); 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric ~Locker() override; 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric private: 3400b57cec5SDimitry Andric bool DoAcquireLock(); 3410b57cec5SDimitry Andric 3429dba64beSDimitry Andric bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in, 3439dba64beSDimitry Andric lldb::FileSP out, lldb::FileSP err); 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric bool DoFreeLock(); 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric bool DoTearDownSession(); 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric bool m_teardown_session; 3500b57cec5SDimitry Andric ScriptInterpreterPythonImpl *m_python_interpreter; 3510b57cec5SDimitry Andric PyGILState_STATE m_GILState; 3520b57cec5SDimitry Andric }; 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric static bool BreakpointCallbackFunction(void *baton, 3550b57cec5SDimitry Andric StoppointCallbackContext *context, 3560b57cec5SDimitry Andric lldb::user_id_t break_id, 3570b57cec5SDimitry Andric lldb::user_id_t break_loc_id); 3580b57cec5SDimitry Andric static bool WatchpointCallbackFunction(void *baton, 3590b57cec5SDimitry Andric StoppointCallbackContext *context, 3600b57cec5SDimitry Andric lldb::user_id_t watch_id); 36104eeddc0SDimitry Andric static void Initialize(); 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric class SynchronicityHandler { 3640b57cec5SDimitry Andric private: 3650b57cec5SDimitry Andric lldb::DebuggerSP m_debugger_sp; 3660b57cec5SDimitry Andric ScriptedCommandSynchronicity m_synch_wanted; 3670b57cec5SDimitry Andric bool m_old_asynch; 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric public: 3700b57cec5SDimitry Andric SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity); 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric ~SynchronicityHandler(); 3730b57cec5SDimitry Andric }; 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric enum class AddLocation { Beginning, End }; 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric static void AddToSysPath(AddLocation location, std::string path); 3780b57cec5SDimitry Andric 3799dba64beSDimitry Andric bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, 3809dba64beSDimitry Andric lldb::FileSP err); 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric void LeaveSession(); 3830b57cec5SDimitry Andric 384*fe013be4SDimitry Andric uint32_t IsExecutingPython() { 385*fe013be4SDimitry Andric std::lock_guard<std::mutex> guard(m_mutex); 386*fe013be4SDimitry Andric return m_lock_count > 0; 387*fe013be4SDimitry Andric } 3880b57cec5SDimitry Andric 389*fe013be4SDimitry Andric uint32_t IncrementLockCount() { 390*fe013be4SDimitry Andric std::lock_guard<std::mutex> guard(m_mutex); 391*fe013be4SDimitry Andric return ++m_lock_count; 392*fe013be4SDimitry Andric } 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric uint32_t DecrementLockCount() { 395*fe013be4SDimitry Andric std::lock_guard<std::mutex> guard(m_mutex); 3960b57cec5SDimitry Andric if (m_lock_count > 0) 3970b57cec5SDimitry Andric --m_lock_count; 3980b57cec5SDimitry Andric return m_lock_count; 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric enum ActiveIOHandler { 4020b57cec5SDimitry Andric eIOHandlerNone, 4030b57cec5SDimitry Andric eIOHandlerBreakpoint, 4040b57cec5SDimitry Andric eIOHandlerWatchpoint 4050b57cec5SDimitry Andric }; 4060b57cec5SDimitry Andric 4079dba64beSDimitry Andric python::PythonModule &GetMainModule(); 4080b57cec5SDimitry Andric 4099dba64beSDimitry Andric python::PythonDictionary &GetSessionDictionary(); 4100b57cec5SDimitry Andric 4119dba64beSDimitry Andric python::PythonDictionary &GetSysModuleDictionary(); 4120b57cec5SDimitry Andric 413480093f4SDimitry Andric llvm::Expected<unsigned> GetMaxPositionalArgumentsForCallable( 414480093f4SDimitry Andric const llvm::StringRef &callable_name) override; 415480093f4SDimitry Andric 4160b57cec5SDimitry Andric bool GetEmbeddedInterpreterModuleObjects(); 4170b57cec5SDimitry Andric 4189dba64beSDimitry Andric bool SetStdHandle(lldb::FileSP file, const char *py_name, 4199dba64beSDimitry Andric python::PythonObject &save_file, const char *mode); 4200b57cec5SDimitry Andric 4219dba64beSDimitry Andric python::PythonObject m_saved_stdin; 4229dba64beSDimitry Andric python::PythonObject m_saved_stdout; 4239dba64beSDimitry Andric python::PythonObject m_saved_stderr; 4249dba64beSDimitry Andric python::PythonModule m_main_module; 4259dba64beSDimitry Andric python::PythonDictionary m_session_dict; 4269dba64beSDimitry Andric python::PythonDictionary m_sys_module_dict; 4279dba64beSDimitry Andric python::PythonObject m_run_one_line_function; 4289dba64beSDimitry Andric python::PythonObject m_run_one_line_str_global; 4290b57cec5SDimitry Andric std::string m_dictionary_name; 4300b57cec5SDimitry Andric ActiveIOHandler m_active_io_handler; 4310b57cec5SDimitry Andric bool m_session_is_active; 4325ffd83dbSDimitry Andric bool m_pty_secondary_is_open; 4330b57cec5SDimitry Andric bool m_valid_session; 4340b57cec5SDimitry Andric uint32_t m_lock_count; 435*fe013be4SDimitry Andric std::mutex m_mutex; 4360b57cec5SDimitry Andric PyThreadState *m_command_thread_state; 4370b57cec5SDimitry Andric }; 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric class IOHandlerPythonInterpreter : public IOHandler { 4400b57cec5SDimitry Andric public: 4410b57cec5SDimitry Andric IOHandlerPythonInterpreter(Debugger &debugger, 4420b57cec5SDimitry Andric ScriptInterpreterPythonImpl *python) 4430b57cec5SDimitry Andric : IOHandler(debugger, IOHandler::Type::PythonInterpreter), 4440b57cec5SDimitry Andric m_python(python) {} 4450b57cec5SDimitry Andric 446fe6060f1SDimitry Andric ~IOHandlerPythonInterpreter() override = default; 4470b57cec5SDimitry Andric 448*fe013be4SDimitry Andric llvm::StringRef GetControlSequence(char ch) override { 449*fe013be4SDimitry Andric static constexpr llvm::StringLiteral control_sequence("quit()\n"); 4500b57cec5SDimitry Andric if (ch == 'd') 451*fe013be4SDimitry Andric return control_sequence; 452*fe013be4SDimitry Andric return {}; 4530b57cec5SDimitry Andric } 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric void Run() override { 4560b57cec5SDimitry Andric if (m_python) { 4570b57cec5SDimitry Andric int stdin_fd = GetInputFD(); 4580b57cec5SDimitry Andric if (stdin_fd >= 0) { 4590b57cec5SDimitry Andric Terminal terminal(stdin_fd); 460349cc55cSDimitry Andric TerminalState terminal_state(terminal); 4610b57cec5SDimitry Andric 462349cc55cSDimitry Andric if (terminal.IsATerminal()) { 463349cc55cSDimitry Andric // FIXME: error handling? 464349cc55cSDimitry Andric llvm::consumeError(terminal.SetCanonical(false)); 465349cc55cSDimitry Andric llvm::consumeError(terminal.SetEcho(true)); 4660b57cec5SDimitry Andric } 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker locker( 4690b57cec5SDimitry Andric m_python, 4700b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker::AcquireLock | 4710b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker::InitSession | 4720b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker::InitGlobals, 4730b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock | 4740b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker::TearDownSession); 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric // The following call drops into the embedded interpreter loop and 4770b57cec5SDimitry Andric // stays there until the user chooses to exit from the Python 4780b57cec5SDimitry Andric // interpreter. This embedded interpreter will, as any Python code that 4790b57cec5SDimitry Andric // performs I/O, unlock the GIL before a system call that can hang, and 4800b57cec5SDimitry Andric // lock it when the syscall has returned. 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric // We need to surround the call to the embedded interpreter with calls 4830b57cec5SDimitry Andric // to PyGILState_Ensure and PyGILState_Release (using the Locker 4840b57cec5SDimitry Andric // above). This is because Python has a global lock which must be held 4850b57cec5SDimitry Andric // whenever we want to touch any Python objects. Otherwise, if the user 4860b57cec5SDimitry Andric // calls Python code, the interpreter state will be off, and things 4870b57cec5SDimitry Andric // could hang (it's happened before). 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric StreamString run_string; 4900b57cec5SDimitry Andric run_string.Printf("run_python_interpreter (%s)", 4910b57cec5SDimitry Andric m_python->GetDictionaryName()); 4920b57cec5SDimitry Andric PyRun_SimpleString(run_string.GetData()); 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric SetIsDone(true); 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric void Cancel() override {} 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric bool Interrupt() override { return m_python->Interrupt(); } 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric void GotEOF() override {} 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric protected: 5050b57cec5SDimitry Andric ScriptInterpreterPythonImpl *m_python; 5060b57cec5SDimitry Andric }; 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric } // namespace lldb_private 5090b57cec5SDimitry Andric 510fe6060f1SDimitry Andric #endif // LLDB_ENABLE_PYTHON 511fe6060f1SDimitry Andric #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 512