[LLDB][Minidump] Make workaround for the Dynamic loader issue (#120166)

In #119598 my recent TLS feature seems to break crashpad symbols. I have
a few ideas on how this is happening, but for now as a mitigation I'm
checking if the Minidump was LLDB generated, and if so leveraging the
dynamic loader.
This commit is contained in:
Jacob Lalonde 2024-12-30 10:48:16 -08:00 committed by GitHub
parent 65a2eb0b15
commit accd4a4ad5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 45 additions and 5 deletions

View File

@ -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
@ -90,7 +90,10 @@ Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
"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,12 @@ Status MinidumpFileBuilder::AddDirectory(StreamType type,
return error;
}
Status MinidumpFileBuilder::AddLLDBGeneratedStream() {
Status error;
StreamType type = StreamType::LLDBGenerated;
return AddDirectory(type, 0);
}
Status MinidumpFileBuilder::AddSystemInfo() {
Status error;
const llvm::Triple &target_triple =

View File

@ -120,6 +120,7 @@ public:
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);

View File

@ -49,6 +49,11 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetStream(StreamType stream_type) {
return m_file->getRawStream(stream_type).value_or(llvm::ArrayRef<uint8_t>());
}
std::optional<llvm::ArrayRef<uint8_t>>
MinidumpParser::GetRawStream(StreamType stream_type) {
return m_file->getRawStream(stream_type);
}
UUID MinidumpParser::GetModuleUUID(const minidump::Module *module) {
auto cv_record =
GetData().slice(module->CvRecord.RVA, module->CvRecord.DataSize);
@ -651,6 +656,7 @@ MinidumpParser::GetStreamTypeAsString(StreamType stream_type) {
ENUM_TO_CSTR(FacebookAbortReason);
ENUM_TO_CSTR(FacebookThreadName);
ENUM_TO_CSTR(FacebookLogcat);
ENUM_TO_CSTR(LLDBGenerated);
}
return "unknown stream type";
}

View File

@ -59,6 +59,7 @@ public:
llvm::ArrayRef<uint8_t> GetData();
llvm::ArrayRef<uint8_t> GetStream(StreamType stream_type);
std::optional<llvm::ArrayRef<uint8_t>> GetRawStream(StreamType stream_type);
UUID GetModuleUUID(const minidump::Module *module);

View File

@ -354,6 +354,22 @@ DataExtractor ProcessMinidump::GetAuxvData() {
GetAddressByteSize(), GetAddressByteSize());
}
bool ProcessMinidump::IsLLDBMinidump() {
std::optional<llvm::ArrayRef<uint8_t>> lldb_generated_section =
m_minidump_parser->GetRawStream(StreamType::LLDBGenerated);
return lldb_generated_section.has_value();
}
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;
}
void ProcessMinidump::BuildMemoryRegions() {
if (m_memory_regions)
return;

View File

@ -53,6 +53,8 @@ public:
Status DoLoadCore() override;
DynamicLoader *GetDynamicLoader() override;
// Returns AUXV structure found in the core file
lldb_private::DataExtractor GetAuxvData() override;
@ -74,8 +76,8 @@ public:
ArchSpec GetArchitecture();
Status GetMemoryRegions(
lldb_private::MemoryRegionInfos &region_list) override;
Status
GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) override;
bool GetProcessInfo(ProcessInstanceInfo &info) override;
@ -113,6 +115,7 @@ private:
std::optional<MemoryRegionInfos> m_memory_regions;
void BuildMemoryRegions();
bool IsLLDBMinidump();
};
} // namespace minidump

View File

@ -85,6 +85,10 @@ HANDLE_MDMP_STREAM_TYPE(0xFACECCCC, FacebookAppStateLog)
HANDLE_MDMP_STREAM_TYPE(0xFACEDEAD, FacebookAbortReason)
HANDLE_MDMP_STREAM_TYPE(0xFACEE000, FacebookThreadName)
// LLDB specific stream types
// Ascii for 'LLDB'
HANDLE_MDMP_STREAM_TYPE(0x4C4C4442, LLDBGenerated)
HANDLE_MDMP_ARCH(0x0000, X86) // PROCESSOR_ARCHITECTURE_INTEL
HANDLE_MDMP_ARCH(0x0001, MIPS) // PROCESSOR_ARCHITECTURE_MIPS
HANDLE_MDMP_ARCH(0x0002, Alpha) // PROCESSOR_ARCHITECTURE_ALPHA