Path: blob/main/contrib/llvm-project/lldb/source/Utility/Diagnostics.cpp
39587 views
//===-- Diagnostics.cpp ---------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Utility/Diagnostics.h"9#include "lldb/Utility/LLDBAssert.h"1011#include "llvm/Support/Error.h"12#include "llvm/Support/FileSystem.h"13#include "llvm/Support/raw_ostream.h"14#include <optional>1516using namespace lldb_private;17using namespace lldb;18using namespace llvm;1920static constexpr size_t g_num_log_messages = 100;2122void Diagnostics::Initialize() {23lldbassert(!InstanceImpl() && "Already initialized.");24InstanceImpl().emplace();25}2627void Diagnostics::Terminate() {28lldbassert(InstanceImpl() && "Already terminated.");29InstanceImpl().reset();30}3132bool Diagnostics::Enabled() { return InstanceImpl().operator bool(); }3334std::optional<Diagnostics> &Diagnostics::InstanceImpl() {35static std::optional<Diagnostics> g_diagnostics;36return g_diagnostics;37}3839Diagnostics &Diagnostics::Instance() { return *InstanceImpl(); }4041Diagnostics::Diagnostics() : m_log_handler(g_num_log_messages) {}4243Diagnostics::~Diagnostics() {}4445Diagnostics::CallbackID Diagnostics::AddCallback(Callback callback) {46std::lock_guard<std::mutex> guard(m_callbacks_mutex);47CallbackID id = m_callback_id++;48m_callbacks.emplace_back(id, callback);49return id;50}5152void Diagnostics::RemoveCallback(CallbackID id) {53std::lock_guard<std::mutex> guard(m_callbacks_mutex);54llvm::erase_if(m_callbacks,55[id](const CallbackEntry &e) { return e.id == id; });56}5758bool Diagnostics::Dump(raw_ostream &stream) {59Expected<FileSpec> diagnostics_dir = CreateUniqueDirectory();60if (!diagnostics_dir) {61stream << "unable to create diagnostic dir: "62<< toString(diagnostics_dir.takeError()) << '\n';63return false;64}6566return Dump(stream, *diagnostics_dir);67}6869bool Diagnostics::Dump(raw_ostream &stream, const FileSpec &dir) {70stream << "LLDB diagnostics will be written to " << dir.GetPath() << "\n";71stream << "Please include the directory content when filing a bug report\n";7273if (Error error = Create(dir)) {74stream << toString(std::move(error)) << '\n';75return false;76}7778return true;79}8081llvm::Expected<FileSpec> Diagnostics::CreateUniqueDirectory() {82SmallString<128> diagnostics_dir;83std::error_code ec =84sys::fs::createUniqueDirectory("diagnostics", diagnostics_dir);85if (ec)86return errorCodeToError(ec);87return FileSpec(diagnostics_dir.str());88}8990Error Diagnostics::Create(const FileSpec &dir) {91if (Error err = DumpDiangosticsLog(dir))92return err;9394for (CallbackEntry e : m_callbacks) {95if (Error err = e.callback(dir))96return err;97}9899return Error::success();100}101102llvm::Error Diagnostics::DumpDiangosticsLog(const FileSpec &dir) const {103FileSpec log_file = dir.CopyByAppendingPathComponent("diagnostics.log");104std::error_code ec;105llvm::raw_fd_ostream stream(log_file.GetPath(), ec, llvm::sys::fs::OF_None);106if (ec)107return errorCodeToError(ec);108m_log_handler.Dump(stream);109return Error::success();110}111112void Diagnostics::Report(llvm::StringRef message) {113m_log_handler.Emit(message);114}115116117