[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Make workaround for the Dynamic loader issue (PR #120166)
Jacob Lalonde via lldb-commits
lldb-commits at lists.llvm.org
Fri Dec 20 13:28:16 PST 2024
https://github.com/Jlalond updated https://github.com/llvm/llvm-project/pull/120166
>From d5dfb15e1ae90ade9b25374eefc605cc36685a43 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Mon, 16 Dec 2024 16:04:01 -0800
Subject: [PATCH 1/2] Make workaround for the Dynamic loader issue
---
.../Minidump/MinidumpFileBuilder.cpp | 4 +-
.../Process/minidump/MinidumpParser.cpp | 25 ++-
.../Plugins/Process/minidump/MinidumpParser.h | 8 +-
.../Process/minidump/ProcessMinidump.cpp | 205 +++++++++---------
.../Process/minidump/ProcessMinidump.h | 7 +-
llvm/include/llvm/BinaryFormat/Minidump.h | 4 +
6 files changed, 137 insertions(+), 116 deletions(-)
diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index bcac5edbc1a793..a4541f8bddf1a2 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -918,8 +918,8 @@ Status MinidumpFileBuilder::DumpHeader() const {
0u), // not used in most of the writers
header.TimeDateStamp =
static_cast<llvm::support::ulittle32_t>(std::time(nullptr));
- header.Flags =
- static_cast<llvm::support::ulittle64_t>(0u); // minidump normal flag
+ header.Flags = static_cast<llvm::support::ulittle64_t>(
+ llvm::minidump::Header::LLDB_HEADER_FLAG);
Status error;
size_t bytes_written;
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index afc095ddbb2f91..6a328b3b841ed0 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -20,8 +20,8 @@
#include <algorithm>
#include <map>
#include <optional>
-#include <vector>
#include <utility>
+#include <vector>
using namespace lldb_private;
using namespace minidump;
@@ -45,6 +45,10 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetData() {
m_data_sp->GetByteSize());
}
+const llvm::minidump::Header *MinidumpParser::GetHeader() const {
+ return reinterpret_cast<llvm::minidump::Header *>(m_file.get());
+}
+
llvm::ArrayRef<uint8_t> MinidumpParser::GetStream(StreamType stream_type) {
return m_file->getRawStream(stream_type).value_or(llvm::ArrayRef<uint8_t>());
}
@@ -70,8 +74,7 @@ UUID MinidumpParser::GetModuleUUID(const minidump::Module *module) {
if (GetArchitecture().GetTriple().isOSBinFormatELF()) {
if (pdb70_uuid->Age != 0)
return UUID(pdb70_uuid, sizeof(*pdb70_uuid));
- return UUID(&pdb70_uuid->Uuid,
- sizeof(pdb70_uuid->Uuid));
+ return UUID(&pdb70_uuid->Uuid, sizeof(pdb70_uuid->Uuid));
}
return UUID(*pdb70_uuid);
} else if (cv_signature == CvSignature::ElfBuildId)
@@ -453,10 +456,12 @@ MinidumpParser::FindMemoryRange(lldb::addr_t addr) {
if (!GetStream(StreamType::Memory64List).empty()) {
llvm::Error err = llvm::Error::success();
- for (const auto &memory_desc : GetMinidumpFile().getMemory64List(err)) {
- if (memory_desc.first.StartOfMemoryRange <= addr
- && addr < memory_desc.first.StartOfMemoryRange + memory_desc.first.DataSize) {
- return minidump::Range(memory_desc.first.StartOfMemoryRange, memory_desc.second);
+ for (const auto &memory_desc : GetMinidumpFile().getMemory64List(err)) {
+ if (memory_desc.first.StartOfMemoryRange <= addr &&
+ addr < memory_desc.first.StartOfMemoryRange +
+ memory_desc.first.DataSize) {
+ return minidump::Range(memory_desc.first.StartOfMemoryRange,
+ memory_desc.second);
}
}
@@ -490,7 +495,8 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr,
return range->range_ref.slice(offset, overlap);
}
-llvm::iterator_range<FallibleMemory64Iterator> MinidumpParser::GetMemory64Iterator(llvm::Error &err) {
+llvm::iterator_range<FallibleMemory64Iterator>
+MinidumpParser::GetMemory64Iterator(llvm::Error &err) {
llvm::ErrorAsOutParameter ErrAsOutParam(&err);
return m_file->getMemory64List(err);
}
@@ -602,8 +608,7 @@ std::pair<MemoryRegionInfos, bool> MinidumpParser::BuildMemoryRegions() {
case StreamType::ST: \
return #ST
-llvm::StringRef
-MinidumpParser::GetStreamTypeAsString(StreamType stream_type) {
+llvm::StringRef MinidumpParser::GetStreamTypeAsString(StreamType stream_type) {
switch (stream_type) {
ENUM_TO_CSTR(Unused);
ENUM_TO_CSTR(ThreadList);
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
index f0b6e6027c52f0..e13065264668c2 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
@@ -47,7 +47,8 @@ struct Range {
}
};
-using FallibleMemory64Iterator = llvm::object::MinidumpFile::FallibleMemory64Iterator;
+using FallibleMemory64Iterator =
+ llvm::object::MinidumpFile::FallibleMemory64Iterator;
using ExceptionStreamsIterator =
llvm::object::MinidumpFile::ExceptionStreamsIterator;
@@ -56,6 +57,8 @@ class MinidumpParser {
static llvm::Expected<MinidumpParser>
Create(const lldb::DataBufferSP &data_buf_sp);
+ const llvm::minidump::Header *GetHeader() const;
+
llvm::ArrayRef<uint8_t> GetData();
llvm::ArrayRef<uint8_t> GetStream(StreamType stream_type);
@@ -96,7 +99,8 @@ class MinidumpParser {
/// complete (includes all regions mapped into the process memory).
std::pair<MemoryRegionInfos, bool> BuildMemoryRegions();
- llvm::iterator_range<FallibleMemory64Iterator> GetMemory64Iterator(llvm::Error &err);
+ llvm::iterator_range<FallibleMemory64Iterator>
+ GetMemory64Iterator(llvm::Error &err);
static llvm::StringRef GetStreamTypeAsString(StreamType stream_type);
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 5b0df72130c161..e03e91887781d8 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -138,7 +138,8 @@ lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp,
return nullptr;
lldbassert(DataPtr->GetByteSize() == header_size);
- if (identify_magic(toStringRef(DataPtr->GetData())) != llvm::file_magic::minidump)
+ if (identify_magic(toStringRef(DataPtr->GetData())) !=
+ llvm::file_magic::minidump)
return nullptr;
auto AllData =
@@ -344,6 +345,23 @@ ArchSpec ProcessMinidump::GetArchitecture() {
return ArchSpec(triple);
}
+bool ProcessMinidump::IsLLDBMinidump() const {
+ const llvm::minidump::Header *header = m_minidump_parser->GetHeader();
+ if (!header)
+ return false;
+ return (header->Flags & llvm::minidump::Header::LLDB_HEADER_FLAG) == 0;
+}
+
+DynamicLoader *ProcessMinidump::GetDynamicLoader() {
+ // This is a workaround for the dynamic loader not playing nice in issue
+ // #119598. The specific reason we use the dynamic loader is to get the TLS
+ // info sections, which we can assume are not being written to the minidump
+ // unless it's an LLDB generate minidump.
+ if (IsLLDBMinidump())
+ return PostMortemProcess::GetDynamicLoader();
+ return nullptr;
+}
+
DataExtractor ProcessMinidump::GetAuxvData() {
std::optional<llvm::ArrayRef<uint8_t>> auxv =
m_minidump_parser->GetStream(StreamType::LinuxAuxv);
@@ -487,8 +505,8 @@ void ProcessMinidump::ReadModuleList() {
Log *log = GetLog(LLDBLog::DynamicLoader);
for (auto module : filtered_modules) {
- std::string name = cantFail(m_minidump_parser->GetMinidumpFile().getString(
- module->ModuleNameRVA));
+ std::string name = cantFail(
+ m_minidump_parser->GetMinidumpFile().getString(module->ModuleNameRVA));
const uint64_t load_addr = module->BaseOfImage;
const uint64_t load_size = module->SizeOfImage;
LLDB_LOG(log, "found module: name: {0} {1:x10}-{2:x10} size: {3}", name,
@@ -507,8 +525,8 @@ void ProcessMinidump::ReadModuleList() {
Status error;
// Try and find a module with a full UUID that matches. This function will
// add the module to the target if it finds one.
- lldb::ModuleSP module_sp = GetTarget().GetOrCreateModule(module_spec,
- true /* notify */, &error);
+ lldb::ModuleSP module_sp =
+ GetTarget().GetOrCreateModule(module_spec, true /* notify */, &error);
if (module_sp) {
LLDB_LOG(log, "Full uuid match for {0}.", name);
} else {
@@ -532,9 +550,8 @@ void ProcessMinidump::ReadModuleList() {
// we don't then we will end up setting the load address of a different
// ObjectFilePlaceholder and an assertion will fire.
auto *objfile = module_sp->GetObjectFile();
- if (objfile &&
- objfile->GetPluginName() ==
- ObjectFilePlaceholder::GetPluginNameStatic()) {
+ if (objfile && objfile->GetPluginName() ==
+ ObjectFilePlaceholder::GetPluginNameStatic()) {
if (((ObjectFilePlaceholder *)objfile)->GetBaseImageAddress() !=
load_addr)
module_sp.reset();
@@ -564,8 +581,7 @@ void ProcessMinidump::ReadModuleList() {
}
bool load_addr_changed = false;
- module_sp->SetLoadAddress(GetTarget(), load_addr, false,
- load_addr_changed);
+ module_sp->SetLoadAddress(GetTarget(), load_addr, false, load_addr_changed);
}
}
@@ -593,10 +609,10 @@ JITLoaderList &ProcessMinidump::GetJITLoaders() {
return *m_jit_loaders_up;
}
-#define INIT_BOOL(VAR, LONG, SHORT, DESC) \
- VAR(LLDB_OPT_SET_1, false, LONG, SHORT, DESC, false, true)
-#define APPEND_OPT(VAR) \
- m_option_group.Append(&VAR, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1)
+#define INIT_BOOL(VAR, LONG, SHORT, DESC) \
+ VAR(LLDB_OPT_SET_1, false, LONG, SHORT, DESC, false, true)
+#define APPEND_OPT(VAR) \
+ m_option_group.Append(&VAR, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1)
class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
private:
@@ -657,55 +673,50 @@ class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
// If no options were set, then dump everything
m_dump_all.GetOptionValue().SetCurrentValue(true);
}
- bool DumpAll() const {
- return m_dump_all.GetOptionValue().GetCurrentValue();
- }
+ bool DumpAll() const { return m_dump_all.GetOptionValue().GetCurrentValue(); }
bool DumpDirectory() const {
- return DumpAll() ||
- m_dump_directory.GetOptionValue().GetCurrentValue();
+ return DumpAll() || m_dump_directory.GetOptionValue().GetCurrentValue();
}
bool DumpLinux() const {
return DumpAll() || m_dump_linux_all.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxCPUInfo() const {
return DumpLinux() ||
- m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue();
+ m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxProcStatus() const {
return DumpLinux() ||
- m_dump_linux_proc_status.GetOptionValue().GetCurrentValue();
+ m_dump_linux_proc_status.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxProcStat() const {
return DumpLinux() ||
- m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue();
+ m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxLSBRelease() const {
return DumpLinux() ||
- m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue();
+ m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxCMDLine() const {
return DumpLinux() ||
- m_dump_linux_cmdline.GetOptionValue().GetCurrentValue();
+ m_dump_linux_cmdline.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxEnviron() const {
return DumpLinux() ||
- m_dump_linux_environ.GetOptionValue().GetCurrentValue();
+ m_dump_linux_environ.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxAuxv() const {
- return DumpLinux() ||
- m_dump_linux_auxv.GetOptionValue().GetCurrentValue();
+ return DumpLinux() || m_dump_linux_auxv.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxMaps() const {
- return DumpLinux() ||
- m_dump_linux_maps.GetOptionValue().GetCurrentValue();
+ return DumpLinux() || m_dump_linux_maps.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxProcUptime() const {
return DumpLinux() ||
- m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue();
+ m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxProcFD() const {
return DumpLinux() ||
- m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue();
+ m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue();
}
bool DumpFacebook() const {
return DumpAll() || m_fb_all.GetOptionValue().GetCurrentValue();
@@ -743,60 +754,59 @@ class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
bool DumpFacebookLogcat() const {
return DumpFacebook() || m_fb_logcat.GetOptionValue().GetCurrentValue();
}
+
public:
CommandObjectProcessMinidumpDump(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "process plugin dump",
- "Dump information from the minidump file.", nullptr),
- m_option_group(),
- INIT_BOOL(m_dump_all, "all", 'a',
- "Dump the everything in the minidump."),
- INIT_BOOL(m_dump_directory, "directory", 'd',
- "Dump the minidump directory map."),
- INIT_BOOL(m_dump_linux_cpuinfo, "cpuinfo", 'C',
- "Dump linux /proc/cpuinfo."),
- INIT_BOOL(m_dump_linux_proc_status, "status", 's',
- "Dump linux /proc/<pid>/status."),
- INIT_BOOL(m_dump_linux_lsb_release, "lsb-release", 'r',
- "Dump linux /etc/lsb-release."),
- INIT_BOOL(m_dump_linux_cmdline, "cmdline", 'c',
- "Dump linux /proc/<pid>/cmdline."),
- INIT_BOOL(m_dump_linux_environ, "environ", 'e',
- "Dump linux /proc/<pid>/environ."),
- INIT_BOOL(m_dump_linux_auxv, "auxv", 'x',
- "Dump linux /proc/<pid>/auxv."),
- INIT_BOOL(m_dump_linux_maps, "maps", 'm',
- "Dump linux /proc/<pid>/maps."),
- INIT_BOOL(m_dump_linux_proc_stat, "stat", 'S',
- "Dump linux /proc/<pid>/stat."),
- INIT_BOOL(m_dump_linux_proc_uptime, "uptime", 'u',
- "Dump linux process uptime."),
- INIT_BOOL(m_dump_linux_proc_fd, "fd", 'f',
- "Dump linux /proc/<pid>/fd."),
- INIT_BOOL(m_dump_linux_all, "linux", 'l',
- "Dump all linux streams."),
- INIT_BOOL(m_fb_app_data, "fb-app-data", 1,
- "Dump Facebook application custom data."),
- INIT_BOOL(m_fb_build_id, "fb-build-id", 2,
- "Dump the Facebook build ID."),
- INIT_BOOL(m_fb_version, "fb-version", 3,
- "Dump Facebook application version string."),
- INIT_BOOL(m_fb_java_stack, "fb-java-stack", 4,
- "Dump Facebook java stack."),
- INIT_BOOL(m_fb_dalvik, "fb-dalvik-info", 5,
- "Dump Facebook Dalvik info."),
- INIT_BOOL(m_fb_unwind, "fb-unwind-symbols", 6,
- "Dump Facebook unwind symbols."),
- INIT_BOOL(m_fb_error_log, "fb-error-log", 7,
- "Dump Facebook error log."),
- INIT_BOOL(m_fb_app_state, "fb-app-state-log", 8,
- "Dump Facebook java stack."),
- INIT_BOOL(m_fb_abort, "fb-abort-reason", 9,
- "Dump Facebook abort reason."),
- INIT_BOOL(m_fb_thread, "fb-thread-name", 10,
- "Dump Facebook thread name."),
- INIT_BOOL(m_fb_logcat, "fb-logcat", 11,
- "Dump Facebook logcat."),
- INIT_BOOL(m_fb_all, "facebook", 12, "Dump all Facebook streams.") {
+ : CommandObjectParsed(interpreter, "process plugin dump",
+ "Dump information from the minidump file.",
+ nullptr),
+ m_option_group(), INIT_BOOL(m_dump_all, "all", 'a',
+ "Dump the everything in the minidump."),
+ INIT_BOOL(m_dump_directory, "directory", 'd',
+ "Dump the minidump directory map."),
+ INIT_BOOL(m_dump_linux_cpuinfo, "cpuinfo", 'C',
+ "Dump linux /proc/cpuinfo."),
+ INIT_BOOL(m_dump_linux_proc_status, "status", 's',
+ "Dump linux /proc/<pid>/status."),
+ INIT_BOOL(m_dump_linux_lsb_release, "lsb-release", 'r',
+ "Dump linux /etc/lsb-release."),
+ INIT_BOOL(m_dump_linux_cmdline, "cmdline", 'c',
+ "Dump linux /proc/<pid>/cmdline."),
+ INIT_BOOL(m_dump_linux_environ, "environ", 'e',
+ "Dump linux /proc/<pid>/environ."),
+ INIT_BOOL(m_dump_linux_auxv, "auxv", 'x',
+ "Dump linux /proc/<pid>/auxv."),
+ INIT_BOOL(m_dump_linux_maps, "maps", 'm',
+ "Dump linux /proc/<pid>/maps."),
+ INIT_BOOL(m_dump_linux_proc_stat, "stat", 'S',
+ "Dump linux /proc/<pid>/stat."),
+ INIT_BOOL(m_dump_linux_proc_uptime, "uptime", 'u',
+ "Dump linux process uptime."),
+ INIT_BOOL(m_dump_linux_proc_fd, "fd", 'f',
+ "Dump linux /proc/<pid>/fd."),
+ INIT_BOOL(m_dump_linux_all, "linux", 'l', "Dump all linux streams."),
+ INIT_BOOL(m_fb_app_data, "fb-app-data", 1,
+ "Dump Facebook application custom data."),
+ INIT_BOOL(m_fb_build_id, "fb-build-id", 2,
+ "Dump the Facebook build ID."),
+ INIT_BOOL(m_fb_version, "fb-version", 3,
+ "Dump Facebook application version string."),
+ INIT_BOOL(m_fb_java_stack, "fb-java-stack", 4,
+ "Dump Facebook java stack."),
+ INIT_BOOL(m_fb_dalvik, "fb-dalvik-info", 5,
+ "Dump Facebook Dalvik info."),
+ INIT_BOOL(m_fb_unwind, "fb-unwind-symbols", 6,
+ "Dump Facebook unwind symbols."),
+ INIT_BOOL(m_fb_error_log, "fb-error-log", 7,
+ "Dump Facebook error log."),
+ INIT_BOOL(m_fb_app_state, "fb-app-state-log", 8,
+ "Dump Facebook java stack."),
+ INIT_BOOL(m_fb_abort, "fb-abort-reason", 9,
+ "Dump Facebook abort reason."),
+ INIT_BOOL(m_fb_thread, "fb-thread-name", 10,
+ "Dump Facebook thread name."),
+ INIT_BOOL(m_fb_logcat, "fb-logcat", 11, "Dump Facebook logcat."),
+ INIT_BOOL(m_fb_all, "facebook", 12, "Dump all Facebook streams.") {
APPEND_OPT(m_dump_all);
APPEND_OPT(m_dump_directory);
APPEND_OPT(m_dump_linux_cpuinfo);
@@ -899,8 +909,7 @@ class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
if (DumpLinuxProcFD())
DumpTextStream(StreamType::LinuxProcFD, "/proc/PID/fd");
if (DumpFacebookAppData())
- DumpTextStream(StreamType::FacebookAppCustomData,
- "Facebook App Data");
+ DumpTextStream(StreamType::FacebookAppCustomData, "Facebook App Data");
if (DumpFacebookBuildID()) {
auto bytes = minidump.GetStream(StreamType::FacebookBuildID);
if (bytes.size() >= 4) {
@@ -917,26 +926,21 @@ class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
DumpTextStream(StreamType::FacebookAppVersionName,
"Facebook Version String");
if (DumpFacebookJavaStack())
- DumpTextStream(StreamType::FacebookJavaStack,
- "Facebook Java Stack");
+ DumpTextStream(StreamType::FacebookJavaStack, "Facebook Java Stack");
if (DumpFacebookDalvikInfo())
- DumpTextStream(StreamType::FacebookDalvikInfo,
- "Facebook Dalvik Info");
+ DumpTextStream(StreamType::FacebookDalvikInfo, "Facebook Dalvik Info");
if (DumpFacebookUnwindSymbols())
DumpBinaryStream(StreamType::FacebookUnwindSymbols,
"Facebook Unwind Symbols Bytes");
if (DumpFacebookErrorLog())
- DumpTextStream(StreamType::FacebookDumpErrorLog,
- "Facebook Error Log");
+ DumpTextStream(StreamType::FacebookDumpErrorLog, "Facebook Error Log");
if (DumpFacebookAppStateLog())
DumpTextStream(StreamType::FacebookAppStateLog,
"Faceook Application State Log");
if (DumpFacebookAbortReason())
- DumpTextStream(StreamType::FacebookAbortReason,
- "Facebook Abort Reason");
+ DumpTextStream(StreamType::FacebookAbortReason, "Facebook Abort Reason");
if (DumpFacebookThreadName())
- DumpTextStream(StreamType::FacebookThreadName,
- "Facebook Thread Name");
+ DumpTextStream(StreamType::FacebookThreadName, "Facebook Thread Name");
if (DumpFacebookLogcat())
DumpTextStream(StreamType::FacebookLogcat, "Facebook Logcat");
}
@@ -945,11 +949,12 @@ class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
class CommandObjectMultiwordProcessMinidump : public CommandObjectMultiword {
public:
CommandObjectMultiwordProcessMinidump(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "process plugin",
- "Commands for operating on a ProcessMinidump process.",
- "process plugin <subcommand> [<subcommand-options>]") {
- LoadSubCommand("dump",
- CommandObjectSP(new CommandObjectProcessMinidumpDump(interpreter)));
+ : CommandObjectMultiword(
+ interpreter, "process plugin",
+ "Commands for operating on a ProcessMinidump process.",
+ "process plugin <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("dump", CommandObjectSP(new CommandObjectProcessMinidumpDump(
+ interpreter)));
}
~CommandObjectMultiwordProcessMinidump() override = default;
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index 3d235670a33abc..1cc1e8addb15d9 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -53,6 +53,8 @@ class ProcessMinidump : public PostMortemProcess {
Status DoLoadCore() override;
+ DynamicLoader *GetDynamicLoader() override;
+
// Returns AUXV structure found in the core file
lldb_private::DataExtractor GetAuxvData() override;
@@ -74,8 +76,8 @@ class ProcessMinidump : public PostMortemProcess {
ArchSpec GetArchitecture();
- Status GetMemoryRegions(
- lldb_private::MemoryRegionInfos ®ion_list) override;
+ Status
+ GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) override;
bool GetProcessInfo(ProcessInstanceInfo &info) override;
@@ -113,6 +115,7 @@ class ProcessMinidump : public PostMortemProcess {
std::optional<MemoryRegionInfos> m_memory_regions;
void BuildMemoryRegions();
+ bool IsLLDBMinidump() const;
};
} // namespace minidump
diff --git a/llvm/include/llvm/BinaryFormat/Minidump.h b/llvm/include/llvm/BinaryFormat/Minidump.h
index 03497d4c5fa66f..75762d3196dfcd 100644
--- a/llvm/include/llvm/BinaryFormat/Minidump.h
+++ b/llvm/include/llvm/BinaryFormat/Minidump.h
@@ -32,6 +32,10 @@ LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
struct Header {
static constexpr uint32_t MagicSignature = 0x504d444d; // PMDM
static constexpr uint16_t MagicVersion = 0xa793;
+ // We set all the high bits flag to indicate this is from LLDB.
+ // We don't want to conflict with anything Microsoft is using the flags for
+ // and the highest bits are not currently being used.
+ static const uint32_t LLDB_HEADER_FLAG = 0xF0000000;
support::ulittle32_t Signature;
// The high 16 bits of version field are implementation specific. The low 16
>From 49bc821677836f3946456f22b9e28c4c0c4c283d Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Fri, 20 Dec 2024 13:14:57 -0800
Subject: [PATCH 2/2] Reset and go with Pavel's plan of a stream section
instead of a flag
---
.../Minidump/MinidumpFileBuilder.cpp | 24 +-
.../ObjectFile/Minidump/MinidumpFileBuilder.h | 1 +
.../Process/minidump/MinidumpParser.cpp | 25 +--
.../Plugins/Process/minidump/MinidumpParser.h | 8 +-
.../Process/minidump/ProcessMinidump.cpp | 212 ++++++++++--------
.../Process/minidump/ProcessMinidump.h | 7 +-
llvm/include/llvm/BinaryFormat/Minidump.h | 5 +-
7 files changed, 157 insertions(+), 125 deletions(-)
diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index a4541f8bddf1a2..85ec42349b38d4 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -58,8 +58,8 @@ Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
// First set the offset on the file, and on the bytes saved
m_saved_data_size = HEADER_SIZE;
// We know we will have at least Misc, SystemInfo, Modules, and ThreadList
- // (corresponding memory list for stacks) And an additional memory list for
- // non-stacks.
+ // (corresponding memory list for stacks), an additional memory list for
+ // non-stacks, and a stream to mark this minidump was generated by LLDB.
lldb_private::Target &target = m_process_sp->GetTarget();
m_expected_directories = 6;
// Check if OS is linux and reserve directory space for all linux specific
@@ -89,8 +89,11 @@ Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
"Failed to fill in header and directory "
"sections. Written / Expected (%" PRIx64 " / %" PRIx64 ")",
new_offset, m_saved_data_size);
-
return error;
+ if (error.Fail())
+ return error;
+
+ return AddLLDBGeneratedStream();
}
Status MinidumpFileBuilder::AddDirectory(StreamType type,
@@ -126,6 +129,17 @@ Status MinidumpFileBuilder::AddDirectory(StreamType type,
return error;
}
+Status MinidumpFileBuilder::AddLLDBGeneratedStream() {
+ Status error;
+ StreamType type = StreamType::LLDBGenerated;
+ error = AddDirectory(type, sizeof(StreamType));
+ if (error.Fail())
+ return error;
+
+ error = AddData(&type, sizeof(StreamType));
+ return error;
+}
+
Status MinidumpFileBuilder::AddSystemInfo() {
Status error;
const llvm::Triple &target_triple =
@@ -918,8 +932,8 @@ Status MinidumpFileBuilder::DumpHeader() const {
0u), // not used in most of the writers
header.TimeDateStamp =
static_cast<llvm::support::ulittle32_t>(std::time(nullptr));
- header.Flags = static_cast<llvm::support::ulittle64_t>(
- llvm::minidump::Header::LLDB_HEADER_FLAG);
+ header.Flags =
+ static_cast<llvm::support::ulittle64_t>(0u); // minidump normal flag
Status error;
size_t bytes_written;
diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h
index 58b284608bd535..48293ee1bf5e56 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h
@@ -120,6 +120,7 @@ class MinidumpFileBuilder {
void DeleteFile() noexcept;
private:
+ lldb_private::Status AddLLDBGeneratedStream();
// Add data to the end of the buffer, if the buffer exceeds the flush level,
// trigger a flush.
lldb_private::Status AddData(const void *data, uint64_t size);
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index 6a328b3b841ed0..afc095ddbb2f91 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -20,8 +20,8 @@
#include <algorithm>
#include <map>
#include <optional>
-#include <utility>
#include <vector>
+#include <utility>
using namespace lldb_private;
using namespace minidump;
@@ -45,10 +45,6 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetData() {
m_data_sp->GetByteSize());
}
-const llvm::minidump::Header *MinidumpParser::GetHeader() const {
- return reinterpret_cast<llvm::minidump::Header *>(m_file.get());
-}
-
llvm::ArrayRef<uint8_t> MinidumpParser::GetStream(StreamType stream_type) {
return m_file->getRawStream(stream_type).value_or(llvm::ArrayRef<uint8_t>());
}
@@ -74,7 +70,8 @@ UUID MinidumpParser::GetModuleUUID(const minidump::Module *module) {
if (GetArchitecture().GetTriple().isOSBinFormatELF()) {
if (pdb70_uuid->Age != 0)
return UUID(pdb70_uuid, sizeof(*pdb70_uuid));
- return UUID(&pdb70_uuid->Uuid, sizeof(pdb70_uuid->Uuid));
+ return UUID(&pdb70_uuid->Uuid,
+ sizeof(pdb70_uuid->Uuid));
}
return UUID(*pdb70_uuid);
} else if (cv_signature == CvSignature::ElfBuildId)
@@ -456,12 +453,10 @@ MinidumpParser::FindMemoryRange(lldb::addr_t addr) {
if (!GetStream(StreamType::Memory64List).empty()) {
llvm::Error err = llvm::Error::success();
- for (const auto &memory_desc : GetMinidumpFile().getMemory64List(err)) {
- if (memory_desc.first.StartOfMemoryRange <= addr &&
- addr < memory_desc.first.StartOfMemoryRange +
- memory_desc.first.DataSize) {
- return minidump::Range(memory_desc.first.StartOfMemoryRange,
- memory_desc.second);
+ for (const auto &memory_desc : GetMinidumpFile().getMemory64List(err)) {
+ if (memory_desc.first.StartOfMemoryRange <= addr
+ && addr < memory_desc.first.StartOfMemoryRange + memory_desc.first.DataSize) {
+ return minidump::Range(memory_desc.first.StartOfMemoryRange, memory_desc.second);
}
}
@@ -495,8 +490,7 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr,
return range->range_ref.slice(offset, overlap);
}
-llvm::iterator_range<FallibleMemory64Iterator>
-MinidumpParser::GetMemory64Iterator(llvm::Error &err) {
+llvm::iterator_range<FallibleMemory64Iterator> MinidumpParser::GetMemory64Iterator(llvm::Error &err) {
llvm::ErrorAsOutParameter ErrAsOutParam(&err);
return m_file->getMemory64List(err);
}
@@ -608,7 +602,8 @@ std::pair<MemoryRegionInfos, bool> MinidumpParser::BuildMemoryRegions() {
case StreamType::ST: \
return #ST
-llvm::StringRef MinidumpParser::GetStreamTypeAsString(StreamType stream_type) {
+llvm::StringRef
+MinidumpParser::GetStreamTypeAsString(StreamType stream_type) {
switch (stream_type) {
ENUM_TO_CSTR(Unused);
ENUM_TO_CSTR(ThreadList);
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
index e13065264668c2..f0b6e6027c52f0 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
@@ -47,8 +47,7 @@ struct Range {
}
};
-using FallibleMemory64Iterator =
- llvm::object::MinidumpFile::FallibleMemory64Iterator;
+using FallibleMemory64Iterator = llvm::object::MinidumpFile::FallibleMemory64Iterator;
using ExceptionStreamsIterator =
llvm::object::MinidumpFile::ExceptionStreamsIterator;
@@ -57,8 +56,6 @@ class MinidumpParser {
static llvm::Expected<MinidumpParser>
Create(const lldb::DataBufferSP &data_buf_sp);
- const llvm::minidump::Header *GetHeader() const;
-
llvm::ArrayRef<uint8_t> GetData();
llvm::ArrayRef<uint8_t> GetStream(StreamType stream_type);
@@ -99,8 +96,7 @@ class MinidumpParser {
/// complete (includes all regions mapped into the process memory).
std::pair<MemoryRegionInfos, bool> BuildMemoryRegions();
- llvm::iterator_range<FallibleMemory64Iterator>
- GetMemory64Iterator(llvm::Error &err);
+ llvm::iterator_range<FallibleMemory64Iterator> GetMemory64Iterator(llvm::Error &err);
static llvm::StringRef GetStreamTypeAsString(StreamType stream_type);
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index e03e91887781d8..c44edd05304b13 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -138,8 +138,7 @@ lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp,
return nullptr;
lldbassert(DataPtr->GetByteSize() == header_size);
- if (identify_magic(toStringRef(DataPtr->GetData())) !=
- llvm::file_magic::minidump)
+ if (identify_magic(toStringRef(DataPtr->GetData())) != llvm::file_magic::minidump)
return nullptr;
auto AllData =
@@ -345,11 +344,27 @@ ArchSpec ProcessMinidump::GetArchitecture() {
return ArchSpec(triple);
}
-bool ProcessMinidump::IsLLDBMinidump() const {
- const llvm::minidump::Header *header = m_minidump_parser->GetHeader();
- if (!header)
+bool ProcessMinidump::IsLLDBMinidump() {
+ // If we've already checked, return the cached value
+ if (m_is_lldb_generated.has_value())
+ return *m_is_lldb_generated;
+
+ // If the minidump doesn't have a LLDBGeneratedStream, it's not an LLDB
+ // We also check to see if the section was generated correctly, but not
+ // enforcing an exact size so we can change it in the future without
+ // impacting older generated Minidumps.
+ llvm::ArrayRef<uint8_t> lldbStream =
+ m_minidump_parser->GetStream(StreamType::LLDBGenerated);
+ if (lldbStream.empty() || lldbStream.size() <= sizeof(StreamType)) {
+ m_is_lldb_generated = false;
return false;
- return (header->Flags & llvm::minidump::Header::LLDB_HEADER_FLAG) == 0;
+ }
+
+ const uint32_t *lldbStreamType =
+ reinterpret_cast<const uint32_t *>(lldbStream.data());
+
+ m_is_lldb_generated = *lldbStreamType == (uint32_t)StreamType::LLDBGenerated;
+ return *m_is_lldb_generated;
}
DynamicLoader *ProcessMinidump::GetDynamicLoader() {
@@ -505,8 +520,8 @@ void ProcessMinidump::ReadModuleList() {
Log *log = GetLog(LLDBLog::DynamicLoader);
for (auto module : filtered_modules) {
- std::string name = cantFail(
- m_minidump_parser->GetMinidumpFile().getString(module->ModuleNameRVA));
+ std::string name = cantFail(m_minidump_parser->GetMinidumpFile().getString(
+ module->ModuleNameRVA));
const uint64_t load_addr = module->BaseOfImage;
const uint64_t load_size = module->SizeOfImage;
LLDB_LOG(log, "found module: name: {0} {1:x10}-{2:x10} size: {3}", name,
@@ -525,8 +540,8 @@ void ProcessMinidump::ReadModuleList() {
Status error;
// Try and find a module with a full UUID that matches. This function will
// add the module to the target if it finds one.
- lldb::ModuleSP module_sp =
- GetTarget().GetOrCreateModule(module_spec, true /* notify */, &error);
+ lldb::ModuleSP module_sp = GetTarget().GetOrCreateModule(module_spec,
+ true /* notify */, &error);
if (module_sp) {
LLDB_LOG(log, "Full uuid match for {0}.", name);
} else {
@@ -550,8 +565,9 @@ void ProcessMinidump::ReadModuleList() {
// we don't then we will end up setting the load address of a different
// ObjectFilePlaceholder and an assertion will fire.
auto *objfile = module_sp->GetObjectFile();
- if (objfile && objfile->GetPluginName() ==
- ObjectFilePlaceholder::GetPluginNameStatic()) {
+ if (objfile &&
+ objfile->GetPluginName() ==
+ ObjectFilePlaceholder::GetPluginNameStatic()) {
if (((ObjectFilePlaceholder *)objfile)->GetBaseImageAddress() !=
load_addr)
module_sp.reset();
@@ -581,7 +597,8 @@ void ProcessMinidump::ReadModuleList() {
}
bool load_addr_changed = false;
- module_sp->SetLoadAddress(GetTarget(), load_addr, false, load_addr_changed);
+ module_sp->SetLoadAddress(GetTarget(), load_addr, false,
+ load_addr_changed);
}
}
@@ -609,10 +626,10 @@ JITLoaderList &ProcessMinidump::GetJITLoaders() {
return *m_jit_loaders_up;
}
-#define INIT_BOOL(VAR, LONG, SHORT, DESC) \
- VAR(LLDB_OPT_SET_1, false, LONG, SHORT, DESC, false, true)
-#define APPEND_OPT(VAR) \
- m_option_group.Append(&VAR, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1)
+#define INIT_BOOL(VAR, LONG, SHORT, DESC) \
+ VAR(LLDB_OPT_SET_1, false, LONG, SHORT, DESC, false, true)
+#define APPEND_OPT(VAR) \
+ m_option_group.Append(&VAR, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1)
class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
private:
@@ -673,50 +690,55 @@ class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
// If no options were set, then dump everything
m_dump_all.GetOptionValue().SetCurrentValue(true);
}
- bool DumpAll() const { return m_dump_all.GetOptionValue().GetCurrentValue(); }
+ bool DumpAll() const {
+ return m_dump_all.GetOptionValue().GetCurrentValue();
+ }
bool DumpDirectory() const {
- return DumpAll() || m_dump_directory.GetOptionValue().GetCurrentValue();
+ return DumpAll() ||
+ m_dump_directory.GetOptionValue().GetCurrentValue();
}
bool DumpLinux() const {
return DumpAll() || m_dump_linux_all.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxCPUInfo() const {
return DumpLinux() ||
- m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue();
+ m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxProcStatus() const {
return DumpLinux() ||
- m_dump_linux_proc_status.GetOptionValue().GetCurrentValue();
+ m_dump_linux_proc_status.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxProcStat() const {
return DumpLinux() ||
- m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue();
+ m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxLSBRelease() const {
return DumpLinux() ||
- m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue();
+ m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxCMDLine() const {
return DumpLinux() ||
- m_dump_linux_cmdline.GetOptionValue().GetCurrentValue();
+ m_dump_linux_cmdline.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxEnviron() const {
return DumpLinux() ||
- m_dump_linux_environ.GetOptionValue().GetCurrentValue();
+ m_dump_linux_environ.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxAuxv() const {
- return DumpLinux() || m_dump_linux_auxv.GetOptionValue().GetCurrentValue();
+ return DumpLinux() ||
+ m_dump_linux_auxv.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxMaps() const {
- return DumpLinux() || m_dump_linux_maps.GetOptionValue().GetCurrentValue();
+ return DumpLinux() ||
+ m_dump_linux_maps.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxProcUptime() const {
return DumpLinux() ||
- m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue();
+ m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue();
}
bool DumpLinuxProcFD() const {
return DumpLinux() ||
- m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue();
+ m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue();
}
bool DumpFacebook() const {
return DumpAll() || m_fb_all.GetOptionValue().GetCurrentValue();
@@ -754,59 +776,60 @@ class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
bool DumpFacebookLogcat() const {
return DumpFacebook() || m_fb_logcat.GetOptionValue().GetCurrentValue();
}
-
public:
CommandObjectProcessMinidumpDump(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "process plugin dump",
- "Dump information from the minidump file.",
- nullptr),
- m_option_group(), INIT_BOOL(m_dump_all, "all", 'a',
- "Dump the everything in the minidump."),
- INIT_BOOL(m_dump_directory, "directory", 'd',
- "Dump the minidump directory map."),
- INIT_BOOL(m_dump_linux_cpuinfo, "cpuinfo", 'C',
- "Dump linux /proc/cpuinfo."),
- INIT_BOOL(m_dump_linux_proc_status, "status", 's',
- "Dump linux /proc/<pid>/status."),
- INIT_BOOL(m_dump_linux_lsb_release, "lsb-release", 'r',
- "Dump linux /etc/lsb-release."),
- INIT_BOOL(m_dump_linux_cmdline, "cmdline", 'c',
- "Dump linux /proc/<pid>/cmdline."),
- INIT_BOOL(m_dump_linux_environ, "environ", 'e',
- "Dump linux /proc/<pid>/environ."),
- INIT_BOOL(m_dump_linux_auxv, "auxv", 'x',
- "Dump linux /proc/<pid>/auxv."),
- INIT_BOOL(m_dump_linux_maps, "maps", 'm',
- "Dump linux /proc/<pid>/maps."),
- INIT_BOOL(m_dump_linux_proc_stat, "stat", 'S',
- "Dump linux /proc/<pid>/stat."),
- INIT_BOOL(m_dump_linux_proc_uptime, "uptime", 'u',
- "Dump linux process uptime."),
- INIT_BOOL(m_dump_linux_proc_fd, "fd", 'f',
- "Dump linux /proc/<pid>/fd."),
- INIT_BOOL(m_dump_linux_all, "linux", 'l', "Dump all linux streams."),
- INIT_BOOL(m_fb_app_data, "fb-app-data", 1,
- "Dump Facebook application custom data."),
- INIT_BOOL(m_fb_build_id, "fb-build-id", 2,
- "Dump the Facebook build ID."),
- INIT_BOOL(m_fb_version, "fb-version", 3,
- "Dump Facebook application version string."),
- INIT_BOOL(m_fb_java_stack, "fb-java-stack", 4,
- "Dump Facebook java stack."),
- INIT_BOOL(m_fb_dalvik, "fb-dalvik-info", 5,
- "Dump Facebook Dalvik info."),
- INIT_BOOL(m_fb_unwind, "fb-unwind-symbols", 6,
- "Dump Facebook unwind symbols."),
- INIT_BOOL(m_fb_error_log, "fb-error-log", 7,
- "Dump Facebook error log."),
- INIT_BOOL(m_fb_app_state, "fb-app-state-log", 8,
- "Dump Facebook java stack."),
- INIT_BOOL(m_fb_abort, "fb-abort-reason", 9,
- "Dump Facebook abort reason."),
- INIT_BOOL(m_fb_thread, "fb-thread-name", 10,
- "Dump Facebook thread name."),
- INIT_BOOL(m_fb_logcat, "fb-logcat", 11, "Dump Facebook logcat."),
- INIT_BOOL(m_fb_all, "facebook", 12, "Dump all Facebook streams.") {
+ : CommandObjectParsed(interpreter, "process plugin dump",
+ "Dump information from the minidump file.", nullptr),
+ m_option_group(),
+ INIT_BOOL(m_dump_all, "all", 'a',
+ "Dump the everything in the minidump."),
+ INIT_BOOL(m_dump_directory, "directory", 'd',
+ "Dump the minidump directory map."),
+ INIT_BOOL(m_dump_linux_cpuinfo, "cpuinfo", 'C',
+ "Dump linux /proc/cpuinfo."),
+ INIT_BOOL(m_dump_linux_proc_status, "status", 's',
+ "Dump linux /proc/<pid>/status."),
+ INIT_BOOL(m_dump_linux_lsb_release, "lsb-release", 'r',
+ "Dump linux /etc/lsb-release."),
+ INIT_BOOL(m_dump_linux_cmdline, "cmdline", 'c',
+ "Dump linux /proc/<pid>/cmdline."),
+ INIT_BOOL(m_dump_linux_environ, "environ", 'e',
+ "Dump linux /proc/<pid>/environ."),
+ INIT_BOOL(m_dump_linux_auxv, "auxv", 'x',
+ "Dump linux /proc/<pid>/auxv."),
+ INIT_BOOL(m_dump_linux_maps, "maps", 'm',
+ "Dump linux /proc/<pid>/maps."),
+ INIT_BOOL(m_dump_linux_proc_stat, "stat", 'S',
+ "Dump linux /proc/<pid>/stat."),
+ INIT_BOOL(m_dump_linux_proc_uptime, "uptime", 'u',
+ "Dump linux process uptime."),
+ INIT_BOOL(m_dump_linux_proc_fd, "fd", 'f',
+ "Dump linux /proc/<pid>/fd."),
+ INIT_BOOL(m_dump_linux_all, "linux", 'l',
+ "Dump all linux streams."),
+ INIT_BOOL(m_fb_app_data, "fb-app-data", 1,
+ "Dump Facebook application custom data."),
+ INIT_BOOL(m_fb_build_id, "fb-build-id", 2,
+ "Dump the Facebook build ID."),
+ INIT_BOOL(m_fb_version, "fb-version", 3,
+ "Dump Facebook application version string."),
+ INIT_BOOL(m_fb_java_stack, "fb-java-stack", 4,
+ "Dump Facebook java stack."),
+ INIT_BOOL(m_fb_dalvik, "fb-dalvik-info", 5,
+ "Dump Facebook Dalvik info."),
+ INIT_BOOL(m_fb_unwind, "fb-unwind-symbols", 6,
+ "Dump Facebook unwind symbols."),
+ INIT_BOOL(m_fb_error_log, "fb-error-log", 7,
+ "Dump Facebook error log."),
+ INIT_BOOL(m_fb_app_state, "fb-app-state-log", 8,
+ "Dump Facebook java stack."),
+ INIT_BOOL(m_fb_abort, "fb-abort-reason", 9,
+ "Dump Facebook abort reason."),
+ INIT_BOOL(m_fb_thread, "fb-thread-name", 10,
+ "Dump Facebook thread name."),
+ INIT_BOOL(m_fb_logcat, "fb-logcat", 11,
+ "Dump Facebook logcat."),
+ INIT_BOOL(m_fb_all, "facebook", 12, "Dump all Facebook streams.") {
APPEND_OPT(m_dump_all);
APPEND_OPT(m_dump_directory);
APPEND_OPT(m_dump_linux_cpuinfo);
@@ -909,7 +932,8 @@ class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
if (DumpLinuxProcFD())
DumpTextStream(StreamType::LinuxProcFD, "/proc/PID/fd");
if (DumpFacebookAppData())
- DumpTextStream(StreamType::FacebookAppCustomData, "Facebook App Data");
+ DumpTextStream(StreamType::FacebookAppCustomData,
+ "Facebook App Data");
if (DumpFacebookBuildID()) {
auto bytes = minidump.GetStream(StreamType::FacebookBuildID);
if (bytes.size() >= 4) {
@@ -926,21 +950,26 @@ class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
DumpTextStream(StreamType::FacebookAppVersionName,
"Facebook Version String");
if (DumpFacebookJavaStack())
- DumpTextStream(StreamType::FacebookJavaStack, "Facebook Java Stack");
+ DumpTextStream(StreamType::FacebookJavaStack,
+ "Facebook Java Stack");
if (DumpFacebookDalvikInfo())
- DumpTextStream(StreamType::FacebookDalvikInfo, "Facebook Dalvik Info");
+ DumpTextStream(StreamType::FacebookDalvikInfo,
+ "Facebook Dalvik Info");
if (DumpFacebookUnwindSymbols())
DumpBinaryStream(StreamType::FacebookUnwindSymbols,
"Facebook Unwind Symbols Bytes");
if (DumpFacebookErrorLog())
- DumpTextStream(StreamType::FacebookDumpErrorLog, "Facebook Error Log");
+ DumpTextStream(StreamType::FacebookDumpErrorLog,
+ "Facebook Error Log");
if (DumpFacebookAppStateLog())
DumpTextStream(StreamType::FacebookAppStateLog,
"Faceook Application State Log");
if (DumpFacebookAbortReason())
- DumpTextStream(StreamType::FacebookAbortReason, "Facebook Abort Reason");
+ DumpTextStream(StreamType::FacebookAbortReason,
+ "Facebook Abort Reason");
if (DumpFacebookThreadName())
- DumpTextStream(StreamType::FacebookThreadName, "Facebook Thread Name");
+ DumpTextStream(StreamType::FacebookThreadName,
+ "Facebook Thread Name");
if (DumpFacebookLogcat())
DumpTextStream(StreamType::FacebookLogcat, "Facebook Logcat");
}
@@ -949,12 +978,11 @@ class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
class CommandObjectMultiwordProcessMinidump : public CommandObjectMultiword {
public:
CommandObjectMultiwordProcessMinidump(CommandInterpreter &interpreter)
- : CommandObjectMultiword(
- interpreter, "process plugin",
- "Commands for operating on a ProcessMinidump process.",
- "process plugin <subcommand> [<subcommand-options>]") {
- LoadSubCommand("dump", CommandObjectSP(new CommandObjectProcessMinidumpDump(
- interpreter)));
+ : CommandObjectMultiword(interpreter, "process plugin",
+ "Commands for operating on a ProcessMinidump process.",
+ "process plugin <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("dump",
+ CommandObjectSP(new CommandObjectProcessMinidumpDump(interpreter)));
}
~CommandObjectMultiwordProcessMinidump() override = default;
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index 1cc1e8addb15d9..7525d8aae0f17b 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -76,8 +76,8 @@ class ProcessMinidump : public PostMortemProcess {
ArchSpec GetArchitecture();
- Status
- GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) override;
+ Status GetMemoryRegions(
+ lldb_private::MemoryRegionInfos ®ion_list) override;
bool GetProcessInfo(ProcessInstanceInfo &info) override;
@@ -106,6 +106,7 @@ class ProcessMinidump : public PostMortemProcess {
JITLoaderList &GetJITLoaders() override;
private:
+ std::optional<bool> m_is_lldb_generated;
lldb::DataBufferSP m_core_data;
llvm::ArrayRef<minidump::Thread> m_thread_list;
std::unordered_map<uint32_t, const minidump::ExceptionStream>
@@ -115,7 +116,7 @@ class ProcessMinidump : public PostMortemProcess {
std::optional<MemoryRegionInfos> m_memory_regions;
void BuildMemoryRegions();
- bool IsLLDBMinidump() const;
+ bool IsLLDBMinidump();
};
} // namespace minidump
diff --git a/llvm/include/llvm/BinaryFormat/Minidump.h b/llvm/include/llvm/BinaryFormat/Minidump.h
index 75762d3196dfcd..e587c6d94efaf8 100644
--- a/llvm/include/llvm/BinaryFormat/Minidump.h
+++ b/llvm/include/llvm/BinaryFormat/Minidump.h
@@ -32,10 +32,6 @@ LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
struct Header {
static constexpr uint32_t MagicSignature = 0x504d444d; // PMDM
static constexpr uint16_t MagicVersion = 0xa793;
- // We set all the high bits flag to indicate this is from LLDB.
- // We don't want to conflict with anything Microsoft is using the flags for
- // and the highest bits are not currently being used.
- static const uint32_t LLDB_HEADER_FLAG = 0xF0000000;
support::ulittle32_t Signature;
// The high 16 bits of version field are implementation specific. The low 16
@@ -56,6 +52,7 @@ enum class StreamType : uint32_t {
#include "llvm/BinaryFormat/MinidumpConstants.def"
Unused = 0,
LastReserved = 0x0000ffff,
+ LLDBGenerated = 0x4C4C4442, // ASCII for 'LLDB'
};
/// Specifies the location (and size) of various objects in the minidump file.
More information about the lldb-commits
mailing list