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