[Lldb-commits] [lldb] r331394 - Use the UUID from the minidump's CodeView Record for placeholder modules
Leonard Mosescu via lldb-commits
lldb-commits at lists.llvm.org
Wed May 2 13:06:17 PDT 2018
Author: lemo
Date: Wed May 2 13:06:17 2018
New Revision: 331394
URL: http://llvm.org/viewvc/llvm-project?rev=331394&view=rev
Log:
Use the UUID from the minidump's CodeView Record for placeholder modules
This change adds support for two types of Minidump CodeView records:
PDB70 (reference: https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html)
This is by far the most common record type.
ELF BuildID (found in Breakpad/Crashpad generated minidumps)
This would set a proper UUID for placeholder modules, in turn enabling
an accurate match with local module images.
Differential Revision: https://reviews.llvm.org/D46292
Modified:
lldb/trunk/include/lldb/Core/Module.h
lldb/trunk/include/lldb/Core/ModuleSpec.h
lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py
lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py
lldb/trunk/source/Commands/CommandObjectTarget.cpp
lldb/trunk/source/Core/Module.cpp
lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.cpp
lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.h
lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.h
lldb/trunk/source/Plugins/Process/minidump/ProcessMinidump.cpp
Modified: lldb/trunk/include/lldb/Core/Module.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Module.h?rev=331394&r1=331393&r2=331394&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Module.h (original)
+++ lldb/trunk/include/lldb/Core/Module.h Wed May 2 13:06:17 2018
@@ -745,7 +745,7 @@ public:
TypeList *GetTypeList();
//------------------------------------------------------------------
- /// Get a pointer to the UUID value contained in this object.
+ /// Get a reference to the UUID value contained in this object.
///
/// If the executable image file doesn't not have a UUID value built into
/// the file format, an MD5 checksum of the entire file, or slice of the
@@ -1111,7 +1111,7 @@ protected:
std::atomic<bool> m_did_load_objfile{false};
std::atomic<bool> m_did_load_symbol_vendor{false};
- std::atomic<bool> m_did_parse_uuid{false};
+ std::atomic<bool> m_did_set_uuid{false};
mutable bool m_file_has_changed : 1,
m_first_file_changed_log : 1; /// See if the module was modified after it
/// was initially opened.
@@ -1161,6 +1161,8 @@ protected:
bool SetArchitecture(const ArchSpec &new_arch);
+ void SetUUID(const lldb_private::UUID &uuid);
+
SectionList *GetUnifiedSectionList();
friend class ModuleList;
Modified: lldb/trunk/include/lldb/Core/ModuleSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ModuleSpec.h?rev=331394&r1=331393&r2=331394&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ModuleSpec.h (original)
+++ lldb/trunk/include/lldb/Core/ModuleSpec.h Wed May 2 13:06:17 2018
@@ -34,9 +34,9 @@ public:
m_object_name(), m_object_offset(0), m_object_size(0),
m_source_mappings() {}
- ModuleSpec(const FileSpec &file_spec)
+ ModuleSpec(const FileSpec &file_spec, const UUID& uuid = UUID())
: m_file(file_spec), m_platform_file(), m_symbol_file(), m_arch(),
- m_uuid(), m_object_name(), m_object_offset(0),
+ m_uuid(uuid), m_object_name(), m_object_offset(0),
m_object_size(file_spec.GetByteSize()), m_source_mappings() {}
ModuleSpec(const FileSpec &file_spec, const ArchSpec &arch)
Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py?rev=331394&r1=331393&r2=331394&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py Wed May 2 13:06:17 2018
@@ -77,9 +77,49 @@ class MiniDumpNewTestCase(TestBase):
self.target = self.dbg.GetSelectedTarget()
self.process = self.target.LoadCore("linux-x86_64.dmp")
self.assertTrue(self.process, PROCESS_IS_VALID)
- self.assertEqual(self.target.GetNumModules(), 9)
- for module in self.target.modules:
+ expected_modules = [
+ {
+ 'filename' : 'linux-gate.so',
+ 'uuid' : '4EAD28F8-88EF-3520-872B-73C6F2FE7306-C41AF22F',
+ },
+ {
+ 'filename' : 'libm-2.19.so',
+ 'uuid' : 'D144258E-6149-00B2-55A3-1F3FD2283A87-8670D5BC',
+ },
+ {
+ 'filename' : 'libstdc++.so.6.0.19',
+ 'uuid' : '76190E92-2AF7-457D-078F-75C9B15FA184-E83EB506',
+ },
+ {
+ 'filename' : 'libc-2.19.so',
+ 'uuid' : 'CF699A15-CAAE-64F5-0311-FC4655B86DC3-9A479789',
+ },
+ {
+ 'filename' : 'linux-x86_64',
+ 'uuid' : 'E35C283B-C327-C287-62DB-788BF5A4078B-E2351448',
+ },
+ {
+ 'filename' : 'libgcc_s.so.1',
+ 'uuid' : '36311B44-5771-0AE5-578C-4BF00791DED7-359DBB92',
+ },
+ {
+ 'filename' : 'libpthread-2.19.so',
+ 'uuid' : '31E9F21A-E8C1-0396-171F-1E13DA157809-86FA696C',
+ },
+ {
+ 'filename' : 'ld-2.19.so',
+ 'uuid' : 'D0F53790-4076-D73F-29E4-A37341F8A449-E2EF6CD0',
+ },
+ {
+ 'filename' : 'libbreakpad.so',
+ 'uuid' : '784FD549-332D-826E-D23F-18C17C6F320A',
+ },
+ ]
+ self.assertEqual(self.target.GetNumModules(), len(expected_modules))
+ for module, expected in zip(self.target.modules, expected_modules):
self.assertTrue(module.IsValid())
+ self.assertEqual(module.file.basename, expected['filename'])
+ self.assertEqual(module.GetUUIDString(), expected['uuid'])
def test_thread_info_in_minidump(self):
"""Test that lldb can read the thread information from the Minidump."""
Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py?rev=331394&r1=331393&r2=331394&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py Wed May 2 13:06:17 2018
@@ -49,17 +49,36 @@ class MiniDumpTestCase(TestBase):
self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp")
self.assertTrue(self.process, PROCESS_IS_VALID)
expected_modules = [
- r"C:\Windows\System32/MSVCP120D.dll",
- r"C:\Windows\SysWOW64/kernel32.dll",
- r"C:\Users\amccarth\Documents\Visual Studio 2013\Projects\fizzbuzz\Debug/fizzbuzz.exe",
- r"C:\Windows\System32/MSVCR120D.dll",
- r"C:\Windows\SysWOW64/KERNELBASE.dll",
- r"C:\Windows\SysWOW64/ntdll.dll",
+ {
+ 'filename' : r"C:\Windows\System32/MSVCP120D.dll",
+ 'uuid' : '6E51053C-E757-EB40-8D3F-9722C5BD80DD-01000000',
+ },
+ {
+ 'filename' : r"C:\Windows\SysWOW64/kernel32.dll",
+ 'uuid' : '1B7ECBE5-5E00-1341-AB98-98D6913B52D8-02000000',
+ },
+ {
+ 'filename' : r"C:\Users\amccarth\Documents\Visual Studio 2013\Projects\fizzbuzz\Debug/fizzbuzz.exe",
+ 'uuid' : '91B7450F-969A-F946-BF8F-2D6076EA421A-11000000',
+ },
+ {
+ 'filename' : r"C:\Windows\System32/MSVCR120D.dll",
+ 'uuid' : '86FB8263-C446-4640-AE42-8D97B3F91FF2-01000000',
+ },
+ {
+ 'filename' : r"C:\Windows\SysWOW64/KERNELBASE.dll",
+ 'uuid' : '4152F90B-0DCB-D44B-AC5D-186A6452E522-01000000',
+ },
+ {
+ 'filename' : r"C:\Windows\SysWOW64/ntdll.dll",
+ 'uuid' : '6A84B0BB-2C40-5240-A16B-67650BBFE6B0-02000000',
+ },
]
self.assertEqual(self.target.GetNumModules(), len(expected_modules))
for module, expected in zip(self.target.modules, expected_modules):
self.assertTrue(module.IsValid())
- self.assertEqual(module.file.fullpath, expected)
+ self.assertEqual(module.file.fullpath, expected['filename'])
+ self.assertEqual(module.GetUUIDString(), expected['uuid'])
@expectedFailureAll(bugnumber="llvm.org/pr35193", hostoslist=["windows"])
def test_stack_info_in_mini_dump(self):
Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=331394&r1=331393&r2=331394&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Wed May 2 13:06:17 2018
@@ -1386,6 +1386,10 @@ static size_t DumpModuleObjfileHeaders(S
ObjectFile *objfile = module->GetObjectFile();
if (objfile)
objfile->Dump(&strm);
+ else {
+ strm.Format("No object file for module: {0:F}\n",
+ module->GetFileSpec());
+ }
}
}
strm.IndentLess();
Modified: lldb/trunk/source/Core/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Module.cpp?rev=331394&r1=331393&r2=331394&view=diff
==============================================================================
--- lldb/trunk/source/Core/Module.cpp (original)
+++ lldb/trunk/source/Core/Module.cpp Wed May 2 13:06:17 2018
@@ -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_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);
}
Modified: lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.cpp?rev=331394&r1=331393&r2=331394&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.cpp (original)
+++ lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.cpp Wed May 2 13:06:17 2018
@@ -96,6 +96,40 @@ llvm::Optional<std::string> MinidumpPars
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);
Modified: lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.h?rev=331394&r1=331393&r2=331394&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.h (original)
+++ lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.h Wed May 2 13:06:17 2018
@@ -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);
Modified: lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.h?rev=331394&r1=331393&r2=331394&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.h (original)
+++ lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.h Wed May 2 13:06:17 2018
@@ -43,6 +43,21 @@ enum class MinidumpHeaderConstants : uin
};
+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 {
Modified: lldb/trunk/source/Plugins/Process/minidump/ProcessMinidump.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/minidump/ProcessMinidump.cpp?rev=331394&r1=331393&r2=331394&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/minidump/ProcessMinidump.cpp (original)
+++ lldb/trunk/source/Plugins/Process/minidump/ProcessMinidump.cpp Wed May 2 13:06:17 2018
@@ -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);
More information about the lldb-commits
mailing list