1 | //===-- Event.cpp ---------------------------------------------------------===// |
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 | #include "lldb/Utility/Event.h" |
10 | |
11 | #include "lldb/Utility/Broadcaster.h" |
12 | #include "lldb/Utility/DataExtractor.h" |
13 | #include "lldb/Utility/Endian.h" |
14 | #include "lldb/Utility/Listener.h" |
15 | #include "lldb/Utility/Stream.h" |
16 | #include "lldb/Utility/StreamString.h" |
17 | #include "lldb/lldb-enumerations.h" |
18 | |
19 | #include "llvm/ADT/StringExtras.h" |
20 | |
21 | #include <algorithm> |
22 | |
23 | #include <cctype> |
24 | |
25 | using namespace lldb; |
26 | using namespace lldb_private; |
27 | |
28 | #pragma mark - |
29 | #pragma mark Event |
30 | |
31 | // Event functions |
32 | |
33 | Event::Event(Broadcaster *broadcaster, uint32_t event_type, EventData *data) |
34 | : m_broadcaster_wp(broadcaster->GetBroadcasterImpl()), m_type(event_type), |
35 | m_data_sp(data) {} |
36 | |
37 | Event::Event(Broadcaster *broadcaster, uint32_t event_type, |
38 | const EventDataSP &event_data_sp) |
39 | : m_broadcaster_wp(broadcaster->GetBroadcasterImpl()), m_type(event_type), |
40 | m_data_sp(event_data_sp) {} |
41 | |
42 | Event::Event(uint32_t event_type, EventData *data) |
43 | : m_broadcaster_wp(), m_type(event_type), m_data_sp(data) {} |
44 | |
45 | Event::Event(uint32_t event_type, const EventDataSP &event_data_sp) |
46 | : m_broadcaster_wp(), m_type(event_type), m_data_sp(event_data_sp) {} |
47 | |
48 | Event::~Event() = default; |
49 | |
50 | void Event::Dump(Stream *s) const { |
51 | Broadcaster *broadcaster; |
52 | Broadcaster::BroadcasterImplSP broadcaster_impl_sp(m_broadcaster_wp.lock()); |
53 | if (broadcaster_impl_sp) |
54 | broadcaster = broadcaster_impl_sp->GetBroadcaster(); |
55 | else |
56 | broadcaster = nullptr; |
57 | |
58 | if (broadcaster) { |
59 | StreamString event_name; |
60 | if (broadcaster->GetEventNames(s&: event_name, event_mask: m_type, prefix_with_broadcaster_name: false)) |
61 | s->Printf(format: "%p Event: broadcaster = %p (%s), type = 0x%8.8x (%s), data = " , |
62 | static_cast<const void *>(this), |
63 | static_cast<void *>(broadcaster), |
64 | broadcaster->GetBroadcasterName().c_str(), m_type, |
65 | event_name.GetData()); |
66 | else |
67 | s->Printf(format: "%p Event: broadcaster = %p (%s), type = 0x%8.8x, data = " , |
68 | static_cast<const void *>(this), |
69 | static_cast<void *>(broadcaster), |
70 | broadcaster->GetBroadcasterName().c_str(), m_type); |
71 | } else |
72 | s->Printf(format: "%p Event: broadcaster = NULL, type = 0x%8.8x, data = " , |
73 | static_cast<const void *>(this), m_type); |
74 | |
75 | if (m_data_sp) { |
76 | s->PutChar(ch: '{'); |
77 | m_data_sp->Dump(s); |
78 | s->PutChar(ch: '}'); |
79 | } else |
80 | s->Printf(format: "<NULL>" ); |
81 | } |
82 | |
83 | void Event::DoOnRemoval() { |
84 | std::lock_guard<std::mutex> guard(m_listeners_mutex); |
85 | |
86 | if (m_data_sp) |
87 | m_data_sp->DoOnRemoval(event_ptr: this); |
88 | // Now that the event has been handled by the primary event Listener, forward |
89 | // it to the other Listeners. |
90 | EventSP me_sp = shared_from_this(); |
91 | for (auto listener_sp : m_pending_listeners) |
92 | listener_sp->AddEvent(event&: me_sp); |
93 | m_pending_listeners.clear(); |
94 | } |
95 | |
96 | #pragma mark - |
97 | #pragma mark EventData |
98 | |
99 | // EventData functions |
100 | |
101 | EventData::EventData() = default; |
102 | |
103 | EventData::~EventData() = default; |
104 | |
105 | void EventData::Dump(Stream *s) const { s->PutCString(cstr: "Generic Event Data" ); } |
106 | |
107 | #pragma mark - |
108 | #pragma mark EventDataBytes |
109 | |
110 | // EventDataBytes functions |
111 | |
112 | EventDataBytes::EventDataBytes() : m_bytes() {} |
113 | |
114 | EventDataBytes::EventDataBytes(llvm::StringRef str) : m_bytes(str.str()) {} |
115 | |
116 | EventDataBytes::~EventDataBytes() = default; |
117 | |
118 | llvm::StringRef EventDataBytes::GetFlavorString() { return "EventDataBytes" ; } |
119 | |
120 | llvm::StringRef EventDataBytes::GetFlavor() const { |
121 | return EventDataBytes::GetFlavorString(); |
122 | } |
123 | |
124 | void EventDataBytes::Dump(Stream *s) const { |
125 | if (llvm::all_of(Range: m_bytes, P: llvm::isPrint)) |
126 | s->Format(format: "\"{0}\"" , args: m_bytes); |
127 | else |
128 | s->Format(format: "{0:$[ ]@[x-2]}" , args: llvm::make_range( |
129 | x: reinterpret_cast<const uint8_t *>(m_bytes.data()), |
130 | y: reinterpret_cast<const uint8_t *>(m_bytes.data() + |
131 | m_bytes.size()))); |
132 | } |
133 | |
134 | const void *EventDataBytes::GetBytes() const { |
135 | return (m_bytes.empty() ? nullptr : m_bytes.data()); |
136 | } |
137 | |
138 | size_t EventDataBytes::GetByteSize() const { return m_bytes.size(); } |
139 | |
140 | const void *EventDataBytes::GetBytesFromEvent(const Event *event_ptr) { |
141 | const EventDataBytes *e = GetEventDataFromEvent(event_ptr); |
142 | if (e != nullptr) |
143 | return e->GetBytes(); |
144 | return nullptr; |
145 | } |
146 | |
147 | size_t EventDataBytes::GetByteSizeFromEvent(const Event *event_ptr) { |
148 | const EventDataBytes *e = GetEventDataFromEvent(event_ptr); |
149 | if (e != nullptr) |
150 | return e->GetByteSize(); |
151 | return 0; |
152 | } |
153 | |
154 | const EventDataBytes * |
155 | EventDataBytes::GetEventDataFromEvent(const Event *event_ptr) { |
156 | if (event_ptr != nullptr) { |
157 | const EventData *event_data = event_ptr->GetData(); |
158 | if (event_data && |
159 | event_data->GetFlavor() == EventDataBytes::GetFlavorString()) |
160 | return static_cast<const EventDataBytes *>(event_data); |
161 | } |
162 | return nullptr; |
163 | } |
164 | |
165 | llvm::StringRef EventDataReceipt::GetFlavorString() { |
166 | return "Process::ProcessEventData" ; |
167 | } |
168 | |
169 | #pragma mark - |
170 | #pragma mark EventStructuredData |
171 | |
172 | // EventDataStructuredData definitions |
173 | |
174 | EventDataStructuredData::EventDataStructuredData() |
175 | : EventData(), m_process_sp(), m_object_sp(), m_plugin_sp() {} |
176 | |
177 | EventDataStructuredData::EventDataStructuredData( |
178 | const ProcessSP &process_sp, const StructuredData::ObjectSP &object_sp, |
179 | const lldb::StructuredDataPluginSP &plugin_sp) |
180 | : EventData(), m_process_sp(process_sp), m_object_sp(object_sp), |
181 | m_plugin_sp(plugin_sp) {} |
182 | |
183 | EventDataStructuredData::~EventDataStructuredData() = default; |
184 | |
185 | // EventDataStructuredData member functions |
186 | |
187 | llvm::StringRef EventDataStructuredData::GetFlavor() const { |
188 | return EventDataStructuredData::GetFlavorString(); |
189 | } |
190 | |
191 | void EventDataStructuredData::Dump(Stream *s) const { |
192 | if (!s) |
193 | return; |
194 | |
195 | if (m_object_sp) |
196 | m_object_sp->Dump(s&: *s); |
197 | } |
198 | |
199 | const ProcessSP &EventDataStructuredData::GetProcess() const { |
200 | return m_process_sp; |
201 | } |
202 | |
203 | const StructuredData::ObjectSP &EventDataStructuredData::GetObject() const { |
204 | return m_object_sp; |
205 | } |
206 | |
207 | const lldb::StructuredDataPluginSP & |
208 | EventDataStructuredData::GetStructuredDataPlugin() const { |
209 | return m_plugin_sp; |
210 | } |
211 | |
212 | void EventDataStructuredData::SetProcess(const ProcessSP &process_sp) { |
213 | m_process_sp = process_sp; |
214 | } |
215 | |
216 | void EventDataStructuredData::SetObject( |
217 | const StructuredData::ObjectSP &object_sp) { |
218 | m_object_sp = object_sp; |
219 | } |
220 | |
221 | void EventDataStructuredData::SetStructuredDataPlugin( |
222 | const lldb::StructuredDataPluginSP &plugin_sp) { |
223 | m_plugin_sp = plugin_sp; |
224 | } |
225 | |
226 | // EventDataStructuredData static functions |
227 | |
228 | const EventDataStructuredData * |
229 | EventDataStructuredData::GetEventDataFromEvent(const Event *event_ptr) { |
230 | if (event_ptr == nullptr) |
231 | return nullptr; |
232 | |
233 | const EventData *event_data = event_ptr->GetData(); |
234 | if (!event_data || |
235 | event_data->GetFlavor() != EventDataStructuredData::GetFlavorString()) |
236 | return nullptr; |
237 | |
238 | return static_cast<const EventDataStructuredData *>(event_data); |
239 | } |
240 | |
241 | ProcessSP EventDataStructuredData::GetProcessFromEvent(const Event *event_ptr) { |
242 | auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr); |
243 | if (event_data) |
244 | return event_data->GetProcess(); |
245 | else |
246 | return ProcessSP(); |
247 | } |
248 | |
249 | StructuredData::ObjectSP |
250 | EventDataStructuredData::GetObjectFromEvent(const Event *event_ptr) { |
251 | auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr); |
252 | if (event_data) |
253 | return event_data->GetObject(); |
254 | else |
255 | return StructuredData::ObjectSP(); |
256 | } |
257 | |
258 | lldb::StructuredDataPluginSP |
259 | EventDataStructuredData::GetPluginFromEvent(const Event *event_ptr) { |
260 | auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr); |
261 | if (event_data) |
262 | return event_data->GetStructuredDataPlugin(); |
263 | else |
264 | return StructuredDataPluginSP(); |
265 | } |
266 | |
267 | llvm::StringRef EventDataStructuredData::GetFlavorString() { |
268 | return "EventDataStructuredData" ; |
269 | } |
270 | |