From d7fd9573950d82401ca70fd37b573aa69907e642 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Fri, 22 Feb 2019 08:51:08 +0000 Subject: [PATCH] Split up minidump register context tests The tests were doing two somewhat independent things: - checking that the registers can be retrieved from the minidump file - checking that they can be converted into a form suitable for consumption by lldb The first thing requires a minidump file (but it's independent of other lldb structures), while the second one does not require a minidump file (but it needs lldb register info structures). Splitting this into two tests gives an opportunity to write more detailed tests, and allows the two pieces of functionality to be moved into different packages, if that proves to be necessary. llvm-svn: 354662 --- lldb/unittests/Process/minidump/CMakeLists.txt | 1 + .../Process/minidump/MinidumpParserTest.cpp | 207 +++++++++------------ .../minidump/RegisterContextMinidumpTest.cpp | 145 +++++++++++++++ 3 files changed, 230 insertions(+), 123 deletions(-) create mode 100644 lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp diff --git a/lldb/unittests/Process/minidump/CMakeLists.txt b/lldb/unittests/Process/minidump/CMakeLists.txt index 8407109..699c798 100644 --- a/lldb/unittests/Process/minidump/CMakeLists.txt +++ b/lldb/unittests/Process/minidump/CMakeLists.txt @@ -1,5 +1,6 @@ add_lldb_unittest(LLDBMinidumpTests MinidumpParserTest.cpp + RegisterContextMinidumpTest.cpp LINK_LIBS lldbCore diff --git a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp index c87889e..0248058 100644 --- a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp +++ b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp @@ -6,13 +6,10 @@ // //===----------------------------------------------------------------------===// -#include "Plugins/Process/Utility/RegisterContextLinux_i386.h" -#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" #include "Plugins/Process/minidump/MinidumpParser.h" #include "Plugins/Process/minidump/MinidumpTypes.h" #include "Plugins/Process/minidump/RegisterContextMinidump_x86_32.h" #include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h" - #include "TestingSupport/TestUtilities.h" #include "lldb/Host/FileSystem.h" #include "lldb/Target/MemoryRegionInfo.h" @@ -490,138 +487,102 @@ TEST_F(MinidumpParserTest, GetModuleListWow64) { #define REG_VAL32(x) *(reinterpret_cast(x)) #define REG_VAL64(x) *(reinterpret_cast(x)) -TEST_F(MinidumpParserTest, ConvertMinidumpContext_x86_32) { +TEST_F(MinidumpParserTest, GetThreadContext_x86_32) { SetUpData("linux-i386.dmp"); llvm::ArrayRef thread_list = parser->GetThreads(); const MinidumpThread thread = thread_list[0]; llvm::ArrayRef registers(parser->GetThreadContext(thread)); - - ArchSpec arch = parser->GetArchitecture(); - auto reg_interface = llvm::make_unique(arch); - lldb::DataBufferSP buf = - ConvertMinidumpContext_x86_32(registers, reg_interface.get()); - ASSERT_EQ(reg_interface->GetGPRSize(), buf->GetByteSize()); - - const RegisterInfo *reg_info = reg_interface->GetRegisterInfo(); - - std::map reg_values; - - reg_values[lldb_eax_i386] = 0x00000000; - reg_values[lldb_ebx_i386] = 0xf7778000; - reg_values[lldb_ecx_i386] = 0x00000001; - reg_values[lldb_edx_i386] = 0xff9dd4a3; - reg_values[lldb_edi_i386] = 0x080482a8; - reg_values[lldb_esi_i386] = 0xff9dd55c; - reg_values[lldb_ebp_i386] = 0xff9dd53c; - reg_values[lldb_esp_i386] = 0xff9dd52c; - reg_values[lldb_eip_i386] = 0x080482a0; - reg_values[lldb_eflags_i386] = 0x00010282; - reg_values[lldb_cs_i386] = 0x00000023; - reg_values[lldb_fs_i386] = 0x00000000; - reg_values[lldb_gs_i386] = 0x00000063; - reg_values[lldb_ss_i386] = 0x0000002b; - reg_values[lldb_ds_i386] = 0x0000002b; - reg_values[lldb_es_i386] = 0x0000002b; - - for (uint32_t reg_index = 0; reg_index < reg_interface->GetRegisterCount(); - ++reg_index) { - if (reg_values.find(reg_index) != reg_values.end()) { - EXPECT_EQ(reg_values[reg_index], - REG_VAL32(buf->GetBytes() + reg_info[reg_index].byte_offset)); - } - } -} - -TEST_F(MinidumpParserTest, ConvertMinidumpContext_x86_64) { + const MinidumpContext_x86_32 *context; + EXPECT_TRUE(consumeObject(registers, context).Success()); + + EXPECT_EQ(MinidumpContext_x86_32_Flags(uint32_t(context->context_flags)), + MinidumpContext_x86_32_Flags::x86_32_Flag | + MinidumpContext_x86_32_Flags::Full | + MinidumpContext_x86_32_Flags::FloatingPoint); + + EXPECT_EQ(0x00000000u, context->eax); + EXPECT_EQ(0xf7778000u, context->ebx); + EXPECT_EQ(0x00000001u, context->ecx); + EXPECT_EQ(0xff9dd4a3u, context->edx); + EXPECT_EQ(0x080482a8u, context->edi); + EXPECT_EQ(0xff9dd55cu, context->esi); + EXPECT_EQ(0xff9dd53cu, context->ebp); + EXPECT_EQ(0xff9dd52cu, context->esp); + EXPECT_EQ(0x080482a0u, context->eip); + EXPECT_EQ(0x00010282u, context->eflags); + EXPECT_EQ(0x0023u, context->cs); + EXPECT_EQ(0x0000u, context->fs); + EXPECT_EQ(0x0063u, context->gs); + EXPECT_EQ(0x002bu, context->ss); + EXPECT_EQ(0x002bu, context->ds); + EXPECT_EQ(0x002bu, context->es); +} + +TEST_F(MinidumpParserTest, GetThreadContext_x86_64) { SetUpData("linux-x86_64.dmp"); llvm::ArrayRef thread_list = parser->GetThreads(); const MinidumpThread thread = thread_list[0]; llvm::ArrayRef registers(parser->GetThreadContext(thread)); - - ArchSpec arch = parser->GetArchitecture(); - auto reg_interface = llvm::make_unique(arch); - lldb::DataBufferSP buf = - ConvertMinidumpContext_x86_64(registers, reg_interface.get()); - ASSERT_EQ(reg_interface->GetGPRSize(), buf->GetByteSize()); - - const RegisterInfo *reg_info = reg_interface->GetRegisterInfo(); - - std::map reg_values; - - reg_values[lldb_rax_x86_64] = 0x0000000000000000; - reg_values[lldb_rbx_x86_64] = 0x0000000000000000; - reg_values[lldb_rcx_x86_64] = 0x0000000000000010; - reg_values[lldb_rdx_x86_64] = 0x0000000000000000; - reg_values[lldb_rdi_x86_64] = 0x00007ffceb349cf0; - reg_values[lldb_rsi_x86_64] = 0x0000000000000000; - reg_values[lldb_rbp_x86_64] = 0x00007ffceb34a210; - reg_values[lldb_rsp_x86_64] = 0x00007ffceb34a210; - reg_values[lldb_r8_x86_64] = 0x00007fe9bc1aa9c0; - reg_values[lldb_r9_x86_64] = 0x0000000000000000; - reg_values[lldb_r10_x86_64] = 0x00007fe9bc3f16a0; - reg_values[lldb_r11_x86_64] = 0x0000000000000246; - reg_values[lldb_r12_x86_64] = 0x0000000000401c92; - reg_values[lldb_r13_x86_64] = 0x00007ffceb34a430; - reg_values[lldb_r14_x86_64] = 0x0000000000000000; - reg_values[lldb_r15_x86_64] = 0x0000000000000000; - reg_values[lldb_rip_x86_64] = 0x0000000000401dc6; - reg_values[lldb_rflags_x86_64] = 0x0000000000010206; - reg_values[lldb_cs_x86_64] = 0x0000000000000033; - reg_values[lldb_fs_x86_64] = 0x0000000000000000; - reg_values[lldb_gs_x86_64] = 0x0000000000000000; - reg_values[lldb_ss_x86_64] = 0x0000000000000000; - reg_values[lldb_ds_x86_64] = 0x0000000000000000; - reg_values[lldb_es_x86_64] = 0x0000000000000000; - - for (uint32_t reg_index = 0; reg_index < reg_interface->GetRegisterCount(); - ++reg_index) { - if (reg_values.find(reg_index) != reg_values.end()) { - EXPECT_EQ(reg_values[reg_index], - REG_VAL64(buf->GetBytes() + reg_info[reg_index].byte_offset)); - } - } -} - -TEST_F(MinidumpParserTest, ConvertMinidumpContext_x86_32_wow64) { + const MinidumpContext_x86_64 *context; + EXPECT_TRUE(consumeObject(registers, context).Success()); + + EXPECT_EQ(MinidumpContext_x86_64_Flags(uint32_t(context->context_flags)), + MinidumpContext_x86_64_Flags::x86_64_Flag | + MinidumpContext_x86_64_Flags::Control | + MinidumpContext_x86_64_Flags::FloatingPoint | + MinidumpContext_x86_64_Flags::Integer); + EXPECT_EQ(0x0000000000000000u, context->rax); + EXPECT_EQ(0x0000000000000000u, context->rbx); + EXPECT_EQ(0x0000000000000010u, context->rcx); + EXPECT_EQ(0x0000000000000000u, context->rdx); + EXPECT_EQ(0x00007ffceb349cf0u, context->rdi); + EXPECT_EQ(0x0000000000000000u, context->rsi); + EXPECT_EQ(0x00007ffceb34a210u, context->rbp); + EXPECT_EQ(0x00007ffceb34a210u, context->rsp); + EXPECT_EQ(0x00007fe9bc1aa9c0u, context->r8); + EXPECT_EQ(0x0000000000000000u, context->r9); + EXPECT_EQ(0x00007fe9bc3f16a0u, context->r10); + EXPECT_EQ(0x0000000000000246u, context->r11); + EXPECT_EQ(0x0000000000401c92u, context->r12); + EXPECT_EQ(0x00007ffceb34a430u, context->r13); + EXPECT_EQ(0x0000000000000000u, context->r14); + EXPECT_EQ(0x0000000000000000u, context->r15); + EXPECT_EQ(0x0000000000401dc6u, context->rip); + EXPECT_EQ(0x00010206u, context->eflags); + EXPECT_EQ(0x0033u, context->cs); + EXPECT_EQ(0x0000u, context->ss); +} + +TEST_F(MinidumpParserTest, GetThreadContext_x86_32_wow64) { SetUpData("fizzbuzz_wow64.dmp"); llvm::ArrayRef thread_list = parser->GetThreads(); const MinidumpThread thread = thread_list[0]; llvm::ArrayRef registers(parser->GetThreadContextWow64(thread)); - - ArchSpec arch = parser->GetArchitecture(); - auto reg_interface = llvm::make_unique(arch); - lldb::DataBufferSP buf = - ConvertMinidumpContext_x86_32(registers, reg_interface.get()); - ASSERT_EQ(reg_interface->GetGPRSize(), buf->GetByteSize()); - - const RegisterInfo *reg_info = reg_interface->GetRegisterInfo(); - - std::map reg_values; - - reg_values[lldb_eax_i386] = 0x00000000; - reg_values[lldb_ebx_i386] = 0x0037f608; - reg_values[lldb_ecx_i386] = 0x00e61578; - reg_values[lldb_edx_i386] = 0x00000008; - reg_values[lldb_edi_i386] = 0x00000000; - reg_values[lldb_esi_i386] = 0x00000002; - reg_values[lldb_ebp_i386] = 0x0037f654; - reg_values[lldb_esp_i386] = 0x0037f5b8; - reg_values[lldb_eip_i386] = 0x77ce01fd; - reg_values[lldb_eflags_i386] = 0x00000246; - reg_values[lldb_cs_i386] = 0x00000023; - reg_values[lldb_fs_i386] = 0x00000053; - reg_values[lldb_gs_i386] = 0x0000002b; - reg_values[lldb_ss_i386] = 0x0000002b; - reg_values[lldb_ds_i386] = 0x0000002b; - reg_values[lldb_es_i386] = 0x0000002b; - - for (uint32_t reg_index = 0; reg_index < reg_interface->GetRegisterCount(); - ++reg_index) { - if (reg_values.find(reg_index) != reg_values.end()) { - EXPECT_EQ(reg_values[reg_index], - REG_VAL32(buf->GetBytes() + reg_info[reg_index].byte_offset)); - } - } + const MinidumpContext_x86_32 *context; + EXPECT_TRUE(consumeObject(registers, context).Success()); + + EXPECT_EQ(MinidumpContext_x86_32_Flags(uint32_t(context->context_flags)), + MinidumpContext_x86_32_Flags::x86_32_Flag | + MinidumpContext_x86_32_Flags::Full | + MinidumpContext_x86_32_Flags::FloatingPoint | + MinidumpContext_x86_32_Flags::ExtendedRegisters); + + EXPECT_EQ(0x00000000u, context->eax); + EXPECT_EQ(0x0037f608u, context->ebx); + EXPECT_EQ(0x00e61578u, context->ecx); + EXPECT_EQ(0x00000008u, context->edx); + EXPECT_EQ(0x00000000u, context->edi); + EXPECT_EQ(0x00000002u, context->esi); + EXPECT_EQ(0x0037f654u, context->ebp); + EXPECT_EQ(0x0037f5b8u, context->esp); + EXPECT_EQ(0x77ce01fdu, context->eip); + EXPECT_EQ(0x00000246u, context->eflags); + EXPECT_EQ(0x0023u, context->cs); + EXPECT_EQ(0x0053u, context->fs); + EXPECT_EQ(0x002bu, context->gs); + EXPECT_EQ(0x002bu, context->ss); + EXPECT_EQ(0x002bu, context->ds); + EXPECT_EQ(0x002bu, context->es); } TEST_F(MinidumpParserTest, MinidumpDuplicateModuleMinAddress) { diff --git a/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp b/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp new file mode 100644 index 0000000..adc65d4 --- /dev/null +++ b/lldb/unittests/Process/minidump/RegisterContextMinidumpTest.cpp @@ -0,0 +1,145 @@ +//===-- RegisterContextMinidumpTest.cpp -------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/Process/Utility/RegisterContextLinux_i386.h" +#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" +#include "Plugins/Process/minidump/RegisterContextMinidump_x86_32.h" +#include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h" +#include "lldb/Utility/DataBuffer.h" +#include "gtest/gtest.h" + +using namespace lldb_private; +using namespace lldb_private::minidump; + +static uint32_t reg32(const DataBuffer &Buf, const RegisterInfo &Info) { + return *reinterpret_cast(Buf.GetBytes() + Info.byte_offset); +} + +static uint64_t reg64(const DataBuffer &Buf, const RegisterInfo &Info) { + return *reinterpret_cast(Buf.GetBytes() + Info.byte_offset); +} + +TEST(RegisterContextMinidump, ConvertMinidumpContext_x86_32) { + MinidumpContext_x86_32 Context; + Context.context_flags = + static_cast(MinidumpContext_x86_32_Flags::x86_32_Flag | + MinidumpContext_x86_32_Flags::Control | + MinidumpContext_x86_32_Flags::Segments | + MinidumpContext_x86_32_Flags::Integer); + Context.eax = 0x00010203; + Context.ebx = 0x04050607; + Context.ecx = 0x08090a0b; + Context.edx = 0x0c0d0e0f; + Context.edi = 0x10111213; + Context.esi = 0x14151617; + Context.ebp = 0x18191a1b; + Context.esp = 0x1c1d1e1f; + Context.eip = 0x20212223; + Context.eflags = 0x24252627; + Context.cs = 0x2829; + Context.fs = 0x2a2b; + Context.gs = 0x2c2d; + Context.ss = 0x2e2f; + Context.ds = 0x3031; + Context.es = 0x3233; + llvm::ArrayRef ContextRef(reinterpret_cast(&Context), + sizeof(Context)); + + ArchSpec arch("i386-pc-linux"); + auto RegInterface = llvm::make_unique(arch); + lldb::DataBufferSP Buf = + ConvertMinidumpContext_x86_32(ContextRef, RegInterface.get()); + ASSERT_EQ(RegInterface->GetGPRSize(), Buf->GetByteSize()); + + const RegisterInfo *Info = RegInterface->GetRegisterInfo(); + ASSERT_NE(nullptr, Info); + + EXPECT_EQ(Context.eax, reg32(*Buf, Info[lldb_eax_i386])); + EXPECT_EQ(Context.ebx, reg32(*Buf, Info[lldb_ebx_i386])); + EXPECT_EQ(Context.ecx, reg32(*Buf, Info[lldb_ecx_i386])); + EXPECT_EQ(Context.edx, reg32(*Buf, Info[lldb_edx_i386])); + EXPECT_EQ(Context.edi, reg32(*Buf, Info[lldb_edi_i386])); + EXPECT_EQ(Context.esi, reg32(*Buf, Info[lldb_esi_i386])); + EXPECT_EQ(Context.ebp, reg32(*Buf, Info[lldb_ebp_i386])); + EXPECT_EQ(Context.esp, reg32(*Buf, Info[lldb_esp_i386])); + EXPECT_EQ(Context.eip, reg32(*Buf, Info[lldb_eip_i386])); + EXPECT_EQ(Context.eflags, reg32(*Buf, Info[lldb_eflags_i386])); + EXPECT_EQ(Context.cs, reg32(*Buf, Info[lldb_cs_i386])); + EXPECT_EQ(Context.fs, reg32(*Buf, Info[lldb_fs_i386])); + EXPECT_EQ(Context.gs, reg32(*Buf, Info[lldb_gs_i386])); + EXPECT_EQ(Context.ss, reg32(*Buf, Info[lldb_ss_i386])); + EXPECT_EQ(Context.ds, reg32(*Buf, Info[lldb_ds_i386])); + EXPECT_EQ(Context.es, reg32(*Buf, Info[lldb_es_i386])); +} + +TEST(RegisterContextMinidump, ConvertMinidumpContext_x86_64) { + MinidumpContext_x86_64 Context; + Context.context_flags = + static_cast(MinidumpContext_x86_64_Flags::x86_64_Flag | + MinidumpContext_x86_64_Flags::Control | + MinidumpContext_x86_64_Flags::Segments | + MinidumpContext_x86_64_Flags::Integer); + Context.rax = 0x0001020304050607; + Context.rbx = 0x08090a0b0c0d0e0f; + Context.rcx = 0x1011121314151617; + Context.rdx = 0x18191a1b1c1d1e1f; + Context.rdi = 0x2021222324252627; + Context.rsi = 0x28292a2b2c2d2e2f; + Context.rbp = 0x3031323334353637; + Context.rsp = 0x38393a3b3c3d3e3f; + Context.r8 = 0x4041424344454647; + Context.r9 = 0x48494a4b4c4d4e4f; + Context.r10 = 0x5051525354555657; + Context.r11 = 0x58595a5b5c5d5e5f; + Context.r12 = 0x6061626364656667; + Context.r13 = 0x68696a6b6c6d6e6f; + Context.r14 = 0x7071727374757677; + Context.r15 = 0x78797a7b7c7d7e7f; + Context.rip = 0x8081828384858687; + Context.eflags = 0x88898a8b; + Context.cs = 0x8c8d; + Context.fs = 0x8e8f; + Context.gs = 0x9091; + Context.ss = 0x9293; + Context.ds = 0x9495; + Context.ss = 0x9697; + llvm::ArrayRef ContextRef(reinterpret_cast(&Context), + sizeof(Context)); + + ArchSpec arch("x86_64-pc-linux"); + auto RegInterface = llvm::make_unique(arch); + lldb::DataBufferSP Buf = + ConvertMinidumpContext_x86_64(ContextRef, RegInterface.get()); + ASSERT_EQ(RegInterface->GetGPRSize(), Buf->GetByteSize()); + + const RegisterInfo *Info = RegInterface->GetRegisterInfo(); + EXPECT_EQ(Context.rax, reg64(*Buf, Info[lldb_rax_x86_64])); + EXPECT_EQ(Context.rbx, reg64(*Buf, Info[lldb_rbx_x86_64])); + EXPECT_EQ(Context.rcx, reg64(*Buf, Info[lldb_rcx_x86_64])); + EXPECT_EQ(Context.rdx, reg64(*Buf, Info[lldb_rdx_x86_64])); + EXPECT_EQ(Context.rdi, reg64(*Buf, Info[lldb_rdi_x86_64])); + EXPECT_EQ(Context.rsi, reg64(*Buf, Info[lldb_rsi_x86_64])); + EXPECT_EQ(Context.rbp, reg64(*Buf, Info[lldb_rbp_x86_64])); + EXPECT_EQ(Context.rsp, reg64(*Buf, Info[lldb_rsp_x86_64])); + EXPECT_EQ(Context.r8, reg64(*Buf, Info[lldb_r8_x86_64])); + EXPECT_EQ(Context.r9, reg64(*Buf, Info[lldb_r9_x86_64])); + EXPECT_EQ(Context.r10, reg64(*Buf, Info[lldb_r10_x86_64])); + EXPECT_EQ(Context.r11, reg64(*Buf, Info[lldb_r11_x86_64])); + EXPECT_EQ(Context.r12, reg64(*Buf, Info[lldb_r12_x86_64])); + EXPECT_EQ(Context.r13, reg64(*Buf, Info[lldb_r13_x86_64])); + EXPECT_EQ(Context.r14, reg64(*Buf, Info[lldb_r14_x86_64])); + EXPECT_EQ(Context.r15, reg64(*Buf, Info[lldb_r15_x86_64])); + EXPECT_EQ(Context.rip, reg64(*Buf, Info[lldb_rip_x86_64])); + EXPECT_EQ(Context.eflags, reg64(*Buf, Info[lldb_rflags_x86_64])); + EXPECT_EQ(Context.cs, reg64(*Buf, Info[lldb_cs_x86_64])); + EXPECT_EQ(Context.fs, reg64(*Buf, Info[lldb_fs_x86_64])); + EXPECT_EQ(Context.gs, reg64(*Buf, Info[lldb_gs_x86_64])); + EXPECT_EQ(Context.ss, reg64(*Buf, Info[lldb_ss_x86_64])); + EXPECT_EQ(Context.ds, reg64(*Buf, Info[lldb_ds_x86_64])); + EXPECT_EQ(Context.es, reg64(*Buf, Info[lldb_es_x86_64])); +} -- 2.7.4