1 //===-- ScriptInterpreter.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_INTERPRETER_SCRIPTINTERPRETER_H 10 #define LLDB_INTERPRETER_SCRIPTINTERPRETER_H 11 12 #include "lldb/API/SBAttachInfo.h" 13 #include "lldb/API/SBBreakpoint.h" 14 #include "lldb/API/SBData.h" 15 #include "lldb/API/SBError.h" 16 #include "lldb/API/SBEvent.h" 17 #include "lldb/API/SBExecutionContext.h" 18 #include "lldb/API/SBLaunchInfo.h" 19 #include "lldb/API/SBMemoryRegionInfo.h" 20 #include "lldb/API/SBStream.h" 21 #include "lldb/Breakpoint/BreakpointOptions.h" 22 #include "lldb/Core/PluginInterface.h" 23 #include "lldb/Core/SearchFilter.h" 24 #include "lldb/Core/ThreadedCommunication.h" 25 #include "lldb/Host/PseudoTerminal.h" 26 #include "lldb/Host/StreamFile.h" 27 #include "lldb/Interpreter/Interfaces/OperatingSystemInterface.h" 28 #include "lldb/Interpreter/Interfaces/ScriptedPlatformInterface.h" 29 #include "lldb/Interpreter/Interfaces/ScriptedProcessInterface.h" 30 #include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h" 31 #include "lldb/Interpreter/ScriptObject.h" 32 #include "lldb/Utility/Broadcaster.h" 33 #include "lldb/Utility/Status.h" 34 #include "lldb/Utility/StructuredData.h" 35 #include "lldb/lldb-private.h" 36 #include <optional> 37 38 namespace lldb_private { 39 40 class ScriptInterpreterLocker { 41 public: 42 ScriptInterpreterLocker() = default; 43 44 virtual ~ScriptInterpreterLocker() = default; 45 46 private: 47 ScriptInterpreterLocker(const ScriptInterpreterLocker &) = delete; 48 const ScriptInterpreterLocker & 49 operator=(const ScriptInterpreterLocker &) = delete; 50 }; 51 52 class ExecuteScriptOptions { 53 public: 54 ExecuteScriptOptions() = default; 55 56 bool GetEnableIO() const { return m_enable_io; } 57 58 bool GetSetLLDBGlobals() const { return m_set_lldb_globals; } 59 60 // If this is true then any exceptions raised by the script will be 61 // cleared with PyErr_Clear(). If false then they will be left for 62 // the caller to clean up 63 bool GetMaskoutErrors() const { return m_maskout_errors; } 64 65 ExecuteScriptOptions &SetEnableIO(bool enable) { 66 m_enable_io = enable; 67 return *this; 68 } 69 70 ExecuteScriptOptions &SetSetLLDBGlobals(bool set) { 71 m_set_lldb_globals = set; 72 return *this; 73 } 74 75 ExecuteScriptOptions &SetMaskoutErrors(bool maskout) { 76 m_maskout_errors = maskout; 77 return *this; 78 } 79 80 private: 81 bool m_enable_io = true; 82 bool m_set_lldb_globals = true; 83 bool m_maskout_errors = true; 84 }; 85 86 class LoadScriptOptions { 87 public: 88 LoadScriptOptions() = default; 89 90 bool GetInitSession() const { return m_init_session; } 91 bool GetSilent() const { return m_silent; } 92 93 LoadScriptOptions &SetInitSession(bool b) { 94 m_init_session = b; 95 return *this; 96 } 97 98 LoadScriptOptions &SetSilent(bool b) { 99 m_silent = b; 100 return *this; 101 } 102 103 private: 104 bool m_init_session = false; 105 bool m_silent = false; 106 }; 107 108 class ScriptInterpreterIORedirect { 109 public: 110 /// Create an IO redirect. If IO is enabled, this will redirects the output 111 /// to the command return object if set or to the debugger otherwise. If IO 112 /// is disabled, it will redirect all IO to /dev/null. 113 static llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> 114 Create(bool enable_io, Debugger &debugger, CommandReturnObject *result); 115 116 ~ScriptInterpreterIORedirect(); 117 118 lldb::FileSP GetInputFile() const { return m_input_file_sp; } 119 lldb::FileSP GetOutputFile() const { return m_output_file_sp->GetFileSP(); } 120 lldb::FileSP GetErrorFile() const { return m_error_file_sp->GetFileSP(); } 121 122 /// Flush our output and error file handles. 123 void Flush(); 124 125 private: 126 ScriptInterpreterIORedirect(std::unique_ptr<File> input, 127 std::unique_ptr<File> output); 128 ScriptInterpreterIORedirect(Debugger &debugger, CommandReturnObject *result); 129 130 lldb::FileSP m_input_file_sp; 131 lldb::StreamFileSP m_output_file_sp; 132 lldb::StreamFileSP m_error_file_sp; 133 ThreadedCommunication m_communication; 134 bool m_disconnect; 135 }; 136 137 class ScriptInterpreter : public PluginInterface { 138 public: 139 enum ScriptReturnType { 140 eScriptReturnTypeCharPtr, 141 eScriptReturnTypeBool, 142 eScriptReturnTypeShortInt, 143 eScriptReturnTypeShortIntUnsigned, 144 eScriptReturnTypeInt, 145 eScriptReturnTypeIntUnsigned, 146 eScriptReturnTypeLongInt, 147 eScriptReturnTypeLongIntUnsigned, 148 eScriptReturnTypeLongLong, 149 eScriptReturnTypeLongLongUnsigned, 150 eScriptReturnTypeFloat, 151 eScriptReturnTypeDouble, 152 eScriptReturnTypeChar, 153 eScriptReturnTypeCharStrOrNone, 154 eScriptReturnTypeOpaqueObject 155 }; 156 157 ScriptInterpreter(Debugger &debugger, lldb::ScriptLanguage script_lang); 158 159 virtual StructuredData::DictionarySP GetInterpreterInfo(); 160 161 ~ScriptInterpreter() override = default; 162 163 virtual bool Interrupt() { return false; } 164 165 virtual bool ExecuteOneLine( 166 llvm::StringRef command, CommandReturnObject *result, 167 const ExecuteScriptOptions &options = ExecuteScriptOptions()) = 0; 168 169 virtual void ExecuteInterpreterLoop() = 0; 170 171 virtual bool ExecuteOneLineWithReturn( 172 llvm::StringRef in_string, ScriptReturnType return_type, void *ret_value, 173 const ExecuteScriptOptions &options = ExecuteScriptOptions()) { 174 return true; 175 } 176 177 virtual Status ExecuteMultipleLines( 178 const char *in_string, 179 const ExecuteScriptOptions &options = ExecuteScriptOptions()) { 180 return Status::FromErrorString("not implemented"); 181 } 182 183 virtual Status 184 ExportFunctionDefinitionToInterpreter(StringList &function_def) { 185 return Status::FromErrorString("not implemented"); 186 } 187 188 virtual Status GenerateBreakpointCommandCallbackData(StringList &input, 189 std::string &output, 190 bool has_extra_args, 191 bool is_callback) { 192 return Status::FromErrorString("not implemented"); 193 } 194 195 virtual bool GenerateWatchpointCommandCallbackData(StringList &input, 196 std::string &output, 197 bool is_callback) { 198 return false; 199 } 200 201 virtual bool GenerateTypeScriptFunction(const char *oneliner, 202 std::string &output, 203 const void *name_token = nullptr) { 204 return false; 205 } 206 207 virtual bool GenerateTypeScriptFunction(StringList &input, 208 std::string &output, 209 const void *name_token = nullptr) { 210 return false; 211 } 212 213 virtual bool GenerateScriptAliasFunction(StringList &input, 214 std::string &output) { 215 return false; 216 } 217 218 virtual bool GenerateTypeSynthClass(StringList &input, std::string &output, 219 const void *name_token = nullptr) { 220 return false; 221 } 222 223 virtual bool GenerateTypeSynthClass(const char *oneliner, std::string &output, 224 const void *name_token = nullptr) { 225 return false; 226 } 227 228 virtual StructuredData::ObjectSP 229 CreateSyntheticScriptedProvider(const char *class_name, 230 lldb::ValueObjectSP valobj) { 231 return StructuredData::ObjectSP(); 232 } 233 234 virtual StructuredData::GenericSP 235 CreateScriptCommandObject(const char *class_name) { 236 return StructuredData::GenericSP(); 237 } 238 239 virtual StructuredData::GenericSP 240 CreateFrameRecognizer(const char *class_name) { 241 return StructuredData::GenericSP(); 242 } 243 244 virtual lldb::ValueObjectListSP GetRecognizedArguments( 245 const StructuredData::ObjectSP &implementor, 246 lldb::StackFrameSP frame_sp) { 247 return lldb::ValueObjectListSP(); 248 } 249 250 virtual bool ShouldHide(const StructuredData::ObjectSP &implementor, 251 lldb::StackFrameSP frame_sp) { 252 return false; 253 } 254 255 virtual StructuredData::GenericSP 256 CreateScriptedBreakpointResolver(const char *class_name, 257 const StructuredDataImpl &args_data, 258 lldb::BreakpointSP &bkpt_sp) { 259 return StructuredData::GenericSP(); 260 } 261 262 virtual bool 263 ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP implementor_sp, 264 SymbolContext *sym_ctx) 265 { 266 return false; 267 } 268 269 virtual lldb::SearchDepth 270 ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP implementor_sp) 271 { 272 return lldb::eSearchDepthModule; 273 } 274 275 virtual StructuredData::ObjectSP 276 LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) { 277 return StructuredData::ObjectSP(); 278 } 279 280 virtual StructuredData::DictionarySP 281 GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, 282 const char *setting_name, lldb_private::Status &error) { 283 return StructuredData::DictionarySP(); 284 } 285 286 virtual Status GenerateFunction(const char *signature, 287 const StringList &input, 288 bool is_callback) { 289 return Status::FromErrorString("not implemented"); 290 } 291 292 virtual void CollectDataForBreakpointCommandCallback( 293 std::vector<std::reference_wrapper<BreakpointOptions>> &options, 294 CommandReturnObject &result); 295 296 virtual void 297 CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, 298 CommandReturnObject &result); 299 300 /// Set the specified text as the callback for the breakpoint. 301 Status SetBreakpointCommandCallback( 302 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, 303 const char *callback_text); 304 305 virtual Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, 306 const char *callback_text, 307 bool is_callback) { 308 return Status::FromErrorString("not implemented"); 309 } 310 311 /// This one is for deserialization: 312 virtual Status SetBreakpointCommandCallback( 313 BreakpointOptions &bp_options, 314 std::unique_ptr<BreakpointOptions::CommandData> &data_up) { 315 return Status::FromErrorString("not implemented"); 316 } 317 318 Status SetBreakpointCommandCallbackFunction( 319 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec, 320 const char *function_name, StructuredData::ObjectSP extra_args_sp); 321 322 /// Set a script function as the callback for the breakpoint. 323 virtual Status 324 SetBreakpointCommandCallbackFunction(BreakpointOptions &bp_options, 325 const char *function_name, 326 StructuredData::ObjectSP extra_args_sp) { 327 return Status::FromErrorString("not implemented"); 328 } 329 330 /// Set a one-liner as the callback for the watchpoint. 331 virtual void SetWatchpointCommandCallback(WatchpointOptions *wp_options, 332 const char *user_input, 333 bool is_callback) {} 334 335 virtual bool GetScriptedSummary(const char *function_name, 336 lldb::ValueObjectSP valobj, 337 StructuredData::ObjectSP &callee_wrapper_sp, 338 const TypeSummaryOptions &options, 339 std::string &retval) { 340 return false; 341 } 342 343 // Calls the specified formatter matching Python function and returns its 344 // result (true if it's a match, false if we should keep looking for a 345 // matching formatter). 346 virtual bool FormatterCallbackFunction(const char *function_name, 347 lldb::TypeImplSP type_impl_sp) { 348 return true; 349 } 350 351 virtual void Clear() { 352 // Clean up any ref counts to SBObjects that might be in global variables 353 } 354 355 virtual size_t 356 CalculateNumChildren(const StructuredData::ObjectSP &implementor, 357 uint32_t max) { 358 return 0; 359 } 360 361 virtual lldb::ValueObjectSP 362 GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) { 363 return lldb::ValueObjectSP(); 364 } 365 366 virtual int 367 GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, 368 const char *child_name) { 369 return UINT32_MAX; 370 } 371 372 virtual bool 373 UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) { 374 return false; 375 } 376 377 virtual bool MightHaveChildrenSynthProviderInstance( 378 const StructuredData::ObjectSP &implementor) { 379 return true; 380 } 381 382 virtual lldb::ValueObjectSP 383 GetSyntheticValue(const StructuredData::ObjectSP &implementor) { 384 return nullptr; 385 } 386 387 virtual ConstString 388 GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) { 389 return ConstString(); 390 } 391 392 virtual bool 393 RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, 394 ScriptedCommandSynchronicity synchronicity, 395 lldb_private::CommandReturnObject &cmd_retobj, 396 Status &error, 397 const lldb_private::ExecutionContext &exe_ctx) { 398 return false; 399 } 400 401 virtual bool RunScriptBasedCommand( 402 StructuredData::GenericSP impl_obj_sp, llvm::StringRef args, 403 ScriptedCommandSynchronicity synchronicity, 404 lldb_private::CommandReturnObject &cmd_retobj, Status &error, 405 const lldb_private::ExecutionContext &exe_ctx) { 406 return false; 407 } 408 409 virtual bool RunScriptBasedParsedCommand( 410 StructuredData::GenericSP impl_obj_sp, Args& args, 411 ScriptedCommandSynchronicity synchronicity, 412 lldb_private::CommandReturnObject &cmd_retobj, Status &error, 413 const lldb_private::ExecutionContext &exe_ctx) { 414 return false; 415 } 416 417 virtual std::optional<std::string> 418 GetRepeatCommandForScriptedCommand(StructuredData::GenericSP impl_obj_sp, 419 Args &args) { 420 return std::nullopt; 421 } 422 423 virtual StructuredData::DictionarySP 424 HandleArgumentCompletionForScriptedCommand( 425 StructuredData::GenericSP impl_obj_sp, std::vector<llvm::StringRef> &args, 426 size_t args_pos, size_t char_in_arg) { 427 return {}; 428 } 429 430 virtual StructuredData::DictionarySP 431 HandleOptionArgumentCompletionForScriptedCommand( 432 StructuredData::GenericSP impl_obj_sp, llvm::StringRef &long_name, 433 size_t char_in_arg) { 434 return {}; 435 } 436 437 virtual bool RunScriptFormatKeyword(const char *impl_function, 438 Process *process, std::string &output, 439 Status &error) { 440 error = Status::FromErrorString("unimplemented"); 441 return false; 442 } 443 444 virtual bool RunScriptFormatKeyword(const char *impl_function, Thread *thread, 445 std::string &output, Status &error) { 446 error = Status::FromErrorString("unimplemented"); 447 return false; 448 } 449 450 virtual bool RunScriptFormatKeyword(const char *impl_function, Target *target, 451 std::string &output, Status &error) { 452 error = Status::FromErrorString("unimplemented"); 453 return false; 454 } 455 456 virtual bool RunScriptFormatKeyword(const char *impl_function, 457 StackFrame *frame, std::string &output, 458 Status &error) { 459 error = Status::FromErrorString("unimplemented"); 460 return false; 461 } 462 463 virtual bool RunScriptFormatKeyword(const char *impl_function, 464 ValueObject *value, std::string &output, 465 Status &error) { 466 error = Status::FromErrorString("unimplemented"); 467 return false; 468 } 469 470 virtual bool GetDocumentationForItem(const char *item, std::string &dest) { 471 dest.clear(); 472 return false; 473 } 474 475 virtual bool 476 GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 477 std::string &dest) { 478 dest.clear(); 479 return false; 480 } 481 482 virtual StructuredData::ObjectSP 483 GetOptionsForCommandObject(StructuredData::GenericSP cmd_obj_sp) { 484 return {}; 485 } 486 487 virtual StructuredData::ObjectSP 488 GetArgumentsForCommandObject(StructuredData::GenericSP cmd_obj_sp) { 489 return {}; 490 } 491 492 virtual bool SetOptionValueForCommandObject( 493 StructuredData::GenericSP cmd_obj_sp, ExecutionContext *exe_ctx, 494 llvm::StringRef long_option, llvm::StringRef value) { 495 return false; 496 } 497 498 virtual void OptionParsingStartedForCommandObject( 499 StructuredData::GenericSP cmd_obj_sp) { 500 return; 501 } 502 503 virtual uint32_t 504 GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) { 505 return 0; 506 } 507 508 virtual bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 509 std::string &dest) { 510 dest.clear(); 511 return false; 512 } 513 514 virtual bool CheckObjectExists(const char *name) { return false; } 515 516 virtual bool 517 LoadScriptingModule(const char *filename, const LoadScriptOptions &options, 518 lldb_private::Status &error, 519 StructuredData::ObjectSP *module_sp = nullptr, 520 FileSpec extra_search_dir = {}); 521 522 virtual bool IsReservedWord(const char *word) { return false; } 523 524 virtual std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock(); 525 526 const char *GetScriptInterpreterPtyName(); 527 528 virtual llvm::Expected<unsigned> 529 GetMaxPositionalArgumentsForCallable(const llvm::StringRef &callable_name) { 530 return llvm::createStringError( 531 llvm::inconvertibleErrorCode(), "Unimplemented function"); 532 } 533 534 static std::string LanguageToString(lldb::ScriptLanguage language); 535 536 static lldb::ScriptLanguage StringToLanguage(const llvm::StringRef &string); 537 538 lldb::ScriptLanguage GetLanguage() { return m_script_lang; } 539 540 virtual lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() { 541 return {}; 542 } 543 544 virtual lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() { 545 return {}; 546 } 547 548 virtual lldb::ScriptedThreadPlanInterfaceSP 549 CreateScriptedThreadPlanInterface() { 550 return {}; 551 } 552 553 virtual lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() { 554 return {}; 555 } 556 557 virtual lldb::ScriptedPlatformInterfaceUP GetScriptedPlatformInterface() { 558 return {}; 559 } 560 561 virtual lldb::ScriptedStopHookInterfaceSP CreateScriptedStopHookInterface() { 562 return {}; 563 } 564 565 virtual StructuredData::ObjectSP 566 CreateStructuredDataFromScriptObject(ScriptObject obj) { 567 return {}; 568 } 569 570 lldb::DataExtractorSP 571 GetDataExtractorFromSBData(const lldb::SBData &data) const; 572 573 Status GetStatusFromSBError(const lldb::SBError &error) const; 574 575 Event *GetOpaqueTypeFromSBEvent(const lldb::SBEvent &event) const; 576 577 lldb::StreamSP GetOpaqueTypeFromSBStream(const lldb::SBStream &stream) const; 578 579 lldb::BreakpointSP 580 GetOpaqueTypeFromSBBreakpoint(const lldb::SBBreakpoint &breakpoint) const; 581 582 lldb::ProcessAttachInfoSP 583 GetOpaqueTypeFromSBAttachInfo(const lldb::SBAttachInfo &attach_info) const; 584 585 lldb::ProcessLaunchInfoSP 586 GetOpaqueTypeFromSBLaunchInfo(const lldb::SBLaunchInfo &launch_info) const; 587 588 std::optional<MemoryRegionInfo> GetOpaqueTypeFromSBMemoryRegionInfo( 589 const lldb::SBMemoryRegionInfo &mem_region) const; 590 591 lldb::ExecutionContextRefSP GetOpaqueTypeFromSBExecutionContext( 592 const lldb::SBExecutionContext &exe_ctx) const; 593 594 protected: 595 Debugger &m_debugger; 596 lldb::ScriptLanguage m_script_lang; 597 }; 598 599 } // namespace lldb_private 600 601 #endif // LLDB_INTERPRETER_SCRIPTINTERPRETER_H 602