diff options
Diffstat (limited to 'lldb/source')
| -rw-r--r-- | lldb/source/Commands/CommandObjectTarget.cpp | 4 | ||||
| -rw-r--r-- | lldb/source/Core/Module.cpp | 17 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/minidump/MinidumpParser.cpp | 34 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/minidump/MinidumpParser.h | 3 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/minidump/MinidumpTypes.h | 15 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp | 12 |
6 files changed, 78 insertions, 7 deletions
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 45204b6b0c2..ee7e0e914a2 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -1386,6 +1386,10 @@ static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) { ObjectFile *objfile = module->GetObjectFile(); if (objfile) objfile->Dump(&strm); + else { + strm.Format("No object file for module: {0:F}\n", + module->GetFileSpec()); + } } } strm.IndentLess(); diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 1ae4d4aaf57..94fbc72a5a6 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -38,6 +38,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" // for GetLogIfAn... #include "lldb/Utility/RegularExpression.h" @@ -321,20 +322,30 @@ ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp, } const lldb_private::UUID &Module::GetUUID() { - if (!m_did_parse_uuid.load()) { + if (!m_did_set_uuid.load()) { std::lock_guard<std::recursive_mutex> guard(m_mutex); - if (!m_did_parse_uuid.load()) { + if (!m_did_set_uuid.load()) { ObjectFile *obj_file = GetObjectFile(); if (obj_file != nullptr) { obj_file->GetUUID(&m_uuid); - m_did_parse_uuid = true; + m_did_set_uuid = true; } } } return m_uuid; } +void Module::SetUUID(const lldb_private::UUID &uuid) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (!m_did_set_uuid) { + m_uuid = uuid; + m_did_set_uuid = true; + } else { + lldbassert(!"Attempting to overwrite the existing module UUID"); + } +} + TypeSystem *Module::GetTypeSystemForLanguage(LanguageType language) { return m_type_system_map.GetTypeSystemForLanguage(language, this, true); } diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp index 5aa04e3e123..58cafc737fc 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -96,6 +96,40 @@ llvm::Optional<std::string> MinidumpParser::GetMinidumpString(uint32_t rva) { return parseMinidumpString(arr_ref); } +UUID MinidumpParser::GetModuleUUID(const MinidumpModule *module) { + auto cv_record = + GetData().slice(module->CV_record.rva, module->CV_record.data_size); + + // Read the CV record signature + const llvm::support::ulittle32_t *signature = nullptr; + Status error = consumeObject(cv_record, signature); + if (error.Fail()) + return UUID(); + + const CvSignature cv_signature = + static_cast<CvSignature>(static_cast<const uint32_t>(*signature)); + + if (cv_signature == CvSignature::Pdb70) { + // PDB70 record + const CvRecordPdb70 *pdb70_uuid = nullptr; + Status error = consumeObject(cv_record, pdb70_uuid); + if (!error.Fail()) + return UUID(pdb70_uuid, sizeof(*pdb70_uuid)); + } else if (cv_signature == CvSignature::ElfBuildId) { + // ELF BuildID (found in Breakpad/Crashpad generated minidumps) + // + // This is variable-length, but usually 20 bytes + // as the binutils ld default is a SHA-1 hash. + // (We'll handle only 16 and 20 bytes signatures, + // matching LLDB support for UUIDs) + // + if (cv_record.size() == 16 || cv_record.size() == 20) + return UUID(cv_record.data(), cv_record.size()); + } + + return UUID(); +} + llvm::ArrayRef<MinidumpThread> MinidumpParser::GetThreads() { llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::ThreadList); diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h index b7329ffc002..1814e9afacf 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h @@ -17,6 +17,7 @@ #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/Status.h" +#include "lldb/Utility/UUID.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -54,6 +55,8 @@ public: llvm::Optional<std::string> GetMinidumpString(uint32_t rva); + UUID GetModuleUUID(const MinidumpModule* module); + llvm::ArrayRef<MinidumpThread> GetThreads(); llvm::ArrayRef<uint8_t> GetThreadContext(const MinidumpThread &td); diff --git a/lldb/source/Plugins/Process/minidump/MinidumpTypes.h b/lldb/source/Plugins/Process/minidump/MinidumpTypes.h index 6de4f55a769..e83089865b9 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpTypes.h +++ b/lldb/source/Plugins/Process/minidump/MinidumpTypes.h @@ -43,6 +43,21 @@ enum class MinidumpHeaderConstants : uint32_t { }; +enum class CvSignature : uint32_t { + Pdb70 = 0x53445352, // RSDS + ElfBuildId = 0x4270454c, // BpEL (Breakpad/Crashpad minidumps) +}; + +// Reference: +// https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html +struct CvRecordPdb70 { + uint8_t Uuid[16]; + llvm::support::ulittle32_t Age; + // char PDBFileName[]; +}; +static_assert(sizeof(CvRecordPdb70) == 20, + "sizeof CvRecordPdb70 is not correct!"); + // Reference: // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680394.aspx enum class MinidumpStreamType : uint32_t { diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp index 0f4f1236c4b..8149f95f239 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -46,8 +46,11 @@ using namespace minidump; //------------------------------------------------------------------ class PlaceholderModule : public Module { public: - PlaceholderModule(const FileSpec &file_spec, const ArchSpec &arch) : - Module(file_spec, arch) {} + PlaceholderModule(const ModuleSpec &module_spec) : + Module(module_spec.GetFileSpec(), module_spec.GetArchitecture()) { + if (module_spec.GetUUID().IsValid()) + SetUUID(module_spec.GetUUID()); + } // Creates a synthetic module section covering the whole module image (and // sets the section load address as well) @@ -321,9 +324,10 @@ void ProcessMinidump::ReadModuleList() { m_is_wow64 = true; } + const auto uuid = m_minidump_parser.GetModuleUUID(module); const auto file_spec = FileSpec(name.getValue(), true, GetArchitecture().GetTriple()); - ModuleSpec module_spec = file_spec; + ModuleSpec module_spec(file_spec, uuid); Status error; lldb::ModuleSP module_sp = GetTarget().GetSharedModule(module_spec, &error); if (!module_sp || error.Fail()) { @@ -335,7 +339,7 @@ void ProcessMinidump::ReadModuleList() { // translations (ex. identifing the module for a stack frame PC) and // modules/sections commands (ex. target modules list, ...) auto placeholder_module = - std::make_shared<PlaceholderModule>(file_spec, GetArchitecture()); + std::make_shared<PlaceholderModule>(module_spec); placeholder_module->CreateImageSection(module, GetTarget()); module_sp = placeholder_module; GetTarget().GetImages().Append(module_sp); |

