181ad6265SDimitry Andric //===-- DebuggerEvents.cpp ------------------------------------------------===// 281ad6265SDimitry Andric // 381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric // 781ad6265SDimitry Andric //===----------------------------------------------------------------------===// 881ad6265SDimitry Andric 981ad6265SDimitry Andric #include "lldb/Core/DebuggerEvents.h" 10bdd1243dSDimitry Andric #include "lldb/Core/Debugger.h" 11bdd1243dSDimitry Andric #include "lldb/Core/Module.h" 12*0fca6ea1SDimitry Andric #include "lldb/Core/Progress.h" 1381ad6265SDimitry Andric #include "llvm/Support/WithColor.h" 1481ad6265SDimitry Andric 1581ad6265SDimitry Andric using namespace lldb_private; 16bdd1243dSDimitry Andric using namespace lldb; 1781ad6265SDimitry Andric 1881ad6265SDimitry Andric template <typename T> 1981ad6265SDimitry Andric static const T *GetEventDataFromEventImpl(const Event *event_ptr) { 2081ad6265SDimitry Andric if (event_ptr) 2181ad6265SDimitry Andric if (const EventData *event_data = event_ptr->GetData()) 2281ad6265SDimitry Andric if (event_data->GetFlavor() == T::GetFlavorString()) 2381ad6265SDimitry Andric return static_cast<const T *>(event_ptr->GetData()); 2481ad6265SDimitry Andric return nullptr; 2581ad6265SDimitry Andric } 2681ad6265SDimitry Andric 2706c3fb27SDimitry Andric llvm::StringRef ProgressEventData::GetFlavorString() { 2806c3fb27SDimitry Andric return "ProgressEventData"; 2981ad6265SDimitry Andric } 3081ad6265SDimitry Andric 3106c3fb27SDimitry Andric llvm::StringRef ProgressEventData::GetFlavor() const { 3281ad6265SDimitry Andric return ProgressEventData::GetFlavorString(); 3381ad6265SDimitry Andric } 3481ad6265SDimitry Andric 3581ad6265SDimitry Andric void ProgressEventData::Dump(Stream *s) const { 3606c3fb27SDimitry Andric s->Printf(" id = %" PRIu64 ", title = \"%s\"", m_id, m_title.c_str()); 3706c3fb27SDimitry Andric if (!m_details.empty()) 3806c3fb27SDimitry Andric s->Printf(", details = \"%s\"", m_details.c_str()); 3981ad6265SDimitry Andric if (m_completed == 0 || m_completed == m_total) 4081ad6265SDimitry Andric s->Printf(", type = %s", m_completed == 0 ? "start" : "end"); 4181ad6265SDimitry Andric else 4281ad6265SDimitry Andric s->PutCString(", type = update"); 4381ad6265SDimitry Andric // If m_total is UINT64_MAX, there is no progress to report, just "start" 4481ad6265SDimitry Andric // and "end". If it isn't we will show the completed and total amounts. 45*0fca6ea1SDimitry Andric if (m_total != Progress::kNonDeterministicTotal) 4681ad6265SDimitry Andric s->Printf(", progress = %" PRIu64 " of %" PRIu64, m_completed, m_total); 4781ad6265SDimitry Andric } 4881ad6265SDimitry Andric 4981ad6265SDimitry Andric const ProgressEventData * 5081ad6265SDimitry Andric ProgressEventData::GetEventDataFromEvent(const Event *event_ptr) { 5181ad6265SDimitry Andric return GetEventDataFromEventImpl<ProgressEventData>(event_ptr); 5281ad6265SDimitry Andric } 5381ad6265SDimitry Andric 5406c3fb27SDimitry Andric StructuredData::DictionarySP 5506c3fb27SDimitry Andric ProgressEventData::GetAsStructuredData(const Event *event_ptr) { 5606c3fb27SDimitry Andric const ProgressEventData *progress_data = 5706c3fb27SDimitry Andric ProgressEventData::GetEventDataFromEvent(event_ptr); 5806c3fb27SDimitry Andric 5906c3fb27SDimitry Andric if (!progress_data) 6006c3fb27SDimitry Andric return {}; 6106c3fb27SDimitry Andric 6206c3fb27SDimitry Andric auto dictionary_sp = std::make_shared<StructuredData::Dictionary>(); 6306c3fb27SDimitry Andric dictionary_sp->AddStringItem("title", progress_data->GetTitle()); 6406c3fb27SDimitry Andric dictionary_sp->AddStringItem("details", progress_data->GetDetails()); 6506c3fb27SDimitry Andric dictionary_sp->AddStringItem("message", progress_data->GetMessage()); 6606c3fb27SDimitry Andric dictionary_sp->AddIntegerItem("progress_id", progress_data->GetID()); 6706c3fb27SDimitry Andric dictionary_sp->AddIntegerItem("completed", progress_data->GetCompleted()); 6806c3fb27SDimitry Andric dictionary_sp->AddIntegerItem("total", progress_data->GetTotal()); 6906c3fb27SDimitry Andric dictionary_sp->AddBooleanItem("debugger_specific", 7006c3fb27SDimitry Andric progress_data->IsDebuggerSpecific()); 7106c3fb27SDimitry Andric 7206c3fb27SDimitry Andric return dictionary_sp; 7306c3fb27SDimitry Andric } 7406c3fb27SDimitry Andric 7581ad6265SDimitry Andric llvm::StringRef DiagnosticEventData::GetPrefix() const { 76*0fca6ea1SDimitry Andric switch (m_severity) { 77*0fca6ea1SDimitry Andric case Severity::eSeverityInfo: 78bdd1243dSDimitry Andric return "info"; 79*0fca6ea1SDimitry Andric case Severity::eSeverityWarning: 8081ad6265SDimitry Andric return "warning"; 81*0fca6ea1SDimitry Andric case Severity::eSeverityError: 8281ad6265SDimitry Andric return "error"; 8381ad6265SDimitry Andric } 8481ad6265SDimitry Andric llvm_unreachable("Fully covered switch above!"); 8581ad6265SDimitry Andric } 8681ad6265SDimitry Andric 8781ad6265SDimitry Andric void DiagnosticEventData::Dump(Stream *s) const { 88*0fca6ea1SDimitry Andric llvm::HighlightColor color = m_severity == lldb::eSeverityWarning 8981ad6265SDimitry Andric ? llvm::HighlightColor::Warning 9081ad6265SDimitry Andric : llvm::HighlightColor::Error; 9181ad6265SDimitry Andric llvm::WithColor(s->AsRawOstream(), color, llvm::ColorMode::Enable) 9281ad6265SDimitry Andric << GetPrefix(); 9381ad6265SDimitry Andric *s << ": " << GetMessage() << '\n'; 9481ad6265SDimitry Andric s->Flush(); 9581ad6265SDimitry Andric } 9681ad6265SDimitry Andric 9706c3fb27SDimitry Andric llvm::StringRef DiagnosticEventData::GetFlavorString() { 9806c3fb27SDimitry Andric return "DiagnosticEventData"; 9981ad6265SDimitry Andric } 10081ad6265SDimitry Andric 10106c3fb27SDimitry Andric llvm::StringRef DiagnosticEventData::GetFlavor() const { 10281ad6265SDimitry Andric return DiagnosticEventData::GetFlavorString(); 10381ad6265SDimitry Andric } 10481ad6265SDimitry Andric 10581ad6265SDimitry Andric const DiagnosticEventData * 10681ad6265SDimitry Andric DiagnosticEventData::GetEventDataFromEvent(const Event *event_ptr) { 10781ad6265SDimitry Andric return GetEventDataFromEventImpl<DiagnosticEventData>(event_ptr); 10881ad6265SDimitry Andric } 109bdd1243dSDimitry Andric 11006c3fb27SDimitry Andric StructuredData::DictionarySP 11106c3fb27SDimitry Andric DiagnosticEventData::GetAsStructuredData(const Event *event_ptr) { 11206c3fb27SDimitry Andric const DiagnosticEventData *diagnostic_data = 11306c3fb27SDimitry Andric DiagnosticEventData::GetEventDataFromEvent(event_ptr); 11406c3fb27SDimitry Andric 11506c3fb27SDimitry Andric if (!diagnostic_data) 11606c3fb27SDimitry Andric return {}; 11706c3fb27SDimitry Andric 11806c3fb27SDimitry Andric auto dictionary_sp = std::make_shared<StructuredData::Dictionary>(); 11906c3fb27SDimitry Andric dictionary_sp->AddStringItem("message", diagnostic_data->GetMessage()); 12006c3fb27SDimitry Andric dictionary_sp->AddStringItem("type", diagnostic_data->GetPrefix()); 12106c3fb27SDimitry Andric dictionary_sp->AddBooleanItem("debugger_specific", 12206c3fb27SDimitry Andric diagnostic_data->IsDebuggerSpecific()); 12306c3fb27SDimitry Andric return dictionary_sp; 124bdd1243dSDimitry Andric } 125bdd1243dSDimitry Andric 12606c3fb27SDimitry Andric llvm::StringRef SymbolChangeEventData::GetFlavorString() { 12706c3fb27SDimitry Andric return "SymbolChangeEventData"; 12806c3fb27SDimitry Andric } 12906c3fb27SDimitry Andric 13006c3fb27SDimitry Andric llvm::StringRef SymbolChangeEventData::GetFlavor() const { 131bdd1243dSDimitry Andric return SymbolChangeEventData::GetFlavorString(); 132bdd1243dSDimitry Andric } 133bdd1243dSDimitry Andric 134bdd1243dSDimitry Andric const SymbolChangeEventData * 135bdd1243dSDimitry Andric SymbolChangeEventData::GetEventDataFromEvent(const Event *event_ptr) { 136bdd1243dSDimitry Andric return GetEventDataFromEventImpl<SymbolChangeEventData>(event_ptr); 137bdd1243dSDimitry Andric } 138bdd1243dSDimitry Andric 139bdd1243dSDimitry Andric void SymbolChangeEventData::DoOnRemoval(Event *event_ptr) { 140bdd1243dSDimitry Andric DebuggerSP debugger_sp(m_debugger_wp.lock()); 141bdd1243dSDimitry Andric if (!debugger_sp) 142bdd1243dSDimitry Andric return; 143bdd1243dSDimitry Andric 144bdd1243dSDimitry Andric for (TargetSP target_sp : debugger_sp->GetTargetList().Targets()) { 145bdd1243dSDimitry Andric if (ModuleSP module_sp = 146bdd1243dSDimitry Andric target_sp->GetImages().FindModule(m_module_spec.GetUUID())) { 147bdd1243dSDimitry Andric { 148bdd1243dSDimitry Andric std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 149bdd1243dSDimitry Andric if (!module_sp->GetSymbolFileFileSpec()) 150bdd1243dSDimitry Andric module_sp->SetSymbolFileFileSpec(m_module_spec.GetSymbolFileSpec()); 151bdd1243dSDimitry Andric } 152bdd1243dSDimitry Andric ModuleList module_list; 153bdd1243dSDimitry Andric module_list.Append(module_sp); 154bdd1243dSDimitry Andric target_sp->SymbolsDidLoad(module_list); 155bdd1243dSDimitry Andric } 156bdd1243dSDimitry Andric } 157bdd1243dSDimitry Andric } 158