Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 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 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 9 | #ifndef LLDB_TARGET_STRUCTUREDDATAPLUGIN_H |
| 10 | #define LLDB_TARGET_STRUCTUREDDATAPLUGIN_H |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 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 | |
Olivier Deprez | f4ef2d0 | 2021-04-20 13:36:24 +0200 | [diff] [blame] | 165 | StructuredDataPlugin(const StructuredDataPlugin &) = delete; |
| 166 | const StructuredDataPlugin &operator=(const StructuredDataPlugin &) = delete; |
Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 167 | }; |
| 168 | } |
| 169 | |
| 170 | #endif |