1 //===-- ScriptInterpreterPython.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 #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H 10 #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H 11 12 #ifdef LLDB_DISABLE_PYTHON 13 14 // Python is disabled in this build 15 16 #else 17 18 #include <memory> 19 #include <string> 20 #include <vector> 21 22 #include "PythonDataObjects.h" 23 #include "lldb/Breakpoint/BreakpointOptions.h" 24 #include "lldb/Core/IOHandler.h" 25 #include "lldb/Host/Terminal.h" 26 #include "lldb/Interpreter/ScriptInterpreter.h" 27 #include "lldb/lldb-private.h" 28 29 class IOHandlerPythonInterpreter; 30 31 namespace lldb_private { 32 33 class ScriptInterpreterPython : public ScriptInterpreter, 34 public IOHandlerDelegateMultiline { 35 public: 36 class CommandDataPython : public BreakpointOptions::CommandData { 37 public: 38 CommandDataPython() : BreakpointOptions::CommandData() { 39 interpreter = lldb::eScriptLanguagePython; 40 } 41 }; 42 43 #if PY_MAJOR_VERSION >= 3 44 typedef PyObject *(*SWIGInitCallback)(void); 45 #else 46 typedef void (*SWIGInitCallback)(void); 47 #endif 48 49 typedef bool (*SWIGBreakpointCallbackFunction)( 50 const char *python_function_name, const char *session_dictionary_name, 51 const lldb::StackFrameSP &frame_sp, 52 const lldb::BreakpointLocationSP &bp_loc_sp); 53 54 typedef bool (*SWIGWatchpointCallbackFunction)( 55 const char *python_function_name, const char *session_dictionary_name, 56 const lldb::StackFrameSP &frame_sp, const lldb::WatchpointSP &wp_sp); 57 58 typedef bool (*SWIGPythonTypeScriptCallbackFunction)( 59 const char *python_function_name, void *session_dictionary, 60 const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper, 61 const lldb::TypeSummaryOptionsSP &options, std::string &retval); 62 63 typedef void *(*SWIGPythonCreateSyntheticProvider)( 64 const char *python_class_name, const char *session_dictionary_name, 65 const lldb::ValueObjectSP &valobj_sp); 66 67 typedef void *(*SWIGPythonCreateCommandObject)( 68 const char *python_class_name, const char *session_dictionary_name, 69 const lldb::DebuggerSP debugger_sp); 70 71 typedef void *(*SWIGPythonCreateScriptedThreadPlan)( 72 const char *python_class_name, const char *session_dictionary_name, 73 const lldb::ThreadPlanSP &thread_plan_sp); 74 75 typedef bool (*SWIGPythonCallThreadPlan)(void *implementor, 76 const char *method_name, 77 Event *event_sp, bool &got_error); 78 79 typedef void *(*SWIGPythonCreateScriptedBreakpointResolver)( 80 const char *python_class_name, const char *session_dictionary_name, 81 lldb_private::StructuredDataImpl *args_impl, 82 lldb::BreakpointSP &bkpt_sp); 83 84 typedef unsigned int (*SWIGPythonCallBreakpointResolver)(void *implementor, 85 const char *method_name, 86 lldb_private::SymbolContext *sym_ctx); 87 88 typedef void *(*SWIGPythonCreateOSPlugin)(const char *python_class_name, 89 const char *session_dictionary_name, 90 const lldb::ProcessSP &process_sp); 91 92 typedef void *(*SWIGPythonCreateFrameRecognizer)( 93 const char *python_class_name, const char *session_dictionary_name); 94 95 typedef void *(*SWIGPythonGetRecognizedArguments)( 96 void *implementor, const lldb::StackFrameSP &frame_sp); 97 98 typedef size_t (*SWIGPythonCalculateNumChildren)(void *implementor, 99 uint32_t max); 100 101 typedef void *(*SWIGPythonGetChildAtIndex)(void *implementor, uint32_t idx); 102 103 typedef int (*SWIGPythonGetIndexOfChildWithName)(void *implementor, 104 const char *child_name); 105 106 typedef void *(*SWIGPythonCastPyObjectToSBValue)(void *data); 107 108 typedef lldb::ValueObjectSP (*SWIGPythonGetValueObjectSPFromSBValue)( 109 void *data); 110 111 typedef bool (*SWIGPythonUpdateSynthProviderInstance)(void *data); 112 113 typedef bool (*SWIGPythonMightHaveChildrenSynthProviderInstance)(void *data); 114 115 typedef void *(*SWIGPythonGetValueSynthProviderInstance)(void *implementor); 116 117 typedef bool (*SWIGPythonCallCommand)( 118 const char *python_function_name, const char *session_dictionary_name, 119 lldb::DebuggerSP &debugger, const char *args, 120 lldb_private::CommandReturnObject &cmd_retobj, 121 lldb::ExecutionContextRefSP exe_ctx_ref_sp); 122 123 typedef bool (*SWIGPythonCallCommandObject)( 124 void *implementor, lldb::DebuggerSP &debugger, const char *args, 125 lldb_private::CommandReturnObject &cmd_retobj, 126 lldb::ExecutionContextRefSP exe_ctx_ref_sp); 127 128 typedef bool (*SWIGPythonCallModuleInit)(const char *python_module_name, 129 const char *session_dictionary_name, 130 lldb::DebuggerSP &debugger); 131 132 typedef bool (*SWIGPythonScriptKeyword_Process)( 133 const char *python_function_name, const char *session_dictionary_name, 134 lldb::ProcessSP &process, std::string &output); 135 136 typedef bool (*SWIGPythonScriptKeyword_Thread)( 137 const char *python_function_name, const char *session_dictionary_name, 138 lldb::ThreadSP &thread, std::string &output); 139 140 typedef bool (*SWIGPythonScriptKeyword_Target)( 141 const char *python_function_name, const char *session_dictionary_name, 142 lldb::TargetSP &target, std::string &output); 143 144 typedef bool (*SWIGPythonScriptKeyword_Frame)( 145 const char *python_function_name, const char *session_dictionary_name, 146 lldb::StackFrameSP &frame, std::string &output); 147 148 typedef bool (*SWIGPythonScriptKeyword_Value)( 149 const char *python_function_name, const char *session_dictionary_name, 150 lldb::ValueObjectSP &value, std::string &output); 151 152 typedef void *(*SWIGPython_GetDynamicSetting)( 153 void *module, const char *setting, const lldb::TargetSP &target_sp); 154 155 friend class ::IOHandlerPythonInterpreter; 156 157 ScriptInterpreterPython(CommandInterpreter &interpreter); 158 159 ~ScriptInterpreterPython() override; 160 161 bool Interrupt() override; 162 163 bool ExecuteOneLine( 164 llvm::StringRef command, CommandReturnObject *result, 165 const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 166 167 void ExecuteInterpreterLoop() override; 168 169 bool ExecuteOneLineWithReturn( 170 llvm::StringRef in_string, 171 ScriptInterpreter::ScriptReturnType return_type, void *ret_value, 172 const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 173 174 lldb_private::Status ExecuteMultipleLines( 175 const char *in_string, 176 const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; 177 178 Status 179 ExportFunctionDefinitionToInterpreter(StringList &function_def) override; 180 181 bool GenerateTypeScriptFunction(StringList &input, std::string &output, 182 const void *name_token = nullptr) override; 183 184 bool GenerateTypeSynthClass(StringList &input, std::string &output, 185 const void *name_token = nullptr) override; 186 187 bool GenerateTypeSynthClass(const char *oneliner, std::string &output, 188 const void *name_token = nullptr) override; 189 190 // use this if the function code is just a one-liner script 191 bool GenerateTypeScriptFunction(const char *oneliner, std::string &output, 192 const void *name_token = nullptr) override; 193 194 bool GenerateScriptAliasFunction(StringList &input, 195 std::string &output) override; 196 197 StructuredData::ObjectSP 198 CreateSyntheticScriptedProvider(const char *class_name, 199 lldb::ValueObjectSP valobj) override; 200 201 StructuredData::GenericSP 202 CreateScriptCommandObject(const char *class_name) override; 203 204 StructuredData::ObjectSP 205 CreateScriptedThreadPlan(const char *class_name, 206 lldb::ThreadPlanSP thread_plan) override; 207 208 bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, 209 Event *event, 210 bool &script_error) override; 211 212 bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, 213 Event *event, bool &script_error) override; 214 215 bool ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp, 216 bool &script_error) override; 217 218 lldb::StateType 219 ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, 220 bool &script_error) override; 221 222 StructuredData::GenericSP 223 CreateScriptedBreakpointResolver(const char *class_name, 224 StructuredDataImpl *args_data, 225 lldb::BreakpointSP &bkpt_sp) override; 226 bool 227 ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP 228 implementor_sp, 229 SymbolContext *sym_ctx) override; 230 231 lldb::SearchDepth 232 ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP 233 implementor_sp) override; 234 235 StructuredData::GenericSP 236 CreateFrameRecognizer(const char *class_name) override; 237 238 lldb::ValueObjectListSP 239 GetRecognizedArguments(const StructuredData::ObjectSP &implementor, 240 lldb::StackFrameSP frame_sp) override; 241 242 StructuredData::GenericSP 243 OSPlugin_CreatePluginObject(const char *class_name, 244 lldb::ProcessSP process_sp) override; 245 246 StructuredData::DictionarySP 247 OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 248 249 StructuredData::ArraySP 250 OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override; 251 252 StructuredData::StringSP 253 OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, 254 lldb::tid_t thread_id) override; 255 256 StructuredData::DictionarySP 257 OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, 258 lldb::tid_t tid, lldb::addr_t context) override; 259 260 StructuredData::ObjectSP 261 LoadPluginModule(const FileSpec &file_spec, 262 lldb_private::Status &error) override; 263 264 StructuredData::DictionarySP 265 GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, 266 const char *setting_name, 267 lldb_private::Status &error) override; 268 269 size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, 270 uint32_t max) override; 271 272 lldb::ValueObjectSP 273 GetChildAtIndex(const StructuredData::ObjectSP &implementor, 274 uint32_t idx) override; 275 276 int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, 277 const char *child_name) override; 278 279 bool UpdateSynthProviderInstance( 280 const StructuredData::ObjectSP &implementor) override; 281 282 bool MightHaveChildrenSynthProviderInstance( 283 const StructuredData::ObjectSP &implementor) override; 284 285 lldb::ValueObjectSP 286 GetSyntheticValue(const StructuredData::ObjectSP &implementor) override; 287 288 ConstString 289 GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override; 290 291 bool 292 RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, 293 ScriptedCommandSynchronicity synchronicity, 294 lldb_private::CommandReturnObject &cmd_retobj, 295 Status &error, 296 const lldb_private::ExecutionContext &exe_ctx) override; 297 298 bool RunScriptBasedCommand( 299 StructuredData::GenericSP impl_obj_sp, llvm::StringRef args, 300 ScriptedCommandSynchronicity synchronicity, 301 lldb_private::CommandReturnObject &cmd_retobj, Status &error, 302 const lldb_private::ExecutionContext &exe_ctx) override; 303 304 Status GenerateFunction(const char *signature, 305 const StringList &input) override; 306 307 Status GenerateBreakpointCommandCallbackData(StringList &input, 308 std::string &output) override; 309 310 bool GenerateWatchpointCommandCallbackData(StringList &input, 311 std::string &output) override; 312 313 static bool BreakpointCallbackFunction(void *baton, 314 StoppointCallbackContext *context, 315 lldb::user_id_t break_id, 316 lldb::user_id_t break_loc_id); 317 318 static bool WatchpointCallbackFunction(void *baton, 319 StoppointCallbackContext *context, 320 lldb::user_id_t watch_id); 321 322 bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, 323 StructuredData::ObjectSP &callee_wrapper_sp, 324 const TypeSummaryOptions &options, 325 std::string &retval) override; 326 327 void Clear() override; 328 329 bool GetDocumentationForItem(const char *item, std::string &dest) override; 330 331 bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 332 std::string &dest) override; 333 334 uint32_t 335 GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override; 336 337 bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 338 std::string &dest) override; 339 340 bool CheckObjectExists(const char *name) override { 341 if (!name || !name[0]) 342 return false; 343 std::string temp; 344 return GetDocumentationForItem(name, temp); 345 } 346 347 bool RunScriptFormatKeyword(const char *impl_function, Process *process, 348 std::string &output, Status &error) override; 349 350 bool RunScriptFormatKeyword(const char *impl_function, Thread *thread, 351 std::string &output, Status &error) override; 352 353 bool RunScriptFormatKeyword(const char *impl_function, Target *target, 354 std::string &output, Status &error) override; 355 356 bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame, 357 std::string &output, Status &error) override; 358 359 bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value, 360 std::string &output, Status &error) override; 361 362 bool 363 LoadScriptingModule(const char *filename, bool can_reload, bool init_session, 364 lldb_private::Status &error, 365 StructuredData::ObjectSP *module_sp = nullptr) override; 366 367 bool IsReservedWord(const char *word) override; 368 369 std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override; 370 371 void CollectDataForBreakpointCommandCallback( 372 std::vector<BreakpointOptions *> &bp_options_vec, 373 CommandReturnObject &result) override; 374 375 void 376 CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, 377 CommandReturnObject &result) override; 378 379 /// Set the callback body text into the callback for the breakpoint. 380 Status SetBreakpointCommandCallback(BreakpointOptions *bp_options, 381 const char *callback_body) override; 382 383 void SetBreakpointCommandCallbackFunction(BreakpointOptions *bp_options, 384 const char *function_name) override; 385 386 /// This one is for deserialization: 387 Status SetBreakpointCommandCallback( 388 BreakpointOptions *bp_options, 389 std::unique_ptr<BreakpointOptions::CommandData> &data_up) override; 390 391 /// Set a one-liner as the callback for the watchpoint. 392 void SetWatchpointCommandCallback(WatchpointOptions *wp_options, 393 const char *oneliner) override; 394 395 StringList ReadCommandInputFromUser(FILE *in_file); 396 397 void ResetOutputFileHandle(FILE *new_fh) override; 398 399 const char *GetDictionaryName() { return m_dictionary_name.c_str(); } 400 401 PyThreadState *GetThreadState() { return m_command_thread_state; } 402 403 void SetThreadState(PyThreadState *s) { 404 if (s) 405 m_command_thread_state = s; 406 } 407 408 //---------------------------------------------------------------------- 409 // IOHandlerDelegate 410 //---------------------------------------------------------------------- 411 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override; 412 413 void IOHandlerInputComplete(IOHandler &io_handler, 414 std::string &data) override; 415 416 //------------------------------------------------------------------ 417 // Static Functions 418 //------------------------------------------------------------------ 419 static void InitializeSWIG(); 420 static void Initialize(); 421 422 static void Terminate(); 423 424 static lldb::ScriptInterpreterSP 425 CreateInstance(CommandInterpreter &interpreter); 426 427 static lldb_private::ConstString GetPluginNameStatic(); 428 429 static const char *GetPluginDescriptionStatic(); 430 431 static FileSpec GetPythonDir(); 432 433 //------------------------------------------------------------------ 434 // PluginInterface protocol 435 //------------------------------------------------------------------ 436 lldb_private::ConstString GetPluginName() override; 437 438 uint32_t GetPluginVersion() override; 439 440 class Locker : public ScriptInterpreterLocker { 441 public: 442 enum OnEntry { 443 AcquireLock = 0x0001, 444 InitSession = 0x0002, 445 InitGlobals = 0x0004, 446 NoSTDIN = 0x0008 447 }; 448 449 enum OnLeave { 450 FreeLock = 0x0001, 451 FreeAcquiredLock = 0x0002, // do not free the lock if we already held it 452 // when calling constructor 453 TearDownSession = 0x0004 454 }; 455 456 Locker(ScriptInterpreterPython *py_interpreter = nullptr, 457 uint16_t on_entry = AcquireLock | InitSession, 458 uint16_t on_leave = FreeLock | TearDownSession, FILE *in = nullptr, 459 FILE *out = nullptr, FILE *err = nullptr); 460 461 ~Locker() override; 462 463 private: 464 bool DoAcquireLock(); 465 466 bool DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err); 467 468 bool DoFreeLock(); 469 470 bool DoTearDownSession(); 471 472 static void ReleasePythonLock(); 473 474 bool m_teardown_session; 475 ScriptInterpreterPython *m_python_interpreter; 476 // FILE* m_tmp_fh; 477 PyGILState_STATE m_GILState; 478 }; 479 480 protected: 481 static void InitializePrivate(); 482 483 static void InitializeInterpreter( 484 SWIGInitCallback python_swig_init_callback, 485 SWIGBreakpointCallbackFunction swig_breakpoint_callback, 486 SWIGWatchpointCallbackFunction swig_watchpoint_callback, 487 SWIGPythonTypeScriptCallbackFunction swig_typescript_callback, 488 SWIGPythonCreateSyntheticProvider swig_synthetic_script, 489 SWIGPythonCreateCommandObject swig_create_cmd, 490 SWIGPythonCalculateNumChildren swig_calc_children, 491 SWIGPythonGetChildAtIndex swig_get_child_index, 492 SWIGPythonGetIndexOfChildWithName swig_get_index_child, 493 SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue, 494 SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue, 495 SWIGPythonUpdateSynthProviderInstance swig_update_provider, 496 SWIGPythonMightHaveChildrenSynthProviderInstance 497 swig_mighthavechildren_provider, 498 SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider, 499 SWIGPythonCallCommand swig_call_command, 500 SWIGPythonCallCommandObject swig_call_command_object, 501 SWIGPythonCallModuleInit swig_call_module_init, 502 SWIGPythonCreateOSPlugin swig_create_os_plugin, 503 SWIGPythonCreateFrameRecognizer swig_create_frame_recognizer, 504 SWIGPythonGetRecognizedArguments swig_get_recognized_arguments, 505 SWIGPythonScriptKeyword_Process swig_run_script_keyword_process, 506 SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread, 507 SWIGPythonScriptKeyword_Target swig_run_script_keyword_target, 508 SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame, 509 SWIGPythonScriptKeyword_Value swig_run_script_keyword_value, 510 SWIGPython_GetDynamicSetting swig_plugin_get, 511 SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script, 512 SWIGPythonCallThreadPlan swig_call_thread_plan, 513 SWIGPythonCreateScriptedBreakpointResolver swig_bkpt_resolver_script, 514 SWIGPythonCallBreakpointResolver swig_call_breakpoint_resolver); 515 516 class SynchronicityHandler { 517 private: 518 lldb::DebuggerSP m_debugger_sp; 519 ScriptedCommandSynchronicity m_synch_wanted; 520 bool m_old_asynch; 521 522 public: 523 SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity); 524 525 ~SynchronicityHandler(); 526 }; 527 528 enum class AddLocation { Beginning, End }; 529 530 static void AddToSysPath(AddLocation location, std::string path); 531 532 static void ComputePythonDirForApple(llvm::SmallVectorImpl<char> &path); 533 static void ComputePythonDirForPosix(llvm::SmallVectorImpl<char> &path); 534 static void ComputePythonDirForWindows(llvm::SmallVectorImpl<char> &path); 535 536 bool EnterSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err); 537 538 void LeaveSession(); 539 540 void SaveTerminalState(int fd); 541 542 void RestoreTerminalState(); 543 544 uint32_t IsExecutingPython() const { return m_lock_count > 0; } 545 546 uint32_t IncrementLockCount() { return ++m_lock_count; } 547 548 uint32_t DecrementLockCount() { 549 if (m_lock_count > 0) 550 --m_lock_count; 551 return m_lock_count; 552 } 553 554 enum ActiveIOHandler { 555 eIOHandlerNone, 556 eIOHandlerBreakpoint, 557 eIOHandlerWatchpoint 558 }; 559 560 PythonObject &GetMainModule(); 561 562 PythonDictionary &GetSessionDictionary(); 563 564 PythonDictionary &GetSysModuleDictionary(); 565 566 bool GetEmbeddedInterpreterModuleObjects(); 567 568 bool SetStdHandle(File &file, const char *py_name, PythonFile &save_file, 569 const char *mode); 570 571 PythonFile m_saved_stdin; 572 PythonFile m_saved_stdout; 573 PythonFile m_saved_stderr; 574 PythonObject m_main_module; 575 PythonObject m_lldb_module; 576 PythonDictionary m_session_dict; 577 PythonDictionary m_sys_module_dict; 578 PythonObject m_run_one_line_function; 579 PythonObject m_run_one_line_str_global; 580 std::string m_dictionary_name; 581 TerminalState m_terminal_state; 582 ActiveIOHandler m_active_io_handler; 583 bool m_session_is_active; 584 bool m_pty_slave_is_open; 585 bool m_valid_session; 586 uint32_t m_lock_count; 587 PyThreadState *m_command_thread_state; 588 }; 589 590 } // namespace lldb_private 591 592 #endif // LLDB_DISABLE_PYTHON 593 594 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H 595