[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:
parent
65a2eb0b15
commit
accd4a4ad5
@ -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 =
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 ®ion_list) override;
|
||||
Status
|
||||
GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) override;
|
||||
|
||||
bool GetProcessInfo(ProcessInstanceInfo &info) override;
|
||||
|
||||
@ -113,6 +115,7 @@ private:
|
||||
std::optional<MemoryRegionInfos> m_memory_regions;
|
||||
|
||||
void BuildMemoryRegions();
|
||||
bool IsLLDBMinidump();
|
||||
};
|
||||
|
||||
} // namespace minidump
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user