summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp21
-rw-r--r--lldb/unittests/Process/minidump/CMakeLists.txt8
-rw-r--r--lldb/unittests/Process/minidump/Inputs/memory-list-not-padded.dmpbin0 -> 107 bytes
-rw-r--r--lldb/unittests/Process/minidump/Inputs/memory-list-padded.dmpbin0 -> 111 bytes
-rw-r--r--lldb/unittests/Process/minidump/Inputs/module-list-not-padded.dmpbin0 -> 296 bytes
-rw-r--r--lldb/unittests/Process/minidump/Inputs/module-list-padded.dmpbin0 -> 300 bytes
-rw-r--r--lldb/unittests/Process/minidump/Inputs/thread-list-not-padded.dmpbin0 -> 144 bytes
-rw-r--r--lldb/unittests/Process/minidump/Inputs/thread-list-padded.dmpbin0 -> 148 bytes
-rw-r--r--lldb/unittests/Process/minidump/MinidumpParserTest.cpp70
9 files changed, 96 insertions, 3 deletions
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp b/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp
index b095aeb2c75..049704ba80c 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp
@@ -81,11 +81,17 @@ const MinidumpThread *MinidumpThread::Parse(llvm::ArrayRef<uint8_t> &data) {
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::Parse(llvm::ArrayRef<uint8_t> &data) {
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::ArrayRef<uint8_t> &data) {
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()),
diff --git a/lldb/unittests/Process/minidump/CMakeLists.txt b/lldb/unittests/Process/minidump/CMakeLists.txt
index 308b77a9184..a4ebb074b95 100644
--- a/lldb/unittests/Process/minidump/CMakeLists.txt
+++ b/lldb/unittests/Process/minidump/CMakeLists.txt
@@ -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}")
diff --git a/lldb/unittests/Process/minidump/Inputs/memory-list-not-padded.dmp b/lldb/unittests/Process/minidump/Inputs/memory-list-not-padded.dmp
new file mode 100644
index 00000000000..cb7b5fb7ee8
--- /dev/null
+++ b/lldb/unittests/Process/minidump/Inputs/memory-list-not-padded.dmp
Binary files differ
diff --git a/lldb/unittests/Process/minidump/Inputs/memory-list-padded.dmp b/lldb/unittests/Process/minidump/Inputs/memory-list-padded.dmp
new file mode 100644
index 00000000000..8b7e837e39d
--- /dev/null
+++ b/lldb/unittests/Process/minidump/Inputs/memory-list-padded.dmp
Binary files differ
diff --git a/lldb/unittests/Process/minidump/Inputs/module-list-not-padded.dmp b/lldb/unittests/Process/minidump/Inputs/module-list-not-padded.dmp
new file mode 100644
index 00000000000..b37e251ce21
--- /dev/null
+++ b/lldb/unittests/Process/minidump/Inputs/module-list-not-padded.dmp
Binary files differ
diff --git a/lldb/unittests/Process/minidump/Inputs/module-list-padded.dmp b/lldb/unittests/Process/minidump/Inputs/module-list-padded.dmp
new file mode 100644
index 00000000000..431c7c025b2
--- /dev/null
+++ b/lldb/unittests/Process/minidump/Inputs/module-list-padded.dmp
Binary files differ
diff --git a/lldb/unittests/Process/minidump/Inputs/thread-list-not-padded.dmp b/lldb/unittests/Process/minidump/Inputs/thread-list-not-padded.dmp
new file mode 100644
index 00000000000..34ba5cc34c8
--- /dev/null
+++ b/lldb/unittests/Process/minidump/Inputs/thread-list-not-padded.dmp
Binary files differ
diff --git a/lldb/unittests/Process/minidump/Inputs/thread-list-padded.dmp b/lldb/unittests/Process/minidump/Inputs/thread-list-padded.dmp
new file mode 100644
index 00000000000..838a4dfb51f
--- /dev/null
+++ b/lldb/unittests/Process/minidump/Inputs/thread-list-padded.dmp
Binary files differ
diff --git a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp
index 9a99f6bde64..cf4873fbc4f 100644
--- a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp
+++ b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp
@@ -84,6 +84,76 @@ TEST_F(MinidumpParserTest, GetThreadsAndGetThreadContext) {
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);
OpenPOWER on IntegriCloud