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(event_name, m_type, false)) 61 s->Printf("%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("%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("%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('{'); 77 m_data_sp->Dump(s); 78 s->PutChar('}'); 79 } else 80 s->Printf("<NULL>"); 81 } 82 83 void Event::DoOnRemoval() { 84 std::lock_guard<std::mutex> guard(m_listeners_mutex); 85 86 if (!m_data_sp) 87 return; 88 89 m_data_sp->DoOnRemoval(this); 90 91 // Now that the event has been handled by the primary event Listener, forward 92 // it to the other Listeners. 93 94 EventSP me_sp = shared_from_this(); 95 if (m_data_sp->ForwardEventToPendingListeners(this)) { 96 for (auto listener_sp : m_pending_listeners) 97 listener_sp->AddEvent(me_sp); 98 m_pending_listeners.clear(); 99 } 100 } 101 102 #pragma mark - 103 #pragma mark EventData 104 105 // EventData functions 106 107 EventData::EventData() = default; 108 109 EventData::~EventData() = default; 110 111 void EventData::Dump(Stream *s) const { s->PutCString("Generic Event Data"); } 112 113 #pragma mark - 114 #pragma mark EventDataBytes 115 116 // EventDataBytes functions 117 118 EventDataBytes::EventDataBytes() : m_bytes() {} 119 120 EventDataBytes::EventDataBytes(llvm::StringRef str) : m_bytes(str.str()) {} 121 122 EventDataBytes::~EventDataBytes() = default; 123 124 llvm::StringRef EventDataBytes::GetFlavorString() { return "EventDataBytes"; } 125 126 llvm::StringRef EventDataBytes::GetFlavor() const { 127 return EventDataBytes::GetFlavorString(); 128 } 129 130 void EventDataBytes::Dump(Stream *s) const { 131 if (llvm::all_of(m_bytes, llvm::isPrint)) 132 s->Format("\"{0}\"", m_bytes); 133 else 134 s->Format("{0:$[ ]@[x-2]}", llvm::make_range( 135 reinterpret_cast<const uint8_t *>(m_bytes.data()), 136 reinterpret_cast<const uint8_t *>(m_bytes.data() + 137 m_bytes.size()))); 138 } 139 140 const void *EventDataBytes::GetBytes() const { 141 return (m_bytes.empty() ? nullptr : m_bytes.data()); 142 } 143 144 size_t EventDataBytes::GetByteSize() const { return m_bytes.size(); } 145 146 const void *EventDataBytes::GetBytesFromEvent(const Event *event_ptr) { 147 const EventDataBytes *e = GetEventDataFromEvent(event_ptr); 148 if (e != nullptr) 149 return e->GetBytes(); 150 return nullptr; 151 } 152 153 size_t EventDataBytes::GetByteSizeFromEvent(const Event *event_ptr) { 154 const EventDataBytes *e = GetEventDataFromEvent(event_ptr); 155 if (e != nullptr) 156 return e->GetByteSize(); 157 return 0; 158 } 159 160 const EventDataBytes * 161 EventDataBytes::GetEventDataFromEvent(const Event *event_ptr) { 162 if (event_ptr != nullptr) { 163 const EventData *event_data = event_ptr->GetData(); 164 if (event_data && 165 event_data->GetFlavor() == EventDataBytes::GetFlavorString()) 166 return static_cast<const EventDataBytes *>(event_data); 167 } 168 return nullptr; 169 } 170 171 llvm::StringRef EventDataReceipt::GetFlavorString() { 172 return "Process::ProcessEventData"; 173 } 174 175 #pragma mark - 176 #pragma mark EventStructuredData 177 178 // EventDataStructuredData definitions 179 180 EventDataStructuredData::EventDataStructuredData() 181 : EventData(), m_process_sp(), m_object_sp(), m_plugin_sp() {} 182 183 EventDataStructuredData::EventDataStructuredData( 184 const ProcessSP &process_sp, const StructuredData::ObjectSP &object_sp, 185 const lldb::StructuredDataPluginSP &plugin_sp) 186 : EventData(), m_process_sp(process_sp), m_object_sp(object_sp), 187 m_plugin_sp(plugin_sp) {} 188 189 EventDataStructuredData::~EventDataStructuredData() = default; 190 191 // EventDataStructuredData member functions 192 193 llvm::StringRef EventDataStructuredData::GetFlavor() const { 194 return EventDataStructuredData::GetFlavorString(); 195 } 196 197 void EventDataStructuredData::Dump(Stream *s) const { 198 if (!s) 199 return; 200 201 if (m_object_sp) 202 m_object_sp->Dump(*s); 203 } 204 205 const ProcessSP &EventDataStructuredData::GetProcess() const { 206 return m_process_sp; 207 } 208 209 const StructuredData::ObjectSP &EventDataStructuredData::GetObject() const { 210 return m_object_sp; 211 } 212 213 const lldb::StructuredDataPluginSP & 214 EventDataStructuredData::GetStructuredDataPlugin() const { 215 return m_plugin_sp; 216 } 217 218 void EventDataStructuredData::SetProcess(const ProcessSP &process_sp) { 219 m_process_sp = process_sp; 220 } 221 222 void EventDataStructuredData::SetObject( 223 const StructuredData::ObjectSP &object_sp) { 224 m_object_sp = object_sp; 225 } 226 227 void EventDataStructuredData::SetStructuredDataPlugin( 228 const lldb::StructuredDataPluginSP &plugin_sp) { 229 m_plugin_sp = plugin_sp; 230 } 231 232 // EventDataStructuredData static functions 233 234 const EventDataStructuredData * 235 EventDataStructuredData::GetEventDataFromEvent(const Event *event_ptr) { 236 if (event_ptr == nullptr) 237 return nullptr; 238 239 const EventData *event_data = event_ptr->GetData(); 240 if (!event_data || 241 event_data->GetFlavor() != EventDataStructuredData::GetFlavorString()) 242 return nullptr; 243 244 return static_cast<const EventDataStructuredData *>(event_data); 245 } 246 247 ProcessSP EventDataStructuredData::GetProcessFromEvent(const Event *event_ptr) { 248 auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr); 249 if (event_data) 250 return event_data->GetProcess(); 251 else 252 return ProcessSP(); 253 } 254 255 StructuredData::ObjectSP 256 EventDataStructuredData::GetObjectFromEvent(const Event *event_ptr) { 257 auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr); 258 if (event_data) 259 return event_data->GetObject(); 260 else 261 return StructuredData::ObjectSP(); 262 } 263 264 lldb::StructuredDataPluginSP 265 EventDataStructuredData::GetPluginFromEvent(const Event *event_ptr) { 266 auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr); 267 if (event_data) 268 return event_data->GetStructuredDataPlugin(); 269 else 270 return StructuredDataPluginSP(); 271 } 272 273 llvm::StringRef EventDataStructuredData::GetFlavorString() { 274 return "EventDataStructuredData"; 275 } 276