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