1*0b57cec5SDimitry Andric //===-- ScriptInterpreterPythonImpl.h ---------------------------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry 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" 13*0b57cec5SDimitry Andric 14480093f4SDimitry Andric #if LLDB_ENABLE_PYTHON 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "lldb-python.h" 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andric #include "PythonDataObjects.h" 19*0b57cec5SDimitry Andric #include "ScriptInterpreterPython.h" 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andric #include "lldb/Host/Terminal.h" 22*0b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h" 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 25*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric namespace lldb_private { 28*0b57cec5SDimitry Andric class IOHandlerPythonInterpreter; 29*0b57cec5SDimitry Andric class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { 30*0b57cec5SDimitry Andric public: 31*0b57cec5SDimitry Andric friend class IOHandlerPythonInterpreter; 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andric ScriptInterpreterPythonImpl(Debugger &debugger); 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andric ~ScriptInterpreterPythonImpl() override; 36*0b57cec5SDimitry Andric 37*0b57cec5SDimitry Andric bool Interrupt() override; 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric bool ExecuteOneLine( 40*0b57cec5SDimitry Andric llvm::StringRef command, CommandReturnObject *result, 41*0b57cec5SDimitry Andric const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric void ExecuteInterpreterLoop() override; 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric bool ExecuteOneLineWithReturn( 46*0b57cec5SDimitry Andric llvm::StringRef in_string, 47*0b57cec5SDimitry Andric ScriptInterpreter::ScriptReturnType return_type, void *ret_value, 48*0b57cec5SDimitry Andric const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 49*0b57cec5SDimitry Andric 50*0b57cec5SDimitry Andric lldb_private::Status ExecuteMultipleLines( 51*0b57cec5SDimitry Andric const char *in_string, 52*0b57cec5SDimitry Andric const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric Status 55*0b57cec5SDimitry Andric ExportFunctionDefinitionToInterpreter(StringList &function_def) override; 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric bool GenerateTypeScriptFunction(StringList &input, std::string &output, 58*0b57cec5SDimitry Andric const void *name_token = nullptr) override; 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric bool GenerateTypeSynthClass(StringList &input, std::string &output, 61*0b57cec5SDimitry Andric const void *name_token = nullptr) override; 62*0b57cec5SDimitry Andric 63*0b57cec5SDimitry Andric bool GenerateTypeSynthClass(const char *oneliner, std::string &output, 64*0b57cec5SDimitry Andric const void *name_token = nullptr) override; 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric // use this if the function code is just a one-liner script 67*0b57cec5SDimitry Andric bool GenerateTypeScriptFunction(const char *oneliner, std::string &output, 68*0b57cec5SDimitry Andric const void *name_token = nullptr) override; 69*0b57cec5SDimitry Andric 70*0b57cec5SDimitry Andric bool GenerateScriptAliasFunction(StringList &input, 71*0b57cec5SDimitry Andric std::string &output) override; 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andric StructuredData::ObjectSP 74*0b57cec5SDimitry Andric CreateSyntheticScriptedProvider(const char *class_name, 75*0b57cec5SDimitry Andric lldb::ValueObjectSP valobj) override; 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric StructuredData::GenericSP 78*0b57cec5SDimitry Andric CreateScriptCommandObject(const char *class_name) override; 79*0b57cec5SDimitry Andric 80*0b57cec5SDimitry Andric StructuredData::ObjectSP 81*0b57cec5SDimitry Andric CreateScriptedThreadPlan(const char *class_name, 829dba64beSDimitry Andric StructuredDataImpl *args_data, 839dba64beSDimitry Andric std::string &error_str, 84*0b57cec5SDimitry Andric lldb::ThreadPlanSP thread_plan) override; 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andric bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, 87*0b57cec5SDimitry Andric Event *event, 88*0b57cec5SDimitry Andric bool &script_error) override; 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, 91*0b57cec5SDimitry Andric Event *event, bool &script_error) override; 92*0b57cec5SDimitry Andric 93*0b57cec5SDimitry Andric bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp, 94*0b57cec5SDimitry Andric bool &script_error) override; 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andric lldb::StateType 97*0b57cec5SDimitry Andric ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, 98*0b57cec5SDimitry Andric bool &script_error) override; 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric StructuredData::GenericSP 101*0b57cec5SDimitry Andric CreateScriptedBreakpointResolver(const char *class_name, 102*0b57cec5SDimitry Andric StructuredDataImpl *args_data, 103*0b57cec5SDimitry Andric lldb::BreakpointSP &bkpt_sp) override; 104*0b57cec5SDimitry Andric bool ScriptedBreakpointResolverSearchCallback( 105*0b57cec5SDimitry Andric StructuredData::GenericSP implementor_sp, 106*0b57cec5SDimitry Andric SymbolContext *sym_ctx) override; 107*0b57cec5SDimitry Andric 108*0b57cec5SDimitry Andric lldb::SearchDepth ScriptedBreakpointResolverSearchDepth( 109*0b57cec5SDimitry Andric StructuredData::GenericSP implementor_sp) override; 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric StructuredData::GenericSP 112e8d8bef9SDimitry Andric CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, 113e8d8bef9SDimitry Andric StructuredDataImpl *args_data, Status &error) override; 114e8d8bef9SDimitry Andric 115e8d8bef9SDimitry Andric bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp, 116e8d8bef9SDimitry Andric ExecutionContext &exc_ctx, 117e8d8bef9SDimitry Andric lldb::StreamSP stream_sp) override; 118e8d8bef9SDimitry Andric 119e8d8bef9SDimitry Andric StructuredData::GenericSP 120*0b57cec5SDimitry Andric CreateFrameRecognizer(const char *class_name) override; 121*0b57cec5SDimitry Andric 122*0b57cec5SDimitry Andric lldb::ValueObjectListSP 123*0b57cec5SDimitry Andric GetRecognizedArguments(const StructuredData::ObjectSP &implementor, 124*0b57cec5SDimitry Andric lldb::StackFrameSP frame_sp) override; 125*0b57cec5SDimitry Andric 126*0b57cec5SDimitry Andric StructuredData::GenericSP 127*0b57cec5SDimitry Andric OSPlugin_CreatePluginObject(const char *class_name, 128*0b57cec5SDimitry Andric lldb::ProcessSP process_sp) override; 129*0b57cec5SDimitry Andric 130*0b57cec5SDimitry Andric StructuredData::DictionarySP 131*0b57cec5SDimitry Andric OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 132*0b57cec5SDimitry Andric 133*0b57cec5SDimitry Andric StructuredData::ArraySP 134*0b57cec5SDimitry Andric OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric StructuredData::StringSP 137*0b57cec5SDimitry Andric OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, 138*0b57cec5SDimitry Andric lldb::tid_t thread_id) override; 139*0b57cec5SDimitry Andric 140*0b57cec5SDimitry Andric StructuredData::DictionarySP 141*0b57cec5SDimitry Andric OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, 142*0b57cec5SDimitry Andric lldb::tid_t tid, lldb::addr_t context) override; 143*0b57cec5SDimitry Andric 144*0b57cec5SDimitry Andric StructuredData::ObjectSP 145*0b57cec5SDimitry Andric LoadPluginModule(const FileSpec &file_spec, 146*0b57cec5SDimitry Andric lldb_private::Status &error) override; 147*0b57cec5SDimitry Andric 148*0b57cec5SDimitry Andric StructuredData::DictionarySP 149*0b57cec5SDimitry Andric GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, 150*0b57cec5SDimitry Andric const char *setting_name, 151*0b57cec5SDimitry Andric lldb_private::Status &error) override; 152*0b57cec5SDimitry Andric 153*0b57cec5SDimitry Andric size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, 154*0b57cec5SDimitry Andric uint32_t max) override; 155*0b57cec5SDimitry Andric 156*0b57cec5SDimitry Andric lldb::ValueObjectSP 157*0b57cec5SDimitry Andric GetChildAtIndex(const StructuredData::ObjectSP &implementor, 158*0b57cec5SDimitry Andric uint32_t idx) override; 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andric int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, 161*0b57cec5SDimitry Andric const char *child_name) override; 162*0b57cec5SDimitry Andric 163*0b57cec5SDimitry Andric bool UpdateSynthProviderInstance( 164*0b57cec5SDimitry Andric const StructuredData::ObjectSP &implementor) override; 165*0b57cec5SDimitry Andric 166*0b57cec5SDimitry Andric bool MightHaveChildrenSynthProviderInstance( 167*0b57cec5SDimitry Andric const StructuredData::ObjectSP &implementor) override; 168*0b57cec5SDimitry Andric 169*0b57cec5SDimitry Andric lldb::ValueObjectSP 170*0b57cec5SDimitry Andric GetSyntheticValue(const StructuredData::ObjectSP &implementor) override; 171*0b57cec5SDimitry Andric 172*0b57cec5SDimitry Andric ConstString 173*0b57cec5SDimitry Andric GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override; 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric bool 176*0b57cec5SDimitry Andric RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, 177*0b57cec5SDimitry Andric ScriptedCommandSynchronicity synchronicity, 178*0b57cec5SDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, 179*0b57cec5SDimitry Andric Status &error, 180*0b57cec5SDimitry Andric const lldb_private::ExecutionContext &exe_ctx) override; 181*0b57cec5SDimitry Andric 182*0b57cec5SDimitry Andric bool RunScriptBasedCommand( 183*0b57cec5SDimitry Andric StructuredData::GenericSP impl_obj_sp, llvm::StringRef args, 184*0b57cec5SDimitry Andric ScriptedCommandSynchronicity synchronicity, 185*0b57cec5SDimitry Andric lldb_private::CommandReturnObject &cmd_retobj, Status &error, 186*0b57cec5SDimitry Andric const lldb_private::ExecutionContext &exe_ctx) override; 187*0b57cec5SDimitry Andric 188*0b57cec5SDimitry Andric Status GenerateFunction(const char *signature, 189*0b57cec5SDimitry Andric const StringList &input) override; 190*0b57cec5SDimitry Andric 191480093f4SDimitry Andric Status GenerateBreakpointCommandCallbackData( 192480093f4SDimitry Andric StringList &input, 193480093f4SDimitry Andric std::string &output, 194480093f4SDimitry Andric bool has_extra_args) override; 195*0b57cec5SDimitry Andric 196*0b57cec5SDimitry Andric bool GenerateWatchpointCommandCallbackData(StringList &input, 197*0b57cec5SDimitry Andric std::string &output) override; 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andric bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, 200*0b57cec5SDimitry Andric StructuredData::ObjectSP &callee_wrapper_sp, 201*0b57cec5SDimitry Andric const TypeSummaryOptions &options, 202*0b57cec5SDimitry Andric std::string &retval) override; 203*0b57cec5SDimitry Andric 204*0b57cec5SDimitry Andric bool GetDocumentationForItem(const char *item, std::string &dest) override; 205*0b57cec5SDimitry Andric 206*0b57cec5SDimitry Andric bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 207*0b57cec5SDimitry Andric std::string &dest) override; 208*0b57cec5SDimitry Andric 209*0b57cec5SDimitry Andric uint32_t 210*0b57cec5SDimitry Andric GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override; 211*0b57cec5SDimitry Andric 212*0b57cec5SDimitry Andric bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 213*0b57cec5SDimitry Andric std::string &dest) override; 214*0b57cec5SDimitry Andric 215*0b57cec5SDimitry Andric bool CheckObjectExists(const char *name) override { 216*0b57cec5SDimitry Andric if (!name || !name[0]) 217*0b57cec5SDimitry Andric return false; 218*0b57cec5SDimitry Andric std::string temp; 219*0b57cec5SDimitry Andric return GetDocumentationForItem(name, temp); 220*0b57cec5SDimitry Andric } 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, Process *process, 223*0b57cec5SDimitry Andric std::string &output, Status &error) override; 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, Thread *thread, 226*0b57cec5SDimitry Andric std::string &output, Status &error) override; 227*0b57cec5SDimitry Andric 228*0b57cec5SDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, Target *target, 229*0b57cec5SDimitry Andric std::string &output, Status &error) override; 230*0b57cec5SDimitry Andric 231*0b57cec5SDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame, 232*0b57cec5SDimitry Andric std::string &output, Status &error) override; 233*0b57cec5SDimitry Andric 234*0b57cec5SDimitry Andric bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value, 235*0b57cec5SDimitry Andric std::string &output, Status &error) override; 236*0b57cec5SDimitry Andric 237fe6060f1SDimitry Andric bool LoadScriptingModule(const char *filename, 238fe6060f1SDimitry Andric const LoadScriptOptions &options, 239*0b57cec5SDimitry Andric lldb_private::Status &error, 240e8d8bef9SDimitry Andric StructuredData::ObjectSP *module_sp = nullptr, 241e8d8bef9SDimitry Andric FileSpec extra_search_dir = {}) override; 242*0b57cec5SDimitry Andric 243*0b57cec5SDimitry Andric bool IsReservedWord(const char *word) override; 244*0b57cec5SDimitry Andric 245*0b57cec5SDimitry Andric std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override; 246*0b57cec5SDimitry Andric 247*0b57cec5SDimitry Andric void CollectDataForBreakpointCommandCallback( 248fe6060f1SDimitry Andric std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, 249*0b57cec5SDimitry Andric CommandReturnObject &result) override; 250*0b57cec5SDimitry Andric 251*0b57cec5SDimitry Andric void 252*0b57cec5SDimitry Andric CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, 253*0b57cec5SDimitry Andric CommandReturnObject &result) override; 254*0b57cec5SDimitry Andric 255*0b57cec5SDimitry Andric /// Set the callback body text into the callback for the breakpoint. 256fe6060f1SDimitry Andric Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 257*0b57cec5SDimitry Andric const char *callback_body) override; 258*0b57cec5SDimitry Andric 259480093f4SDimitry Andric Status SetBreakpointCommandCallbackFunction( 260fe6060f1SDimitry Andric BreakpointOptions &bp_options, const char *function_name, 261480093f4SDimitry Andric StructuredData::ObjectSP extra_args_sp) override; 262*0b57cec5SDimitry Andric 263*0b57cec5SDimitry Andric /// This one is for deserialization: 264*0b57cec5SDimitry Andric Status SetBreakpointCommandCallback( 265fe6060f1SDimitry Andric BreakpointOptions &bp_options, 266*0b57cec5SDimitry Andric std::unique_ptr<BreakpointOptions::CommandData> &data_up) override; 267*0b57cec5SDimitry Andric 268fe6060f1SDimitry Andric Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 269480093f4SDimitry Andric const char *command_body_text, 270480093f4SDimitry Andric StructuredData::ObjectSP extra_args_sp, 271480093f4SDimitry Andric bool uses_extra_args); 272480093f4SDimitry Andric 273*0b57cec5SDimitry Andric /// Set a one-liner as the callback for the watchpoint. 274*0b57cec5SDimitry Andric void SetWatchpointCommandCallback(WatchpointOptions *wp_options, 275*0b57cec5SDimitry Andric const char *oneliner) override; 276*0b57cec5SDimitry Andric 277*0b57cec5SDimitry Andric const char *GetDictionaryName() { return m_dictionary_name.c_str(); } 278*0b57cec5SDimitry Andric 279*0b57cec5SDimitry Andric PyThreadState *GetThreadState() { return m_command_thread_state; } 280*0b57cec5SDimitry Andric 281*0b57cec5SDimitry Andric void SetThreadState(PyThreadState *s) { 282*0b57cec5SDimitry Andric if (s) 283*0b57cec5SDimitry Andric m_command_thread_state = s; 284*0b57cec5SDimitry Andric } 285*0b57cec5SDimitry Andric 286*0b57cec5SDimitry Andric // IOHandlerDelegate 287*0b57cec5SDimitry Andric void IOHandlerActivated(IOHandler &io_handler, bool interactive) override; 288*0b57cec5SDimitry Andric 289*0b57cec5SDimitry Andric void IOHandlerInputComplete(IOHandler &io_handler, 290*0b57cec5SDimitry Andric std::string &data) override; 291*0b57cec5SDimitry Andric 292*0b57cec5SDimitry Andric static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger); 293*0b57cec5SDimitry Andric 294*0b57cec5SDimitry Andric // PluginInterface protocol 295*0b57cec5SDimitry Andric lldb_private::ConstString GetPluginName() override; 296*0b57cec5SDimitry Andric 297*0b57cec5SDimitry Andric uint32_t GetPluginVersion() override; 298*0b57cec5SDimitry Andric 299*0b57cec5SDimitry Andric class Locker : public ScriptInterpreterLocker { 300*0b57cec5SDimitry Andric public: 301*0b57cec5SDimitry Andric enum OnEntry { 302*0b57cec5SDimitry Andric AcquireLock = 0x0001, 303*0b57cec5SDimitry Andric InitSession = 0x0002, 304*0b57cec5SDimitry Andric InitGlobals = 0x0004, 305*0b57cec5SDimitry Andric NoSTDIN = 0x0008 306*0b57cec5SDimitry Andric }; 307*0b57cec5SDimitry Andric 308*0b57cec5SDimitry Andric enum OnLeave { 309*0b57cec5SDimitry Andric FreeLock = 0x0001, 310*0b57cec5SDimitry Andric FreeAcquiredLock = 0x0002, // do not free the lock if we already held it 311*0b57cec5SDimitry Andric // when calling constructor 312*0b57cec5SDimitry Andric TearDownSession = 0x0004 313*0b57cec5SDimitry Andric }; 314*0b57cec5SDimitry Andric 3159dba64beSDimitry Andric Locker(ScriptInterpreterPythonImpl *py_interpreter, 316*0b57cec5SDimitry Andric uint16_t on_entry = AcquireLock | InitSession, 3179dba64beSDimitry Andric uint16_t on_leave = FreeLock | TearDownSession, 3189dba64beSDimitry Andric lldb::FileSP in = nullptr, lldb::FileSP out = nullptr, 3199dba64beSDimitry Andric lldb::FileSP err = nullptr); 320*0b57cec5SDimitry Andric 321*0b57cec5SDimitry Andric ~Locker() override; 322*0b57cec5SDimitry Andric 323*0b57cec5SDimitry Andric private: 324*0b57cec5SDimitry Andric bool DoAcquireLock(); 325*0b57cec5SDimitry Andric 3269dba64beSDimitry Andric bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in, 3279dba64beSDimitry Andric lldb::FileSP out, lldb::FileSP err); 328*0b57cec5SDimitry Andric 329*0b57cec5SDimitry Andric bool DoFreeLock(); 330*0b57cec5SDimitry Andric 331*0b57cec5SDimitry Andric bool DoTearDownSession(); 332*0b57cec5SDimitry Andric 333*0b57cec5SDimitry Andric bool m_teardown_session; 334*0b57cec5SDimitry Andric ScriptInterpreterPythonImpl *m_python_interpreter; 335*0b57cec5SDimitry Andric PyGILState_STATE m_GILState; 336*0b57cec5SDimitry Andric }; 337*0b57cec5SDimitry Andric 338*0b57cec5SDimitry Andric static bool BreakpointCallbackFunction(void *baton, 339*0b57cec5SDimitry Andric StoppointCallbackContext *context, 340*0b57cec5SDimitry Andric lldb::user_id_t break_id, 341*0b57cec5SDimitry Andric lldb::user_id_t break_loc_id); 342*0b57cec5SDimitry Andric static bool WatchpointCallbackFunction(void *baton, 343*0b57cec5SDimitry Andric StoppointCallbackContext *context, 344*0b57cec5SDimitry Andric lldb::user_id_t watch_id); 345*0b57cec5SDimitry Andric static void InitializePrivate(); 346*0b57cec5SDimitry Andric 347*0b57cec5SDimitry Andric class SynchronicityHandler { 348*0b57cec5SDimitry Andric private: 349*0b57cec5SDimitry Andric lldb::DebuggerSP m_debugger_sp; 350*0b57cec5SDimitry Andric ScriptedCommandSynchronicity m_synch_wanted; 351*0b57cec5SDimitry Andric bool m_old_asynch; 352*0b57cec5SDimitry Andric 353*0b57cec5SDimitry Andric public: 354*0b57cec5SDimitry Andric SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity); 355*0b57cec5SDimitry Andric 356*0b57cec5SDimitry Andric ~SynchronicityHandler(); 357*0b57cec5SDimitry Andric }; 358*0b57cec5SDimitry Andric 359*0b57cec5SDimitry Andric enum class AddLocation { Beginning, End }; 360*0b57cec5SDimitry Andric 361*0b57cec5SDimitry Andric static void AddToSysPath(AddLocation location, std::string path); 362*0b57cec5SDimitry Andric 3639dba64beSDimitry Andric bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, 3649dba64beSDimitry Andric lldb::FileSP err); 365*0b57cec5SDimitry Andric 366*0b57cec5SDimitry Andric void LeaveSession(); 367*0b57cec5SDimitry Andric 368*0b57cec5SDimitry Andric uint32_t IsExecutingPython() const { return m_lock_count > 0; } 369*0b57cec5SDimitry Andric 370*0b57cec5SDimitry Andric uint32_t IncrementLockCount() { return ++m_lock_count; } 371*0b57cec5SDimitry Andric 372*0b57cec5SDimitry Andric uint32_t DecrementLockCount() { 373*0b57cec5SDimitry Andric if (m_lock_count > 0) 374*0b57cec5SDimitry Andric --m_lock_count; 375*0b57cec5SDimitry Andric return m_lock_count; 376*0b57cec5SDimitry Andric } 377*0b57cec5SDimitry Andric 378*0b57cec5SDimitry Andric enum ActiveIOHandler { 379*0b57cec5SDimitry Andric eIOHandlerNone, 380*0b57cec5SDimitry Andric eIOHandlerBreakpoint, 381*0b57cec5SDimitry Andric eIOHandlerWatchpoint 382*0b57cec5SDimitry Andric }; 383*0b57cec5SDimitry Andric 3849dba64beSDimitry Andric python::PythonModule &GetMainModule(); 385*0b57cec5SDimitry Andric 3869dba64beSDimitry Andric python::PythonDictionary &GetSessionDictionary(); 387*0b57cec5SDimitry Andric 3889dba64beSDimitry Andric python::PythonDictionary &GetSysModuleDictionary(); 389*0b57cec5SDimitry Andric 390480093f4SDimitry Andric llvm::Expected<unsigned> GetMaxPositionalArgumentsForCallable( 391480093f4SDimitry Andric const llvm::StringRef &callable_name) override; 392480093f4SDimitry Andric 393*0b57cec5SDimitry Andric bool GetEmbeddedInterpreterModuleObjects(); 394*0b57cec5SDimitry Andric 3959dba64beSDimitry Andric bool SetStdHandle(lldb::FileSP file, const char *py_name, 3969dba64beSDimitry Andric python::PythonObject &save_file, const char *mode); 397*0b57cec5SDimitry Andric 3989dba64beSDimitry Andric python::PythonObject m_saved_stdin; 3999dba64beSDimitry Andric python::PythonObject m_saved_stdout; 4009dba64beSDimitry Andric python::PythonObject m_saved_stderr; 4019dba64beSDimitry Andric python::PythonModule m_main_module; 4029dba64beSDimitry Andric python::PythonDictionary m_session_dict; 4039dba64beSDimitry Andric python::PythonDictionary m_sys_module_dict; 4049dba64beSDimitry Andric python::PythonObject m_run_one_line_function; 4059dba64beSDimitry Andric python::PythonObject m_run_one_line_str_global; 406*0b57cec5SDimitry Andric std::string m_dictionary_name; 407*0b57cec5SDimitry Andric ActiveIOHandler m_active_io_handler; 408*0b57cec5SDimitry Andric bool m_session_is_active; 4095ffd83dbSDimitry Andric bool m_pty_secondary_is_open; 410*0b57cec5SDimitry Andric bool m_valid_session; 411*0b57cec5SDimitry Andric uint32_t m_lock_count; 412*0b57cec5SDimitry Andric PyThreadState *m_command_thread_state; 413*0b57cec5SDimitry Andric }; 414*0b57cec5SDimitry Andric 415*0b57cec5SDimitry Andric class IOHandlerPythonInterpreter : public IOHandler { 416*0b57cec5SDimitry Andric public: 417*0b57cec5SDimitry Andric IOHandlerPythonInterpreter(Debugger &debugger, 418*0b57cec5SDimitry Andric ScriptInterpreterPythonImpl *python) 419*0b57cec5SDimitry Andric : IOHandler(debugger, IOHandler::Type::PythonInterpreter), 420*0b57cec5SDimitry Andric m_python(python) {} 421*0b57cec5SDimitry Andric 422fe6060f1SDimitry Andric ~IOHandlerPythonInterpreter() override = default; 423*0b57cec5SDimitry Andric 424*0b57cec5SDimitry Andric ConstString GetControlSequence(char ch) override { 425*0b57cec5SDimitry Andric if (ch == 'd') 426*0b57cec5SDimitry Andric return ConstString("quit()\n"); 427*0b57cec5SDimitry Andric return ConstString(); 428*0b57cec5SDimitry Andric } 429*0b57cec5SDimitry Andric 430*0b57cec5SDimitry Andric void Run() override { 431*0b57cec5SDimitry Andric if (m_python) { 432*0b57cec5SDimitry Andric int stdin_fd = GetInputFD(); 433*0b57cec5SDimitry Andric if (stdin_fd >= 0) { 434*0b57cec5SDimitry Andric Terminal terminal(stdin_fd); 435*0b57cec5SDimitry Andric TerminalState terminal_state; 436*0b57cec5SDimitry Andric const bool is_a_tty = terminal.IsATerminal(); 437*0b57cec5SDimitry Andric 438*0b57cec5SDimitry Andric if (is_a_tty) { 439*0b57cec5SDimitry Andric terminal_state.Save(stdin_fd, false); 440*0b57cec5SDimitry Andric terminal.SetCanonical(false); 441*0b57cec5SDimitry Andric terminal.SetEcho(true); 442*0b57cec5SDimitry Andric } 443*0b57cec5SDimitry Andric 444*0b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker locker( 445*0b57cec5SDimitry Andric m_python, 446*0b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker::AcquireLock | 447*0b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker::InitSession | 448*0b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker::InitGlobals, 449*0b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker::FreeAcquiredLock | 450*0b57cec5SDimitry Andric ScriptInterpreterPythonImpl::Locker::TearDownSession); 451*0b57cec5SDimitry Andric 452*0b57cec5SDimitry Andric // The following call drops into the embedded interpreter loop and 453*0b57cec5SDimitry Andric // stays there until the user chooses to exit from the Python 454*0b57cec5SDimitry Andric // interpreter. This embedded interpreter will, as any Python code that 455*0b57cec5SDimitry Andric // performs I/O, unlock the GIL before a system call that can hang, and 456*0b57cec5SDimitry Andric // lock it when the syscall has returned. 457*0b57cec5SDimitry Andric 458*0b57cec5SDimitry Andric // We need to surround the call to the embedded interpreter with calls 459*0b57cec5SDimitry Andric // to PyGILState_Ensure and PyGILState_Release (using the Locker 460*0b57cec5SDimitry Andric // above). This is because Python has a global lock which must be held 461*0b57cec5SDimitry Andric // whenever we want to touch any Python objects. Otherwise, if the user 462*0b57cec5SDimitry Andric // calls Python code, the interpreter state will be off, and things 463*0b57cec5SDimitry Andric // could hang (it's happened before). 464*0b57cec5SDimitry Andric 465*0b57cec5SDimitry Andric StreamString run_string; 466*0b57cec5SDimitry Andric run_string.Printf("run_python_interpreter (%s)", 467*0b57cec5SDimitry Andric m_python->GetDictionaryName()); 468*0b57cec5SDimitry Andric PyRun_SimpleString(run_string.GetData()); 469*0b57cec5SDimitry Andric 470*0b57cec5SDimitry Andric if (is_a_tty) 471*0b57cec5SDimitry Andric terminal_state.Restore(); 472*0b57cec5SDimitry Andric } 473*0b57cec5SDimitry Andric } 474*0b57cec5SDimitry Andric SetIsDone(true); 475*0b57cec5SDimitry Andric } 476*0b57cec5SDimitry Andric 477*0b57cec5SDimitry Andric void Cancel() override {} 478*0b57cec5SDimitry Andric 479*0b57cec5SDimitry Andric bool Interrupt() override { return m_python->Interrupt(); } 480*0b57cec5SDimitry Andric 481*0b57cec5SDimitry Andric void GotEOF() override {} 482*0b57cec5SDimitry Andric 483*0b57cec5SDimitry Andric protected: 484*0b57cec5SDimitry Andric ScriptInterpreterPythonImpl *m_python; 485*0b57cec5SDimitry Andric }; 486*0b57cec5SDimitry Andric 487*0b57cec5SDimitry Andric } // namespace lldb_private 488*0b57cec5SDimitry Andric 489fe6060f1SDimitry Andric #endif // LLDB_ENABLE_PYTHON 490fe6060f1SDimitry Andric #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H 491