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 m_callbacks.erase(
56 std::remove_if(m_callbacks.begin(), m_callbacks.end(),
57 [id](const CallbackEntry &e) { return e.id == id; }),
58 m_callbacks.end());
59}
60
61bool Diagnostics::Dump(raw_ostream &stream) {
62 Expected<FileSpec> diagnostics_dir = CreateUniqueDirectory();
63 if (!diagnostics_dir) {
64 stream << "unable to create diagnostic dir: "
65 << toString(diagnostics_dir.takeError()) << '\n';
66 return false;
67 }
68
69 return Dump(stream, *diagnostics_dir);
70}
71
72bool Diagnostics::Dump(raw_ostream &stream, const FileSpec &dir) {
73 stream << "LLDB diagnostics will be written to " << dir.GetPath() << "\n";
74 stream << "Please include the directory content when filing a bug report\n";
75
76 if (Error error = Create(dir)) {
77 stream << toString(std::move(error)) << '\n';
78 return false;
79 }
80
81 return true;
82}
83
84llvm::Expected<FileSpec> Diagnostics::CreateUniqueDirectory() {
85 SmallString<128> diagnostics_dir;
86 std::error_code ec =
87 sys::fs::createUniqueDirectory("diagnostics", diagnostics_dir);
88 if (ec)
89 return errorCodeToError(ec);
90 return FileSpec(diagnostics_dir.str());
91}
92
94 if (Error err = DumpDiangosticsLog(dir))
95 return err;
96
97 for (CallbackEntry e : m_callbacks) {
98 if (Error err = e.callback(dir))
99 return err;
100 }
101
102 return Error::success();
103}
104
105llvm::Error Diagnostics::DumpDiangosticsLog(const FileSpec &dir) const {
106 FileSpec log_file = dir.CopyByAppendingPathComponent("diagnostics.log");
107 std::error_code ec;
108 llvm::raw_fd_ostream stream(log_file.GetPath(), ec, llvm::sys::fs::OF_None);
109 if (ec)
110 return errorCodeToError(ec);
111 m_log_handler.Dump(stream);
112 return Error::success();
113}
114
115void Diagnostics::Report(llvm::StringRef message) {
116 m_log_handler.Emit(message);
117}
static llvm::raw_ostream & error(Stream &strm)
static constexpr size_t g_num_log_messages
Definition: Diagnostics.cpp:21
#define lldbassert(x)
Definition: LLDBAssert.h:13
llvm::Error Error
Diagnostics are a collection of files to help investigate bugs and troubleshoot issues.
Definition: Diagnostics.h:28
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.
Definition: Diagnostics.cpp:61
CallbackID AddCallback(Callback callback)
Definition: Diagnostics.cpp:46
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.
Definition: Diagnostics.cpp:93
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.
Definition: Diagnostics.cpp:84
static std::optional< Diagnostics > & InstanceImpl()
Definition: Diagnostics.cpp:35
std::function< llvm::Error(const FileSpec &)> Callback
Definition: Diagnostics.h:44
void RemoveCallback(CallbackID id)
Definition: Diagnostics.cpp:53
static Diagnostics & Instance()
Definition: Diagnostics.cpp:40
A file utility class.
Definition: FileSpec.h:56
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
Definition: FileSpec.cpp:417
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:366
void Dump(llvm::raw_ostream &stream) const
Definition: Log.cpp:416
void Emit(llvm::StringRef message) override
Definition: Log.cpp:398
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
const char * toString(AppleArm64ExceptionClass EC)
Definition: SBAddress.h:15
Definition: Debugger.h:52