[Lldb-commits] [lldb] r337694 - Add support for parsing Breakpad minidump files that can have extra padding in the module, thread and memory lists.

Greg Clayton via lldb-commits lldb-commits at lists.llvm.org
Mon Jul 23 07:16:08 PDT 2018


Author: gclayton
Date: Mon Jul 23 07:16:08 2018
New Revision: 337694

URL: http://llvm.org/viewvc/llvm-project?rev=337694&view=rev
Log:
Add support for parsing Breakpad minidump files that can have extra padding in the module, thread and memory lists.

Differential Revision: https://reviews.llvm.org/D49579


Added:
    lldb/trunk/unittests/Process/minidump/Inputs/memory-list-not-padded.dmp   (with props)
    lldb/trunk/unittests/Process/minidump/Inputs/memory-list-padded.dmp   (with props)
    lldb/trunk/unittests/Process/minidump/Inputs/module-list-not-padded.dmp   (with props)
    lldb/trunk/unittests/Process/minidump/Inputs/module-list-padded.dmp   (with props)
    lldb/trunk/unittests/Process/minidump/Inputs/thread-list-not-padded.dmp   (with props)
    lldb/trunk/unittests/Process/minidump/Inputs/thread-list-padded.dmp   (with props)
Modified:
    lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.cpp
    lldb/trunk/unittests/Process/minidump/CMakeLists.txt
    lldb/trunk/unittests/Process/minidump/MinidumpParserTest.cpp

Modified: lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.cpp?rev=337694&r1=337693&r2=337694&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.cpp (original)
+++ lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.cpp Mon Jul 23 07:16:08 2018
@@ -81,11 +81,17 @@ const MinidumpThread *MinidumpThread::Pa
 
 llvm::ArrayRef<MinidumpThread>
 MinidumpThread::ParseThreadList(llvm::ArrayRef<uint8_t> &data) {
+  const auto orig_size = data.size();
   const llvm::support::ulittle32_t *thread_count;
   Status error = consumeObject(data, thread_count);
   if (error.Fail() || *thread_count * sizeof(MinidumpThread) > data.size())
     return {};
 
+  // Compilers might end up padding an extra 4 bytes depending on how the
+  // structure is padded by the compiler and the #pragma pack settings.
+  if (4 + *thread_count * sizeof(MinidumpThread) < orig_size)
+    data = data.drop_front(4);
+
   return llvm::ArrayRef<MinidumpThread>(
       reinterpret_cast<const MinidumpThread *>(data.data()), *thread_count);
 }
@@ -157,12 +163,17 @@ const MinidumpModule *MinidumpModule::Pa
 
 llvm::ArrayRef<MinidumpModule>
 MinidumpModule::ParseModuleList(llvm::ArrayRef<uint8_t> &data) {
-
+  const auto orig_size = data.size();
   const llvm::support::ulittle32_t *modules_count;
   Status error = consumeObject(data, modules_count);
   if (error.Fail() || *modules_count * sizeof(MinidumpModule) > data.size())
     return {};
-
+  
+  // Compilers might end up padding an extra 4 bytes depending on how the
+  // structure is padded by the compiler and the #pragma pack settings.
+  if (4 + *modules_count * sizeof(MinidumpModule) < orig_size)
+    data = data.drop_front(4);
+  
   return llvm::ArrayRef<MinidumpModule>(
       reinterpret_cast<const MinidumpModule *>(data.data()), *modules_count);
 }
@@ -180,11 +191,17 @@ MinidumpExceptionStream::Parse(llvm::Arr
 
 llvm::ArrayRef<MinidumpMemoryDescriptor>
 MinidumpMemoryDescriptor::ParseMemoryList(llvm::ArrayRef<uint8_t> &data) {
+  const auto orig_size = data.size();
   const llvm::support::ulittle32_t *mem_ranges_count;
   Status error = consumeObject(data, mem_ranges_count);
   if (error.Fail() ||
       *mem_ranges_count * sizeof(MinidumpMemoryDescriptor) > data.size())
     return {};
+  
+  // Compilers might end up padding an extra 4 bytes depending on how the
+  // structure is padded by the compiler and the #pragma pack settings.
+  if (4 + *mem_ranges_count * sizeof(MinidumpMemoryDescriptor) < orig_size)
+    data = data.drop_front(4);
 
   return llvm::makeArrayRef(
       reinterpret_cast<const MinidumpMemoryDescriptor *>(data.data()),

Modified: lldb/trunk/unittests/Process/minidump/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Process/minidump/CMakeLists.txt?rev=337694&r1=337693&r2=337694&view=diff
==============================================================================
--- lldb/trunk/unittests/Process/minidump/CMakeLists.txt (original)
+++ lldb/trunk/unittests/Process/minidump/CMakeLists.txt Mon Jul 23 07:16:08 2018
@@ -19,6 +19,12 @@ set(test_inputs
    fizzbuzz_no_heap.dmp
    fizzbuzz_wow64.dmp
    bad_duplicate_streams.dmp
-   bad_overlapping_streams.dmp)
+   bad_overlapping_streams.dmp
+   thread-list-padded.dmp
+   thread-list-not-padded.dmp
+   module-list-padded.dmp
+   module-list-not-padded.dmp
+   memory-list-padded.dmp
+   memory-list-not-padded.dmp)
 
 add_unittest_inputs(LLDBMinidumpTests "${test_inputs}")

Added: lldb/trunk/unittests/Process/minidump/Inputs/memory-list-not-padded.dmp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Process/minidump/Inputs/memory-list-not-padded.dmp?rev=337694&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lldb/trunk/unittests/Process/minidump/Inputs/memory-list-not-padded.dmp
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lldb/trunk/unittests/Process/minidump/Inputs/memory-list-padded.dmp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Process/minidump/Inputs/memory-list-padded.dmp?rev=337694&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lldb/trunk/unittests/Process/minidump/Inputs/memory-list-padded.dmp
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lldb/trunk/unittests/Process/minidump/Inputs/module-list-not-padded.dmp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Process/minidump/Inputs/module-list-not-padded.dmp?rev=337694&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lldb/trunk/unittests/Process/minidump/Inputs/module-list-not-padded.dmp
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lldb/trunk/unittests/Process/minidump/Inputs/module-list-padded.dmp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Process/minidump/Inputs/module-list-padded.dmp?rev=337694&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lldb/trunk/unittests/Process/minidump/Inputs/module-list-padded.dmp
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lldb/trunk/unittests/Process/minidump/Inputs/thread-list-not-padded.dmp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Process/minidump/Inputs/thread-list-not-padded.dmp?rev=337694&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lldb/trunk/unittests/Process/minidump/Inputs/thread-list-not-padded.dmp
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lldb/trunk/unittests/Process/minidump/Inputs/thread-list-padded.dmp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Process/minidump/Inputs/thread-list-padded.dmp?rev=337694&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lldb/trunk/unittests/Process/minidump/Inputs/thread-list-padded.dmp
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: lldb/trunk/unittests/Process/minidump/MinidumpParserTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Process/minidump/MinidumpParserTest.cpp?rev=337694&r1=337693&r2=337694&view=diff
==============================================================================
--- lldb/trunk/unittests/Process/minidump/MinidumpParserTest.cpp (original)
+++ lldb/trunk/unittests/Process/minidump/MinidumpParserTest.cpp Mon Jul 23 07:16:08 2018
@@ -84,6 +84,76 @@ TEST_F(MinidumpParserTest, GetThreadsAnd
   EXPECT_EQ(1232UL, context.size());
 }
 
+TEST_F(MinidumpParserTest, GetThreadListNotPadded) {
+  // Verify that we can load a thread list that doesn't have 4 bytes of padding
+  // after the thread count.
+  SetUpData("thread-list-not-padded.dmp");
+  llvm::ArrayRef<MinidumpThread> thread_list;
+  
+  thread_list = parser->GetThreads();
+  ASSERT_EQ(2UL, thread_list.size());
+  EXPECT_EQ(0x11223344UL, thread_list[0].thread_id);
+  EXPECT_EQ(0x55667788UL, thread_list[1].thread_id);
+}
+
+TEST_F(MinidumpParserTest, GetThreadListPadded) {
+  // Verify that we can load a thread list that has 4 bytes of padding
+  // after the thread count as found in breakpad minidump files.
+  SetUpData("thread-list-padded.dmp");
+  auto thread_list = parser->GetThreads();
+  ASSERT_EQ(2UL, thread_list.size());
+  EXPECT_EQ(0x11223344UL, thread_list[0].thread_id);
+  EXPECT_EQ(0x55667788UL, thread_list[1].thread_id);
+}
+
+TEST_F(MinidumpParserTest, GetModuleListNotPadded) {
+  // Verify that we can load a module list that doesn't have 4 bytes of padding
+  // after the module count.
+  SetUpData("module-list-not-padded.dmp");
+  auto module_list = parser->GetModuleList();
+  ASSERT_EQ(2UL, module_list.size());
+  EXPECT_EQ(0x1000UL, module_list[0].base_of_image);
+  EXPECT_EQ(0x2000UL, module_list[0].size_of_image);
+  EXPECT_EQ(0x5000UL, module_list[1].base_of_image);
+  EXPECT_EQ(0x3000UL, module_list[1].size_of_image);
+}
+
+TEST_F(MinidumpParserTest, GetModuleListPadded) {
+  // Verify that we can load a module list that has 4 bytes of padding
+  // after the module count as found in breakpad minidump files.
+  SetUpData("module-list-padded.dmp");
+  auto module_list = parser->GetModuleList();
+  ASSERT_EQ(2UL, module_list.size());
+  EXPECT_EQ(0x1000UL, module_list[0].base_of_image);
+  EXPECT_EQ(0x2000UL, module_list[0].size_of_image);
+  EXPECT_EQ(0x5000UL, module_list[1].base_of_image);
+  EXPECT_EQ(0x3000UL, module_list[1].size_of_image);
+}
+
+TEST_F(MinidumpParserTest, GetMemoryListNotPadded) {
+  // Verify that we can load a memory list that doesn't have 4 bytes of padding
+  // after the memory range count.
+  SetUpData("memory-list-not-padded.dmp");
+  auto mem = parser->FindMemoryRange(0x8000);
+  ASSERT_TRUE(mem.hasValue());
+  EXPECT_EQ((lldb::addr_t)0x8000, mem->start);
+  mem = parser->FindMemoryRange(0x8010);
+  ASSERT_TRUE(mem.hasValue());
+  EXPECT_EQ((lldb::addr_t)0x8010, mem->start);
+}
+
+TEST_F(MinidumpParserTest, GetMemoryListPadded) {
+  // Verify that we can load a memory list that has 4 bytes of padding
+  // after the memory range count as found in breakpad minidump files.
+  SetUpData("memory-list-padded.dmp");
+  auto mem = parser->FindMemoryRange(0x8000);
+  ASSERT_TRUE(mem.hasValue());
+  EXPECT_EQ((lldb::addr_t)0x8000, mem->start);
+  mem = parser->FindMemoryRange(0x8010);
+  ASSERT_TRUE(mem.hasValue());
+  EXPECT_EQ((lldb::addr_t)0x8010, mem->start);
+}
+
 TEST_F(MinidumpParserTest, TruncatedMinidumps) {
   InvalidMinidump("linux-x86_64.dmp", 32);
   InvalidMinidump("linux-x86_64.dmp", 100);




More information about the lldb-commits mailing list