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/Breakpoint/BreakpointOptions.h" 13 #include "lldb/Core/Communication.h" 14 #include "lldb/Core/PluginInterface.h" 15 #include "lldb/Core/SearchFilter.h" 16 #include "lldb/Core/StreamFile.h" 17 #include "lldb/Host/PseudoTerminal.h" 18 #include "lldb/Utility/Broadcaster.h" 19 #include "lldb/Utility/Status.h" 20 #include "lldb/Utility/StructuredData.h" 21 #include "lldb/lldb-private.h" 22 23 namespace lldb_private { 24 25 class ScriptInterpreterLocker { 26 public: 27 ScriptInterpreterLocker() = default; 28 29 virtual ~ScriptInterpreterLocker() = default; 30 31 private: 32 ScriptInterpreterLocker(const ScriptInterpreterLocker &) = delete; 33 const ScriptInterpreterLocker & 34 operator=(const ScriptInterpreterLocker &) = delete; 35 }; 36 37 class ScriptInterpreterIORedirect { 38 public: 39 /// Create an IO redirect. If IO is enabled, this will redirects the output 40 /// to the command return object if set or to the debugger otherwise. If IO 41 /// is disabled, it will redirect all IO to /dev/null. 42 static llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>> 43 Create(bool enable_io, Debugger &debugger, CommandReturnObject *result); 44 45 ~ScriptInterpreterIORedirect(); 46 47 lldb::FileSP GetInputFile() const { return m_input_file_sp; } 48 lldb::FileSP GetOutputFile() const { return m_output_file_sp->GetFileSP(); } 49 lldb::FileSP GetErrorFile() const { return m_error_file_sp->GetFileSP(); } 50 51 /// Flush our output and error file handles. 52 void Flush(); 53 54 private: 55 ScriptInterpreterIORedirect(std::unique_ptr<File> input, 56 std::unique_ptr<File> output); 57 ScriptInterpreterIORedirect(Debugger &debugger, CommandReturnObject *result); 58 59 lldb::FileSP m_input_file_sp; 60 lldb::StreamFileSP m_output_file_sp; 61 lldb::StreamFileSP m_error_file_sp; 62 Communication m_communication; 63 bool m_disconnect; 64 }; 65 66 class ScriptInterpreter : public PluginInterface { 67 public: 68 enum ScriptReturnType { 69 eScriptReturnTypeCharPtr, 70 eScriptReturnTypeBool, 71 eScriptReturnTypeShortInt, 72 eScriptReturnTypeShortIntUnsigned, 73 eScriptReturnTypeInt, 74 eScriptReturnTypeIntUnsigned, 75 eScriptReturnTypeLongInt, 76 eScriptReturnTypeLongIntUnsigned, 77 eScriptReturnTypeLongLong, 78 eScriptReturnTypeLongLongUnsigned, 79 eScriptReturnTypeFloat, 80 eScriptReturnTypeDouble, 81 eScriptReturnTypeChar, 82 eScriptReturnTypeCharStrOrNone, 83 eScriptReturnTypeOpaqueObject 84 }; 85 86 ScriptInterpreter(Debugger &debugger, lldb::ScriptLanguage script_lang); 87 88 ~ScriptInterpreter() override; 89 90 struct ExecuteScriptOptions { 91 public: 92 ExecuteScriptOptions() 93 : m_enable_io(true), m_set_lldb_globals(true), m_maskout_errors(true) {} 94 95 bool GetEnableIO() const { return m_enable_io; } 96 97 bool GetSetLLDBGlobals() const { return m_set_lldb_globals; } 98 99 // If this is true then any exceptions raised by the script will be 100 // cleared with PyErr_Clear(). If false then they will be left for 101 // the caller to clean up 102 bool GetMaskoutErrors() const { return m_maskout_errors; } 103 104 ExecuteScriptOptions &SetEnableIO(bool enable) { 105 m_enable_io = enable; 106 return *this; 107 } 108 109 ExecuteScriptOptions &SetSetLLDBGlobals(bool set) { 110 m_set_lldb_globals = set; 111 return *this; 112 } 113 114 ExecuteScriptOptions &SetMaskoutErrors(bool maskout) { 115 m_maskout_errors = maskout; 116 return *this; 117 } 118 119 private: 120 bool m_enable_io; 121 bool m_set_lldb_globals; 122 bool m_maskout_errors; 123 }; 124 125 virtual bool Interrupt() { return false; } 126 127 virtual bool ExecuteOneLine( 128 llvm::StringRef command, CommandReturnObject *result, 129 const ExecuteScriptOptions &options = ExecuteScriptOptions()) = 0; 130 131 virtual void ExecuteInterpreterLoop() = 0; 132 133 virtual bool ExecuteOneLineWithReturn( 134 llvm::StringRef in_string, ScriptReturnType return_type, void *ret_value, 135 const ExecuteScriptOptions &options = ExecuteScriptOptions()) { 136 return true; 137 } 138 139 virtual Status ExecuteMultipleLines( 140 const char *in_string, 141 const ExecuteScriptOptions &options = ExecuteScriptOptions()) { 142 Status error; 143 error.SetErrorString("not implemented"); 144 return error; 145 } 146 147 virtual Status 148 ExportFunctionDefinitionToInterpreter(StringList &function_def) { 149 Status error; 150 error.SetErrorString("not implemented"); 151 return error; 152 } 153 154 virtual Status GenerateBreakpointCommandCallbackData( 155 StringList &input, 156 std::string &output, 157 bool has_extra_args) { 158 Status error; 159 error.SetErrorString("not implemented"); 160 return error; 161 } 162 163 virtual bool GenerateWatchpointCommandCallbackData(StringList &input, 164 std::string &output) { 165 return false; 166 } 167 168 virtual bool GenerateTypeScriptFunction(const char *oneliner, 169 std::string &output, 170 const void *name_token = nullptr) { 171 return false; 172 } 173 174 virtual bool GenerateTypeScriptFunction(StringList &input, 175 std::string &output, 176 const void *name_token = nullptr) { 177 return false; 178 } 179 180 virtual bool GenerateScriptAliasFunction(StringList &input, 181 std::string &output) { 182 return false; 183 } 184 185 virtual bool GenerateTypeSynthClass(StringList &input, std::string &output, 186 const void *name_token = nullptr) { 187 return false; 188 } 189 190 virtual bool GenerateTypeSynthClass(const char *oneliner, std::string &output, 191 const void *name_token = nullptr) { 192 return false; 193 } 194 195 virtual StructuredData::ObjectSP 196 CreateSyntheticScriptedProvider(const char *class_name, 197 lldb::ValueObjectSP valobj) { 198 return StructuredData::ObjectSP(); 199 } 200 201 virtual StructuredData::GenericSP 202 CreateScriptCommandObject(const char *class_name) { 203 return StructuredData::GenericSP(); 204 } 205 206 virtual StructuredData::GenericSP 207 CreateFrameRecognizer(const char *class_name) { 208 return StructuredData::GenericSP(); 209 } 210 211 virtual lldb::ValueObjectListSP GetRecognizedArguments( 212 const StructuredData::ObjectSP &implementor, 213 lldb::StackFrameSP frame_sp) { 214 return lldb::ValueObjectListSP(); 215 } 216 217 virtual StructuredData::GenericSP 218 OSPlugin_CreatePluginObject(const char *class_name, 219 lldb::ProcessSP process_sp) { 220 return StructuredData::GenericSP(); 221 } 222 223 virtual StructuredData::DictionarySP 224 OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) { 225 return StructuredData::DictionarySP(); 226 } 227 228 virtual StructuredData::ArraySP 229 OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) { 230 return StructuredData::ArraySP(); 231 } 232 233 virtual StructuredData::StringSP 234 OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, 235 lldb::tid_t thread_id) { 236 return StructuredData::StringSP(); 237 } 238 239 virtual StructuredData::DictionarySP 240 OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, 241 lldb::tid_t tid, lldb::addr_t context) { 242 return StructuredData::DictionarySP(); 243 } 244 245 virtual StructuredData::ObjectSP 246 CreateScriptedThreadPlan(const char *class_name, 247 StructuredDataImpl *args_data, 248 std::string &error_str, 249 lldb::ThreadPlanSP thread_plan_sp) { 250 return StructuredData::ObjectSP(); 251 } 252 253 virtual bool 254 ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, 255 Event *event, bool &script_error) { 256 script_error = true; 257 return true; 258 } 259 260 virtual bool 261 ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, 262 Event *event, bool &script_error) { 263 script_error = true; 264 return true; 265 } 266 267 virtual bool 268 ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp, 269 bool &script_error) { 270 script_error = true; 271 return true; 272 } 273 274 virtual lldb::StateType 275 ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, 276 bool &script_error) { 277 script_error = true; 278 return lldb::eStateStepping; 279 } 280 281 virtual StructuredData::GenericSP 282 CreateScriptedBreakpointResolver(const char *class_name, 283 StructuredDataImpl *args_data, 284 lldb::BreakpointSP &bkpt_sp) { 285 return StructuredData::GenericSP(); 286 } 287 288 virtual bool 289 ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP implementor_sp, 290 SymbolContext *sym_ctx) 291 { 292 return false; 293 } 294 295 virtual lldb::SearchDepth 296 ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP implementor_sp) 297 { 298 return lldb::eSearchDepthModule; 299 } 300 301 virtual StructuredData::ObjectSP 302 LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) { 303 return StructuredData::ObjectSP(); 304 } 305 306 virtual StructuredData::DictionarySP 307 GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, 308 const char *setting_name, lldb_private::Status &error) { 309 return StructuredData::DictionarySP(); 310 } 311 312 virtual Status GenerateFunction(const char *signature, 313 const StringList &input) { 314 Status error; 315 error.SetErrorString("unimplemented"); 316 return error; 317 } 318 319 virtual void CollectDataForBreakpointCommandCallback( 320 std::vector<BreakpointOptions *> &options, CommandReturnObject &result); 321 322 virtual void 323 CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, 324 CommandReturnObject &result); 325 326 /// Set the specified text as the callback for the breakpoint. 327 Status 328 SetBreakpointCommandCallback(std::vector<BreakpointOptions *> &bp_options_vec, 329 const char *callback_text); 330 331 virtual Status SetBreakpointCommandCallback(BreakpointOptions *bp_options, 332 const char *callback_text) { 333 Status error; 334 error.SetErrorString("unimplemented"); 335 return error; 336 } 337 338 /// This one is for deserialization: 339 virtual Status SetBreakpointCommandCallback( 340 BreakpointOptions *bp_options, 341 std::unique_ptr<BreakpointOptions::CommandData> &data_up) { 342 Status error; 343 error.SetErrorString("unimplemented"); 344 return error; 345 } 346 347 Status SetBreakpointCommandCallbackFunction( 348 std::vector<BreakpointOptions *> &bp_options_vec, 349 const char *function_name, StructuredData::ObjectSP extra_args_sp); 350 351 /// Set a script function as the callback for the breakpoint. 352 virtual Status 353 SetBreakpointCommandCallbackFunction( 354 BreakpointOptions *bp_options, 355 const char *function_name, 356 StructuredData::ObjectSP extra_args_sp) { 357 Status error; 358 error.SetErrorString("unimplemented"); 359 return error; 360 } 361 362 /// Set a one-liner as the callback for the watchpoint. 363 virtual void SetWatchpointCommandCallback(WatchpointOptions *wp_options, 364 const char *oneliner) {} 365 366 virtual bool GetScriptedSummary(const char *function_name, 367 lldb::ValueObjectSP valobj, 368 StructuredData::ObjectSP &callee_wrapper_sp, 369 const TypeSummaryOptions &options, 370 std::string &retval) { 371 return false; 372 } 373 374 virtual void Clear() { 375 // Clean up any ref counts to SBObjects that might be in global variables 376 } 377 378 virtual size_t 379 CalculateNumChildren(const StructuredData::ObjectSP &implementor, 380 uint32_t max) { 381 return 0; 382 } 383 384 virtual lldb::ValueObjectSP 385 GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) { 386 return lldb::ValueObjectSP(); 387 } 388 389 virtual int 390 GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, 391 const char *child_name) { 392 return UINT32_MAX; 393 } 394 395 virtual bool 396 UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) { 397 return false; 398 } 399 400 virtual bool MightHaveChildrenSynthProviderInstance( 401 const StructuredData::ObjectSP &implementor) { 402 return true; 403 } 404 405 virtual lldb::ValueObjectSP 406 GetSyntheticValue(const StructuredData::ObjectSP &implementor) { 407 return nullptr; 408 } 409 410 virtual ConstString 411 GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) { 412 return ConstString(); 413 } 414 415 virtual bool 416 RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, 417 ScriptedCommandSynchronicity synchronicity, 418 lldb_private::CommandReturnObject &cmd_retobj, 419 Status &error, 420 const lldb_private::ExecutionContext &exe_ctx) { 421 return false; 422 } 423 424 virtual bool RunScriptBasedCommand( 425 StructuredData::GenericSP impl_obj_sp, llvm::StringRef args, 426 ScriptedCommandSynchronicity synchronicity, 427 lldb_private::CommandReturnObject &cmd_retobj, Status &error, 428 const lldb_private::ExecutionContext &exe_ctx) { 429 return false; 430 } 431 432 virtual bool RunScriptFormatKeyword(const char *impl_function, 433 Process *process, std::string &output, 434 Status &error) { 435 error.SetErrorString("unimplemented"); 436 return false; 437 } 438 439 virtual bool RunScriptFormatKeyword(const char *impl_function, Thread *thread, 440 std::string &output, Status &error) { 441 error.SetErrorString("unimplemented"); 442 return false; 443 } 444 445 virtual bool RunScriptFormatKeyword(const char *impl_function, Target *target, 446 std::string &output, Status &error) { 447 error.SetErrorString("unimplemented"); 448 return false; 449 } 450 451 virtual bool RunScriptFormatKeyword(const char *impl_function, 452 StackFrame *frame, std::string &output, 453 Status &error) { 454 error.SetErrorString("unimplemented"); 455 return false; 456 } 457 458 virtual bool RunScriptFormatKeyword(const char *impl_function, 459 ValueObject *value, std::string &output, 460 Status &error) { 461 error.SetErrorString("unimplemented"); 462 return false; 463 } 464 465 virtual bool GetDocumentationForItem(const char *item, std::string &dest) { 466 dest.clear(); 467 return false; 468 } 469 470 virtual bool 471 GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 472 std::string &dest) { 473 dest.clear(); 474 return false; 475 } 476 477 virtual uint32_t 478 GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) { 479 return 0; 480 } 481 482 virtual bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, 483 std::string &dest) { 484 dest.clear(); 485 return false; 486 } 487 488 virtual bool CheckObjectExists(const char *name) { return false; } 489 490 virtual bool 491 LoadScriptingModule(const char *filename, bool init_session, 492 lldb_private::Status &error, 493 StructuredData::ObjectSP *module_sp = nullptr); 494 495 virtual bool IsReservedWord(const char *word) { return false; } 496 497 virtual std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock(); 498 499 const char *GetScriptInterpreterPtyName(); 500 501 virtual llvm::Expected<unsigned> 502 GetMaxPositionalArgumentsForCallable(const llvm::StringRef &callable_name) { 503 return llvm::createStringError( 504 llvm::inconvertibleErrorCode(), "Unimplemented function"); 505 } 506 507 static std::string LanguageToString(lldb::ScriptLanguage language); 508 509 static lldb::ScriptLanguage StringToLanguage(const llvm::StringRef &string); 510 511 lldb::ScriptLanguage GetLanguage() { return m_script_lang; } 512 513 protected: 514 Debugger &m_debugger; 515 lldb::ScriptLanguage m_script_lang; 516 }; 517 518 } // namespace lldb_private 519 520 #endif // LLDB_INTERPRETER_SCRIPTINTERPRETER_H 521