15ffd83dbSDimitry Andric //===-- Event.cpp ---------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "lldb/Utility/Event.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "lldb/Utility/Broadcaster.h" 120b57cec5SDimitry Andric #include "lldb/Utility/DataExtractor.h" 130b57cec5SDimitry Andric #include "lldb/Utility/Endian.h" 145f757f3fSDimitry Andric #include "lldb/Utility/Listener.h" 150b57cec5SDimitry Andric #include "lldb/Utility/Stream.h" 160b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h" 170b57cec5SDimitry Andric #include "lldb/lldb-enumerations.h" 180b57cec5SDimitry Andric 1906c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h" 2006c3fb27SDimitry Andric 210b57cec5SDimitry Andric #include <algorithm> 220b57cec5SDimitry Andric 23fe6060f1SDimitry Andric #include <cctype> 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric using namespace lldb; 260b57cec5SDimitry Andric using namespace lldb_private; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric #pragma mark - 290b57cec5SDimitry Andric #pragma mark Event 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric // Event functions 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric Event::Event(Broadcaster *broadcaster, uint32_t event_type, EventData *data) 340b57cec5SDimitry Andric : m_broadcaster_wp(broadcaster->GetBroadcasterImpl()), m_type(event_type), 350b57cec5SDimitry Andric m_data_sp(data) {} 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric Event::Event(Broadcaster *broadcaster, uint32_t event_type, 380b57cec5SDimitry Andric const EventDataSP &event_data_sp) 390b57cec5SDimitry Andric : m_broadcaster_wp(broadcaster->GetBroadcasterImpl()), m_type(event_type), 400b57cec5SDimitry Andric m_data_sp(event_data_sp) {} 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric Event::Event(uint32_t event_type, EventData *data) 430b57cec5SDimitry Andric : m_broadcaster_wp(), m_type(event_type), m_data_sp(data) {} 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric Event::Event(uint32_t event_type, const EventDataSP &event_data_sp) 460b57cec5SDimitry Andric : m_broadcaster_wp(), m_type(event_type), m_data_sp(event_data_sp) {} 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric Event::~Event() = default; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric void Event::Dump(Stream *s) const { 510b57cec5SDimitry Andric Broadcaster *broadcaster; 520b57cec5SDimitry Andric Broadcaster::BroadcasterImplSP broadcaster_impl_sp(m_broadcaster_wp.lock()); 530b57cec5SDimitry Andric if (broadcaster_impl_sp) 540b57cec5SDimitry Andric broadcaster = broadcaster_impl_sp->GetBroadcaster(); 550b57cec5SDimitry Andric else 560b57cec5SDimitry Andric broadcaster = nullptr; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric if (broadcaster) { 590b57cec5SDimitry Andric StreamString event_name; 600b57cec5SDimitry Andric if (broadcaster->GetEventNames(event_name, m_type, false)) 610b57cec5SDimitry Andric s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x (%s), data = ", 620b57cec5SDimitry Andric static_cast<const void *>(this), 630b57cec5SDimitry Andric static_cast<void *>(broadcaster), 6406c3fb27SDimitry Andric broadcaster->GetBroadcasterName().c_str(), m_type, 650b57cec5SDimitry Andric event_name.GetData()); 660b57cec5SDimitry Andric else 670b57cec5SDimitry Andric s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x, data = ", 680b57cec5SDimitry Andric static_cast<const void *>(this), 690b57cec5SDimitry Andric static_cast<void *>(broadcaster), 7006c3fb27SDimitry Andric broadcaster->GetBroadcasterName().c_str(), m_type); 710b57cec5SDimitry Andric } else 720b57cec5SDimitry Andric s->Printf("%p Event: broadcaster = NULL, type = 0x%8.8x, data = ", 730b57cec5SDimitry Andric static_cast<const void *>(this), m_type); 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric if (m_data_sp) { 760b57cec5SDimitry Andric s->PutChar('{'); 770b57cec5SDimitry Andric m_data_sp->Dump(s); 780b57cec5SDimitry Andric s->PutChar('}'); 790b57cec5SDimitry Andric } else 800b57cec5SDimitry Andric s->Printf("<NULL>"); 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric void Event::DoOnRemoval() { 845f757f3fSDimitry Andric std::lock_guard<std::mutex> guard(m_listeners_mutex); 855f757f3fSDimitry Andric 86*0fca6ea1SDimitry Andric if (!m_data_sp) 87*0fca6ea1SDimitry Andric return; 88*0fca6ea1SDimitry Andric 890b57cec5SDimitry Andric m_data_sp->DoOnRemoval(this); 90*0fca6ea1SDimitry Andric 915f757f3fSDimitry Andric // Now that the event has been handled by the primary event Listener, forward 925f757f3fSDimitry Andric // it to the other Listeners. 93*0fca6ea1SDimitry Andric 945f757f3fSDimitry Andric EventSP me_sp = shared_from_this(); 95*0fca6ea1SDimitry Andric if (m_data_sp->ForwardEventToPendingListeners(this)) { 965f757f3fSDimitry Andric for (auto listener_sp : m_pending_listeners) 975f757f3fSDimitry Andric listener_sp->AddEvent(me_sp); 985f757f3fSDimitry Andric m_pending_listeners.clear(); 990b57cec5SDimitry Andric } 100*0fca6ea1SDimitry Andric } 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric #pragma mark - 1030b57cec5SDimitry Andric #pragma mark EventData 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric // EventData functions 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric EventData::EventData() = default; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric EventData::~EventData() = default; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric void EventData::Dump(Stream *s) const { s->PutCString("Generic Event Data"); } 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric #pragma mark - 1140b57cec5SDimitry Andric #pragma mark EventDataBytes 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric // EventDataBytes functions 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric EventDataBytes::EventDataBytes() : m_bytes() {} 1190b57cec5SDimitry Andric 120*0fca6ea1SDimitry Andric EventDataBytes::EventDataBytes(llvm::StringRef str) : m_bytes(str.str()) {} 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric EventDataBytes::~EventDataBytes() = default; 1230b57cec5SDimitry Andric 12406c3fb27SDimitry Andric llvm::StringRef EventDataBytes::GetFlavorString() { return "EventDataBytes"; } 1250b57cec5SDimitry Andric 12606c3fb27SDimitry Andric llvm::StringRef EventDataBytes::GetFlavor() const { 1270b57cec5SDimitry Andric return EventDataBytes::GetFlavorString(); 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric void EventDataBytes::Dump(Stream *s) const { 131bdd1243dSDimitry Andric if (llvm::all_of(m_bytes, llvm::isPrint)) 1320b57cec5SDimitry Andric s->Format("\"{0}\"", m_bytes); 1330b57cec5SDimitry Andric else 1340b57cec5SDimitry Andric s->Format("{0:$[ ]@[x-2]}", llvm::make_range( 1350b57cec5SDimitry Andric reinterpret_cast<const uint8_t *>(m_bytes.data()), 1360b57cec5SDimitry Andric reinterpret_cast<const uint8_t *>(m_bytes.data() + 1370b57cec5SDimitry Andric m_bytes.size()))); 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric const void *EventDataBytes::GetBytes() const { 1410b57cec5SDimitry Andric return (m_bytes.empty() ? nullptr : m_bytes.data()); 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric size_t EventDataBytes::GetByteSize() const { return m_bytes.size(); } 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric const void *EventDataBytes::GetBytesFromEvent(const Event *event_ptr) { 1470b57cec5SDimitry Andric const EventDataBytes *e = GetEventDataFromEvent(event_ptr); 1480b57cec5SDimitry Andric if (e != nullptr) 1490b57cec5SDimitry Andric return e->GetBytes(); 1500b57cec5SDimitry Andric return nullptr; 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric size_t EventDataBytes::GetByteSizeFromEvent(const Event *event_ptr) { 1540b57cec5SDimitry Andric const EventDataBytes *e = GetEventDataFromEvent(event_ptr); 1550b57cec5SDimitry Andric if (e != nullptr) 1560b57cec5SDimitry Andric return e->GetByteSize(); 1570b57cec5SDimitry Andric return 0; 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric const EventDataBytes * 1610b57cec5SDimitry Andric EventDataBytes::GetEventDataFromEvent(const Event *event_ptr) { 1620b57cec5SDimitry Andric if (event_ptr != nullptr) { 1630b57cec5SDimitry Andric const EventData *event_data = event_ptr->GetData(); 1640b57cec5SDimitry Andric if (event_data && 1650b57cec5SDimitry Andric event_data->GetFlavor() == EventDataBytes::GetFlavorString()) 1660b57cec5SDimitry Andric return static_cast<const EventDataBytes *>(event_data); 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric return nullptr; 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 17106c3fb27SDimitry Andric llvm::StringRef EventDataReceipt::GetFlavorString() { 17206c3fb27SDimitry Andric return "Process::ProcessEventData"; 17306c3fb27SDimitry Andric } 17406c3fb27SDimitry Andric 1750b57cec5SDimitry Andric #pragma mark - 1760b57cec5SDimitry Andric #pragma mark EventStructuredData 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric // EventDataStructuredData definitions 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric EventDataStructuredData::EventDataStructuredData() 1810b57cec5SDimitry Andric : EventData(), m_process_sp(), m_object_sp(), m_plugin_sp() {} 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric EventDataStructuredData::EventDataStructuredData( 1840b57cec5SDimitry Andric const ProcessSP &process_sp, const StructuredData::ObjectSP &object_sp, 1850b57cec5SDimitry Andric const lldb::StructuredDataPluginSP &plugin_sp) 1860b57cec5SDimitry Andric : EventData(), m_process_sp(process_sp), m_object_sp(object_sp), 1870b57cec5SDimitry Andric m_plugin_sp(plugin_sp) {} 1880b57cec5SDimitry Andric 189fe6060f1SDimitry Andric EventDataStructuredData::~EventDataStructuredData() = default; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric // EventDataStructuredData member functions 1920b57cec5SDimitry Andric 19306c3fb27SDimitry Andric llvm::StringRef EventDataStructuredData::GetFlavor() const { 1940b57cec5SDimitry Andric return EventDataStructuredData::GetFlavorString(); 1950b57cec5SDimitry Andric } 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric void EventDataStructuredData::Dump(Stream *s) const { 1980b57cec5SDimitry Andric if (!s) 1990b57cec5SDimitry Andric return; 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric if (m_object_sp) 2020b57cec5SDimitry Andric m_object_sp->Dump(*s); 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric const ProcessSP &EventDataStructuredData::GetProcess() const { 2060b57cec5SDimitry Andric return m_process_sp; 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric const StructuredData::ObjectSP &EventDataStructuredData::GetObject() const { 2100b57cec5SDimitry Andric return m_object_sp; 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric const lldb::StructuredDataPluginSP & 2140b57cec5SDimitry Andric EventDataStructuredData::GetStructuredDataPlugin() const { 2150b57cec5SDimitry Andric return m_plugin_sp; 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric void EventDataStructuredData::SetProcess(const ProcessSP &process_sp) { 2190b57cec5SDimitry Andric m_process_sp = process_sp; 2200b57cec5SDimitry Andric } 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric void EventDataStructuredData::SetObject( 2230b57cec5SDimitry Andric const StructuredData::ObjectSP &object_sp) { 2240b57cec5SDimitry Andric m_object_sp = object_sp; 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric void EventDataStructuredData::SetStructuredDataPlugin( 2280b57cec5SDimitry Andric const lldb::StructuredDataPluginSP &plugin_sp) { 2290b57cec5SDimitry Andric m_plugin_sp = plugin_sp; 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric // EventDataStructuredData static functions 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric const EventDataStructuredData * 2350b57cec5SDimitry Andric EventDataStructuredData::GetEventDataFromEvent(const Event *event_ptr) { 2360b57cec5SDimitry Andric if (event_ptr == nullptr) 2370b57cec5SDimitry Andric return nullptr; 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric const EventData *event_data = event_ptr->GetData(); 2400b57cec5SDimitry Andric if (!event_data || 2410b57cec5SDimitry Andric event_data->GetFlavor() != EventDataStructuredData::GetFlavorString()) 2420b57cec5SDimitry Andric return nullptr; 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric return static_cast<const EventDataStructuredData *>(event_data); 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric ProcessSP EventDataStructuredData::GetProcessFromEvent(const Event *event_ptr) { 2480b57cec5SDimitry Andric auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr); 2490b57cec5SDimitry Andric if (event_data) 2500b57cec5SDimitry Andric return event_data->GetProcess(); 2510b57cec5SDimitry Andric else 2520b57cec5SDimitry Andric return ProcessSP(); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric StructuredData::ObjectSP 2560b57cec5SDimitry Andric EventDataStructuredData::GetObjectFromEvent(const Event *event_ptr) { 2570b57cec5SDimitry Andric auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr); 2580b57cec5SDimitry Andric if (event_data) 2590b57cec5SDimitry Andric return event_data->GetObject(); 2600b57cec5SDimitry Andric else 2610b57cec5SDimitry Andric return StructuredData::ObjectSP(); 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric lldb::StructuredDataPluginSP 2650b57cec5SDimitry Andric EventDataStructuredData::GetPluginFromEvent(const Event *event_ptr) { 2660b57cec5SDimitry Andric auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr); 2670b57cec5SDimitry Andric if (event_data) 2680b57cec5SDimitry Andric return event_data->GetStructuredDataPlugin(); 2690b57cec5SDimitry Andric else 2700b57cec5SDimitry Andric return StructuredDataPluginSP(); 2710b57cec5SDimitry Andric } 2720b57cec5SDimitry Andric 27306c3fb27SDimitry Andric llvm::StringRef EventDataStructuredData::GetFlavorString() { 27406c3fb27SDimitry Andric return "EventDataStructuredData"; 2750b57cec5SDimitry Andric } 276