LLDB mainline
Diagnostics.cpp
Go to the documentation of this file.
1//===-- Diagnostics.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
11
12#include "llvm/Support/Error.h"
13#include "llvm/Support/FileSystem.h"
14#include "llvm/Support/raw_ostream.h"
15#include <optional>
16
17using namespace lldb_private;
18using namespace lldb;
19using namespace llvm;
20
21static constexpr size_t g_num_log_messages = 100;
22
24 lldbassert(!InstanceImpl() && "Already initialized.");
25 InstanceImpl().emplace();
26}
27
29 lldbassert(InstanceImpl() && "Already terminated.");
30 InstanceImpl().reset();
31}
32
33bool Diagnostics::Enabled() { return InstanceImpl().operator bool(); }
34
35std::optional<Diagnostics> &Diagnostics::InstanceImpl() {
36 static std::optional<Diagnostics> g_diagnostics;
37 return g_diagnostics;
38}
39
41
43
45
47 std::lock_guard<std::mutex> guard(m_callbacks_mutex);
49 m_callbacks.emplace_back(id, callback);
50 return id;
51}
52
54 std::lock_guard<std::mutex> guard(m_callbacks_mutex);
55 llvm::erase_if(m_callbacks,
56 [id](const CallbackEntry &e) { return e.id == id; });
57}
58
59bool Diagnostics::Dump(raw_ostream &stream) {
60 Expected<FileSpec> diagnostics_dir = CreateUniqueDirectory();
61 if (!diagnostics_dir) {
62 stream << "unable to create diagnostic dir: "
63 << toString(diagnostics_dir.takeError()) << '\n';
64 return false;
65 }
66
67 return Dump(stream, *diagnostics_dir);
68}
69
70bool Diagnostics::Dump(raw_ostream &stream, const FileSpec &dir) {
71 stream << "LLDB diagnostics will be written to " << dir.GetPath() << "\n";
72 stream << "Please include the directory content when filing a bug report\n";
73
74 if (Error error = Create(dir)) {
75 stream << toString(std::move(error)) << '\n';
76 return false;
77 }
78
79 return true;
80}
81
82llvm::Expected<FileSpec> Diagnostics::CreateUniqueDirectory() {
83 SmallString<128> diagnostics_dir;
84 std::error_code ec =
85 sys::fs::createUniqueDirectory("diagnostics", diagnostics_dir);
86 if (ec)
87 return errorCodeToError(ec);
88 return FileSpec(diagnostics_dir.str());
89}
90
91Error Diagnostics::Create(const FileSpec &dir) {
92 if (Error err = DumpDiangosticsLog(dir))
93 return err;
94
95 for (CallbackEntry e : m_callbacks) {
96 if (Error err = e.callback(dir))
97 return err;
98 }
99
100 return Error::success();
101}
102
103llvm::Error Diagnostics::DumpDiangosticsLog(const FileSpec &dir) const {
104 FileSpec log_file = dir.CopyByAppendingPathComponent("diagnostics.log");
105 std::error_code ec;
106 llvm::raw_fd_ostream stream(log_file.GetPath(), ec, llvm::sys::fs::OF_None);
107 if (ec)
108 return errorCodeToError(ec);
109 m_log_handler.Dump(stream);
110 return Error::success();
111}
112
113void Diagnostics::Report(llvm::StringRef message) {
114 m_log_handler.Emit(message);
115}
static llvm::raw_ostream & error(Stream &strm)
static constexpr size_t g_num_log_messages
#define lldbassert(x)
Definition LLDBAssert.h:16
RotatingLogHandler m_log_handler
Definition Diagnostics.h:64
bool Dump(llvm::raw_ostream &stream)
Gather diagnostics and print a message to the given output stream.
CallbackID AddCallback(Callback callback)
void Report(llvm::StringRef message)
llvm::Error DumpDiangosticsLog(const FileSpec &dir) const
llvm::SmallVector< CallbackEntry, 4 > m_callbacks
List of callback entries.
Definition Diagnostics.h:78
llvm::Error Create(const FileSpec &dir)
Gather diagnostics in the given directory.
CallbackID m_callback_id
Monotonically increasing callback identifier.
Definition Diagnostics.h:75
std::mutex m_callbacks_mutex
Mutex to protect callback list and callback identifier.
Definition Diagnostics.h:81
static llvm::Expected< FileSpec > CreateUniqueDirectory()
Create a unique diagnostic directory.
static std::optional< Diagnostics > & InstanceImpl()
std::function< llvm::Error(const FileSpec &)> Callback
Definition Diagnostics.h:44
void RemoveCallback(CallbackID id)
static Diagnostics & Instance()
A file utility class.
Definition FileSpec.h:57
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
Definition FileSpec.cpp:425
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
A class that represents a running process on the host machine.
const char * toString(AppleArm64ExceptionClass EC)