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