28#include "llvm/ADT/STLExtras.h"
29#include "llvm/Support/Error.h"
30#include "llvm/Support/FileSystem.h"
31#include "llvm/Support/FormatVariadic.h"
32#include "llvm/Support/JSON.h"
33#include "llvm/Support/raw_ostream.h"
46#define LLDB_PROPERTIES_diagnostics
47#include "CoreProperties.inc"
50#define LLDB_PROPERTIES_diagnostics
51#include "CorePropertiesEnum.inc"
57 m_collection_sp = std::make_shared<OptionValueProperties>(
"diagnostics");
62 const uint32_t idx = ePropertyCollectBinaries;
64 idx, g_diagnostics_properties[idx].default_uint_value != 0);
91 static std::optional<Diagnostics> g_diagnostics;
103 if (!diagnostics_dir) {
104 stream <<
"unable to create diagnostic dir: "
105 <<
toString(diagnostics_dir.takeError()) <<
'\n';
109 return Dump(stream, *diagnostics_dir);
113 stream <<
"LLDB diagnostics will be written to " << dir.
GetPath() <<
"\n";
114 stream <<
"Please include the directory content when filing a bug report\n";
125 SmallString<128> diagnostics_dir;
127 sys::fs::createUniqueDirectory(
"diagnostics", diagnostics_dir);
129 return errorCodeToError(ec);
130 return FileSpec(diagnostics_dir.str());
137 return Error::success();
143 llvm::raw_fd_ostream stream(log_file.
GetPath(), ec, llvm::sys::fs::OF_None);
145 return errorCodeToError(ec);
147 return Error::success();
173 llvm::StringRef content,
174 std::vector<std::string> &files) {
177 llvm::raw_fd_ostream os(file.
GetPath(), ec, llvm::sys::fs::OF_Text);
182 llvm::sys::fs::setPermissions(file.
GetPath(), llvm::sys::fs::owner_read |
183 llvm::sys::fs::owner_write);
184 files.push_back(name.str());
191 std::vector<std::string> &files) {
198 name = formatv(
"{0}.{1}", src.
GetFilename(), i).str();
204 llvm::sys::fs::setPermissions(dst.
GetPath(), llvm::sys::fs::owner_read |
205 llvm::sys::fs::owner_write);
206 files.push_back(std::move(name));
222struct TriageCommand {
223 llvm::StringRef command;
224 Requires requirement;
232 {
"target list", Requires::Always},
233 {
"image list", Requires::Target},
234 {
"process status", Requires::Process},
235 {
"thread list", Requires::Process},
236 {
"thread backtrace all", Requires::Process},
237 {
"image lookup -va $pc", Requires::Frame},
238 {
"register read", Requires::Frame},
239 {
"frame variable", Requires::Frame},
243 switch (requirement) {
244 case Requires::Always:
246 case Requires::Target:
248 case Requires::Process:
250 case Requires::Frame:
253 llvm_unreachable(
"unhandled Requires");
256llvm::Expected<Diagnostics::Report>
261 llvm::sys::fs::setPermissions(dir.
GetPath(), llvm::sys::fs::owner_read |
262 llvm::sys::fs::owner_write |
263 llvm::sys::fs::owner_exe);
281 std::vector<std::string> &files) {
284 consumeError(std::move(
error));
286 files.push_back(
"diagnostics.log");
290 files.push_back(std::move(name));
296 std::vector<std::string> &files) {
301 raw_string_ostream os(str);
302 os << formatv(
"{0:2}", stats);
309 std::vector<std::string> &files) {
310 std::string snapshot;
314 snapshot += formatv(
"=== {0} ===\n", tc.command).str();
323 std::vector<std::string> &files) {
325 if (
Module *exe = target->GetExecutableModulePointer()) {
328 if (exe->GetSymbolFileFileSpec() != exe->GetFileSpec())
329 CopyBinary(exe->GetSymbolFileFileSpec(), dir, files);
334 CopyBinary(process->GetCoreFile(), dir, files);
338 std::vector<std::string> &files) {
341 std::vector<ArtifactProviderEntry> providers;
351 std::string os = HostInfo::GetTargetTriple().str();
359 os += formatv(
" platform={0}", platform_sp->GetName()).str();
360 VersionTuple version = platform_sp->GetOSVersion();
361 if (!version.empty())
362 os +=
" os=" + version.getAsString();
363 if (std::optional<std::string> build = platform_sp->GetOSBuildString())
364 os +=
" build=" + *build;
376 std::string invocation;
392 obj[
"attachments"] = json::Object{
static llvm::raw_ostream & error(Stream &strm)
static constexpr size_t g_num_log_messages
static constexpr TriageCommand g_triage_commands[]
static void CopyBinary(const FileSpec &src, const FileSpec &dir, std::vector< std::string > &files)
static bool Available(Requires requirement, const ExecutionContext &exe_ctx)
static std::string CaptureCommand(Debugger &debugger, llvm::StringRef command)
static void WriteArtifact(const FileSpec &dir, llvm::StringRef name, llvm::StringRef content, std::vector< std::string > &files)
A command line argument class.
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
bool HandleCommand(const char *command_line, LazyBool add_to_history, const ExecutionContext &override_context, CommandReturnObject &result)
std::string GetErrorString(bool with_diagnostics=true) const
Return the errors as a string.
llvm::StringRef GetOutputString() const
static llvm::json::Value ReportStatistics(Debugger &debugger, Target *target, const lldb_private::StatisticsOptions &options)
Get metrics associated with one or all targets in a debugger in JSON format.
A class to manage flag bits.
CommandInterpreter & GetCommandInterpreter()
std::vector< std::string > CopyLogFilesToDirectory(const FileSpec &dir)
Copy this debugger's file-backed log files into the given directory, for inclusion in a diagnostics b...
The global diagnostics settings, exposed under diagnostics in the settings hierarchy.
bool SetCollectBinaries(bool collect)
bool GetCollectBinaries() const
std::mutex m_artifact_providers_mutex
RotatingLogHandler m_log_handler
std::vector< ArtifactProviderEntry > m_artifact_providers
bool Dump(llvm::raw_ostream &stream)
Write the diagnostic log into a directory and print a message to the given output stream.
static std::string GetInvocation()
static std::string GetHostDescription(const ExecutionContext &exe_ctx)
Scalars carried in the report rather than written as files.
static void CollectBinaries(const ExecutionContext &exe_ctx, const FileSpec &dir, std::vector< std::string > &files)
ArtifactProviderID AddArtifactProvider(std::string name, ArtifactProvider provider)
Register provider to contribute file name.
void CollectArtifactProviders(const FileSpec &dir, std::vector< std::string > &files)
llvm::Error DumpDiangosticsLog(const FileSpec &dir) const
void CollectLogs(Debugger &debugger, const FileSpec &dir, std::vector< std::string > &files)
Collect the individual parts of the bundle into dir, appending the name of each file to files as it i...
std::function< std::string()> ArtifactProvider
Supplies an artifact's contents on demand.
static DiagnosticsProperties & GetGlobalProperties()
void RemoveArtifactProvider(ArtifactProviderID id)
Unregister a provider. Thread-safe.
llvm::Error Create(const FileSpec &dir)
Write the in-memory diagnostic log into the given directory.
void Record(llvm::StringRef message)
Record a diagnostic message into the always-on, in-memory log.
static llvm::Expected< FileSpec > CreateUniqueDirectory()
Create a unique diagnostic directory.
static std::optional< Diagnostics > & InstanceImpl()
llvm::Expected< Report > Collect(Debugger &debugger, const ExecutionContext &exe_ctx, const FileSpec &dir)
Collect a full diagnostics bundle into dir and return its report.
ArtifactProviderID m_next_artifact_provider_id
Registered artifact providers, guarded by the mutex.
static void CollectCommands(Debugger &debugger, const ExecutionContext &exe_ctx, const FileSpec &dir, std::vector< std::string > &files)
uint64_t ArtifactProviderID
static Diagnostics & Instance()
static void CollectStatistics(Debugger &debugger, const ExecutionContext &exe_ctx, const FileSpec &dir, std::vector< std::string > &files)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
Target * GetTargetPtr() const
Returns a pointer to the target object.
Process * GetProcessPtr() const
Returns a pointer to the process object.
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
llvm::StringRef GetFilename() const
Filename string const get accessor.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
static FileSystem & Instance()
static lldb::pid_t GetCurrentProcessID()
Get the process ID for the calling process.
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
A class that describes an executable image and its associated object and symbol files.
A plug-in interface definition class for debugging a process.
lldb::OptionValuePropertiesSP m_collection_sp
T GetPropertyAtIndexAs(uint32_t idx, T default_value, const ExecutionContext *exe_ctx=nullptr) const
bool SetPropertyAtIndex(uint32_t idx, T t, const ExecutionContext *exe_ctx=nullptr) const
lldb::PlatformSP GetPlatform()
A class that represents a running process on the host machine.
const char * GetVersion()
Retrieves a string representing the complete LLDB version, which includes the lldb version number,...
llvm::json::Value toJSON(const Diagnostics::Report &report)
Render a diagnostics report as JSON, for diagnostics dump's terminal output.
std::string toString(FormatterBytecode::OpCodes op)
std::shared_ptr< lldb_private::Platform > PlatformSP
std::vector< std::string > files
The state a triager needs to make sense of a bug report.