1 //===-- StructuredDataPlugin.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_TARGET_STRUCTUREDDATAPLUGIN_H 10 #define LLDB_TARGET_STRUCTUREDDATAPLUGIN_H 11 12 #include "lldb/Core/PluginInterface.h" 13 #include "lldb/Utility/StructuredData.h" 14 15 namespace lldb_private { 16 17 class CommandObjectMultiword; 18 19 /// Plugin that supports process-related structured data sent asynchronously 20 /// from the debug monitor (e.g. debugserver, lldb-server, etc.) 21 /// 22 /// This plugin type is activated by a Process-derived instance when that 23 /// instance detects that a given structured data feature is available. 24 /// 25 /// StructuredDataPlugin instances are inherently tied to a process. The 26 /// main functionality they support is the ability to consume asynchronously- 27 /// delivered structured data from the process monitor, and do something 28 /// reasonable with it. Something reasonable can include broadcasting a 29 /// StructuredData event, which other parts of the system can then do with 30 /// as they please. An IDE could use this facility to retrieve CPU usage, 31 /// memory usage, and other run-time aspects of the process. That data 32 /// can then be displayed meaningfully to the user through the IDE. 33 34 /// For command-line LLDB, the Debugger instance listens for the structured 35 /// data events raised by the plugin, and give the plugin both the output 36 /// and error streams such that the plugin can display something about the 37 /// event, at a time when the debugger ensures it is safe to write to the 38 /// output or error streams. 39 40 class StructuredDataPlugin 41 : public PluginInterface, 42 public std::enable_shared_from_this<StructuredDataPlugin> { 43 public: 44 ~StructuredDataPlugin() override; 45 46 lldb::ProcessSP GetProcess() const; 47 48 // Public instance API 49 50 /// Return whether this plugin supports the given StructuredData feature. 51 /// 52 /// When Process is informed of a list of process-monitor-supported 53 /// structured data features, Process will go through the list of plugins, 54 /// one at a time, and have the first plugin that supports a given feature 55 /// be the plugin instantiated to handle that feature. There is a 1-1 56 /// correspondence between a Process instance and a StructuredDataPlugin 57 /// mapped to that process. A plugin can support handling multiple 58 /// features, and if that happens, there is a single plugin instance 59 /// created covering all of the mapped features for a given process. 60 /// 61 /// \param[in] type_name 62 /// The name of the feature tag supported by a process. 63 /// e.g. "darwin-log". 64 /// 65 /// \return 66 /// true if the plugin supports the feature; otherwise, false. 67 virtual bool SupportsStructuredDataType(ConstString type_name) = 0; 68 69 /// Handle the arrival of asynchronous structured data from the process. 70 /// 71 /// When asynchronous structured data arrives from the process monitor, 72 /// it is immediately delivered to the plugin mapped for that feature 73 /// if one exists. The structured data that arrives from a process 74 /// monitor must be a dictionary, and it must have a string field named 75 /// "type" that must contain the StructuredData feature name set as the 76 /// value. This is the manner in which the data is routed to the proper 77 /// plugin instance. 78 /// 79 /// \param[in] process 80 /// The process instance that just received the structured data. 81 /// This will always be the same process for a given instance of 82 /// a plugin. 83 /// 84 /// \param[in] type_name 85 /// The name of the feature tag for the asynchronous structured data. 86 /// Note this data will also be present in the \b object_sp dictionary 87 /// under the string value with key "type". 88 /// 89 /// \param[in] object_sp 90 /// A shared pointer to the structured data that arrived. This must 91 /// be a dictionary. The only key required is the aforementioned 92 /// key named "type" that must be a string value containing the 93 /// structured data type name. 94 virtual void 95 HandleArrivalOfStructuredData(Process &process, ConstString type_name, 96 const StructuredData::ObjectSP &object_sp) = 0; 97 98 /// Get a human-readable description of the contents of the data. 99 /// 100 /// In command-line LLDB, this method will be called by the Debugger 101 /// instance for each structured data event generated, and the output 102 /// will be printed to the LLDB console. If nothing is added to the stream, 103 /// nothing will be printed; otherwise, a newline will be added to the end 104 /// when displayed. 105 /// 106 /// \param[in] object_sp 107 /// A shared pointer to the structured data to format. 108 /// 109 /// \param[in] stream 110 /// The stream where the structured data should be pretty printed. 111 /// 112 /// \return 113 /// The error if formatting the object contents failed; otherwise, 114 /// success. 115 virtual Status GetDescription(const StructuredData::ObjectSP &object_sp, 116 lldb_private::Stream &stream) = 0; 117 118 /// Returns whether the plugin's features are enabled. 119 /// 120 /// This is a convenience method for plugins that can enable or disable 121 /// their functionality. It allows retrieval of this state without 122 /// requiring a cast. 123 /// 124 /// \param[in] type_name 125 /// The name of the feature tag for the asynchronous structured data. 126 /// This is needed for plugins that support more than one feature. 127 virtual bool GetEnabled(ConstString type_name) const; 128 129 /// Allow the plugin to do work related to modules that loaded in the 130 /// the corresponding process. 131 /// 132 /// This method defaults to doing nothing. Plugins can override it 133 /// if they have any behavior they want to enable/modify based on loaded 134 /// modules. 135 /// 136 /// \param[in] process 137 /// The process that just was notified of modules having been loaded. 138 /// This will always be the same process for a given instance of 139 /// a plugin. 140 /// 141 /// \param[in] module_list 142 /// The list of modules that the process registered as having just 143 /// loaded. See \b Process::ModulesDidLoad(...). 144 virtual void ModulesDidLoad(Process &process, ModuleList &module_list); 145 146 protected: 147 // Derived-class API 148 StructuredDataPlugin(const lldb::ProcessWP &process_wp); 149 150 /// Derived classes must call this before attempting to hook up commands 151 /// to the 'plugin structured-data' tree. 152 /// 153 /// This ensures the relevant command and options hook points for all 154 /// StructuredDataPlugin derived classes are available for this debugger. 155 /// If this has already happened, this call is a no-op. 156 /// 157 /// \param[in] debugger 158 /// The Debugger instance for which we're creating the required shared 159 /// components for the StructuredDataPlugin derived classes. 160 static void InitializeBasePluginForDebugger(Debugger &debugger); 161 162 private: 163 lldb::ProcessWP m_process_wp; 164 165 StructuredDataPlugin(const StructuredDataPlugin &) = delete; 166 const StructuredDataPlugin &operator=(const StructuredDataPlugin &) = delete; 167 }; 168 } 169 170 #endif 171