1 //===-- DebuggerEvents.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/Core/DebuggerEvents.h" 10 #include "lldb/Core/Debugger.h" 11 #include "lldb/Core/Module.h" 12 #include "lldb/Core/Progress.h" 13 #include "llvm/Support/WithColor.h" 14 15 using namespace lldb_private; 16 using namespace lldb; 17 18 template <typename T> 19 static const T *GetEventDataFromEventImpl(const Event *event_ptr) { 20 if (event_ptr) 21 if (const EventData *event_data = event_ptr->GetData()) 22 if (event_data->GetFlavor() == T::GetFlavorString()) 23 return static_cast<const T *>(event_ptr->GetData()); 24 return nullptr; 25 } 26 27 llvm::StringRef ProgressEventData::GetFlavorString() { 28 return "ProgressEventData"; 29 } 30 31 llvm::StringRef ProgressEventData::GetFlavor() const { 32 return ProgressEventData::GetFlavorString(); 33 } 34 35 void ProgressEventData::Dump(Stream *s) const { 36 s->Printf(" id = %" PRIu64 ", title = \"%s\"", m_id, m_title.c_str()); 37 if (!m_details.empty()) 38 s->Printf(", details = \"%s\"", m_details.c_str()); 39 if (m_completed == 0 || m_completed == m_total) 40 s->Printf(", type = %s", m_completed == 0 ? "start" : "end"); 41 else 42 s->PutCString(", type = update"); 43 // If m_total is UINT64_MAX, there is no progress to report, just "start" 44 // and "end". If it isn't we will show the completed and total amounts. 45 if (m_total != Progress::kNonDeterministicTotal) 46 s->Printf(", progress = %" PRIu64 " of %" PRIu64, m_completed, m_total); 47 } 48 49 const ProgressEventData * 50 ProgressEventData::GetEventDataFromEvent(const Event *event_ptr) { 51 return GetEventDataFromEventImpl<ProgressEventData>(event_ptr); 52 } 53 54 StructuredData::DictionarySP 55 ProgressEventData::GetAsStructuredData(const Event *event_ptr) { 56 const ProgressEventData *progress_data = 57 ProgressEventData::GetEventDataFromEvent(event_ptr); 58 59 if (!progress_data) 60 return {}; 61 62 auto dictionary_sp = std::make_shared<StructuredData::Dictionary>(); 63 dictionary_sp->AddStringItem("title", progress_data->GetTitle()); 64 dictionary_sp->AddStringItem("details", progress_data->GetDetails()); 65 dictionary_sp->AddStringItem("message", progress_data->GetMessage()); 66 dictionary_sp->AddIntegerItem("progress_id", progress_data->GetID()); 67 dictionary_sp->AddIntegerItem("completed", progress_data->GetCompleted()); 68 dictionary_sp->AddIntegerItem("total", progress_data->GetTotal()); 69 dictionary_sp->AddBooleanItem("debugger_specific", 70 progress_data->IsDebuggerSpecific()); 71 72 return dictionary_sp; 73 } 74 75 llvm::StringRef DiagnosticEventData::GetPrefix() const { 76 switch (m_severity) { 77 case Severity::eSeverityInfo: 78 return "info"; 79 case Severity::eSeverityWarning: 80 return "warning"; 81 case Severity::eSeverityError: 82 return "error"; 83 } 84 llvm_unreachable("Fully covered switch above!"); 85 } 86 87 void DiagnosticEventData::Dump(Stream *s) const { 88 llvm::HighlightColor color = m_severity == lldb::eSeverityWarning 89 ? llvm::HighlightColor::Warning 90 : llvm::HighlightColor::Error; 91 llvm::WithColor(s->AsRawOstream(), color, llvm::ColorMode::Enable) 92 << GetPrefix(); 93 *s << ": " << GetMessage() << '\n'; 94 s->Flush(); 95 } 96 97 llvm::StringRef DiagnosticEventData::GetFlavorString() { 98 return "DiagnosticEventData"; 99 } 100 101 llvm::StringRef DiagnosticEventData::GetFlavor() const { 102 return DiagnosticEventData::GetFlavorString(); 103 } 104 105 const DiagnosticEventData * 106 DiagnosticEventData::GetEventDataFromEvent(const Event *event_ptr) { 107 return GetEventDataFromEventImpl<DiagnosticEventData>(event_ptr); 108 } 109 110 StructuredData::DictionarySP 111 DiagnosticEventData::GetAsStructuredData(const Event *event_ptr) { 112 const DiagnosticEventData *diagnostic_data = 113 DiagnosticEventData::GetEventDataFromEvent(event_ptr); 114 115 if (!diagnostic_data) 116 return {}; 117 118 auto dictionary_sp = std::make_shared<StructuredData::Dictionary>(); 119 dictionary_sp->AddStringItem("message", diagnostic_data->GetMessage()); 120 dictionary_sp->AddStringItem("type", diagnostic_data->GetPrefix()); 121 dictionary_sp->AddBooleanItem("debugger_specific", 122 diagnostic_data->IsDebuggerSpecific()); 123 return dictionary_sp; 124 } 125 126 llvm::StringRef SymbolChangeEventData::GetFlavorString() { 127 return "SymbolChangeEventData"; 128 } 129 130 llvm::StringRef SymbolChangeEventData::GetFlavor() const { 131 return SymbolChangeEventData::GetFlavorString(); 132 } 133 134 const SymbolChangeEventData * 135 SymbolChangeEventData::GetEventDataFromEvent(const Event *event_ptr) { 136 return GetEventDataFromEventImpl<SymbolChangeEventData>(event_ptr); 137 } 138 139 void SymbolChangeEventData::DoOnRemoval(Event *event_ptr) { 140 DebuggerSP debugger_sp(m_debugger_wp.lock()); 141 if (!debugger_sp) 142 return; 143 144 for (TargetSP target_sp : debugger_sp->GetTargetList().Targets()) { 145 if (ModuleSP module_sp = 146 target_sp->GetImages().FindModule(m_module_spec.GetUUID())) { 147 { 148 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 149 if (!module_sp->GetSymbolFileFileSpec()) 150 module_sp->SetSymbolFileFileSpec(m_module_spec.GetSymbolFileSpec()); 151 } 152 ModuleList module_list; 153 module_list.Append(module_sp); 154 target_sp->SymbolsDidLoad(module_list); 155 } 156 } 157 } 158