xref: /freebsd-src/contrib/llvm-project/lldb/source/Utility/Event.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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