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
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
Definition: Diagnostics.cpp:21
#define lldbassert(x)
Definition: LLDBAssert.h:15
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:59
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:91
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:82
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:418
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:367
void Dump(llvm::raw_ostream &stream) const
Definition: Log.cpp:431
void Emit(llvm::StringRef message) override
Definition: Log.cpp:413
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:53