brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.0 KiB · 91c4fd6 Raw
241 lines · cpp
1//===-- NativeProcessProtocolTest.cpp -------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "TestingSupport/Host/NativeProcessTestUtils.h"10 11#include "lldb/Host/common/NativeProcessProtocol.h"12#include "llvm/Support/Process.h"13#include "llvm/Testing/Support/Error.h"14#include "gmock/gmock.h"15 16using namespace lldb_private;17using namespace lldb;18using namespace testing;19 20TEST(NativeProcessProtocolTest, SetBreakpoint) {21  NiceMock<MockDelegate> DummyDelegate;22  MockProcess<NativeProcessProtocol> Process(DummyDelegate,23                                             ArchSpec("x86_64-pc-linux"));24  auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1));25  InSequence S;26  EXPECT_CALL(Process, ReadMemory(0x47, 1))27      .WillOnce(Return(ByMove(std::vector<uint8_t>{0xbb})));28  EXPECT_CALL(Process, WriteMemory(0x47, Trap)).WillOnce(Return(ByMove(1)));29  EXPECT_CALL(Process, ReadMemory(0x47, 1)).WillOnce(Return(ByMove(Trap)));30  EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),31                    llvm::Succeeded());32}33 34TEST(NativeProcessProtocolTest, SetBreakpointFailRead) {35  NiceMock<MockDelegate> DummyDelegate;36  MockProcess<NativeProcessProtocol> Process(DummyDelegate,37                                             ArchSpec("x86_64-pc-linux"));38  EXPECT_CALL(Process, ReadMemory(0x47, 1))39      .WillOnce(Return(ByMove(40          llvm::createStringError(llvm::inconvertibleErrorCode(), "Foo"))));41  EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),42                    llvm::Failed());43}44 45TEST(NativeProcessProtocolTest, SetBreakpointFailWrite) {46  NiceMock<MockDelegate> DummyDelegate;47  MockProcess<NativeProcessProtocol> Process(DummyDelegate,48                                             ArchSpec("x86_64-pc-linux"));49  auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1));50  InSequence S;51  EXPECT_CALL(Process, ReadMemory(0x47, 1))52      .WillOnce(Return(ByMove(std::vector<uint8_t>{0xbb})));53  EXPECT_CALL(Process, WriteMemory(0x47, Trap))54      .WillOnce(Return(ByMove(55          llvm::createStringError(llvm::inconvertibleErrorCode(), "Foo"))));56  EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),57                    llvm::Failed());58}59 60TEST(NativeProcessProtocolTest, SetBreakpointFailVerify) {61  NiceMock<MockDelegate> DummyDelegate;62  MockProcess<NativeProcessProtocol> Process(DummyDelegate,63                                             ArchSpec("x86_64-pc-linux"));64  auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1));65  InSequence S;66  EXPECT_CALL(Process, ReadMemory(0x47, 1))67      .WillOnce(Return(ByMove(std::vector<uint8_t>{0xbb})));68  EXPECT_CALL(Process, WriteMemory(0x47, Trap)).WillOnce(Return(ByMove(1)));69  EXPECT_CALL(Process, ReadMemory(0x47, 1))70      .WillOnce(Return(ByMove(71          llvm::createStringError(llvm::inconvertibleErrorCode(), "Foo"))));72  EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),73                    llvm::Failed());74}75 76TEST(NativeProcessProtocolTest, RemoveSoftwareBreakpoint) {77  NiceMock<MockDelegate> DummyDelegate;78  MockProcess<NativeProcessProtocol> Process(DummyDelegate,79                                             ArchSpec("x86_64-pc-linux"));80  auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1));81  auto Original = std::vector<uint8_t>{0xbb};82 83  // Set up a breakpoint.84  {85    InSequence S;86    EXPECT_CALL(Process, ReadMemory(0x47, 1))87        .WillOnce(Return(ByMove(Original)));88    EXPECT_CALL(Process, WriteMemory(0x47, Trap)).WillOnce(Return(ByMove(1)));89    EXPECT_CALL(Process, ReadMemory(0x47, 1)).WillOnce(Return(ByMove(Trap)));90    EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),91                      llvm::Succeeded());92  }93 94  // Remove the breakpoint for the first time. This should remove the breakpoint95  // from m_software_breakpoints.96  //97  // Should succeed.98  {99    InSequence S;100    EXPECT_CALL(Process, ReadMemory(0x47, 1)).WillOnce(Return(ByMove(Trap)));101    EXPECT_CALL(Process, WriteMemory(0x47, llvm::ArrayRef(Original)))102        .WillOnce(Return(ByMove(1)));103    EXPECT_CALL(Process, ReadMemory(0x47, 1))104        .WillOnce(Return(ByMove(Original)));105    EXPECT_THAT_ERROR(Process.RemoveBreakpoint(0x47, false).ToError(),106                      llvm::Succeeded());107  }108 109  // Remove the breakpoint for the second time.110  //111  // Should fail. None of the ReadMemory() or WriteMemory() should be called,112  // because the function should early return when seeing that the breakpoint113  // isn't in m_software_breakpoints.114  {115    EXPECT_CALL(Process, ReadMemory(_, _)).Times(0);116    EXPECT_CALL(Process, WriteMemory(_, _)).Times(0);117    EXPECT_THAT_ERROR(Process.RemoveBreakpoint(0x47, false).ToError(),118                      llvm::Failed());119  }120}121 122TEST(NativeProcessProtocolTest, RemoveSoftwareBreakpointMemoryError) {123  NiceMock<MockDelegate> DummyDelegate;124  MockProcess<NativeProcessProtocol> Process(DummyDelegate,125                                             ArchSpec("x86_64-pc-linux"));126  auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1));127  auto Original = std::vector<uint8_t>{0xbb};128  auto SomethingElse = std::vector<uint8_t>{0xaa};129 130  // Set up a breakpoint.131  {132    InSequence S;133    EXPECT_CALL(Process, ReadMemory(0x47, 1))134        .WillOnce(Return(ByMove(Original)));135    EXPECT_CALL(Process, WriteMemory(0x47, Trap)).WillOnce(Return(ByMove(1)));136    EXPECT_CALL(Process, ReadMemory(0x47, 1)).WillOnce(Return(ByMove(Trap)));137    EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),138                      llvm::Succeeded());139  }140 141  // Remove the breakpoint for the first time, with an unexpected value read by142  // the first ReadMemory(). This should cause an early return, with the143  // breakpoint removed from m_software_breakpoints.144  //145  // Should fail.146  {147    InSequence S;148    EXPECT_CALL(Process, ReadMemory(0x47, 1))149        .WillOnce(Return(ByMove(SomethingElse)));150    EXPECT_THAT_ERROR(Process.RemoveBreakpoint(0x47, false).ToError(),151                      llvm::Failed());152  }153 154  // Remove the breakpoint for the second time.155  //156  // Should fail. None of the ReadMemory() or WriteMemory() should be called,157  // because the function should early return when seeing that the breakpoint158  // isn't in m_software_breakpoints.159  {160    EXPECT_CALL(Process, ReadMemory(_, _)).Times(0);161    EXPECT_CALL(Process, WriteMemory(_, _)).Times(0);162    EXPECT_THAT_ERROR(Process.RemoveBreakpoint(0x47, false).ToError(),163                      llvm::Failed());164  }165}166 167TEST(NativeProcessProtocolTest, ReadMemoryWithoutTrap) {168  NiceMock<MockDelegate> DummyDelegate;169  MockProcess<NativeProcessProtocol> Process(DummyDelegate,170                                             ArchSpec("aarch64-pc-linux"));171  FakeMemory M{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};172  EXPECT_CALL(Process, ReadMemory(_, _))173      .WillRepeatedly(Invoke(&M, &FakeMemory::Read));174  EXPECT_CALL(Process, WriteMemory(_, _))175      .WillRepeatedly(Invoke(&M, &FakeMemory::Write));176 177  EXPECT_THAT_ERROR(Process.SetBreakpoint(0x4, 0, false).ToError(),178                    llvm::Succeeded());179  EXPECT_THAT_EXPECTED(180      Process.ReadMemoryWithoutTrap(0, 10),181      llvm::HasValue(std::vector<uint8_t>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}));182  EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(0, 6),183                       llvm::HasValue(std::vector<uint8_t>{0, 1, 2, 3, 4, 5}));184  EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(6, 4),185                       llvm::HasValue(std::vector<uint8_t>{6, 7, 8, 9}));186  EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(6, 2),187                       llvm::HasValue(std::vector<uint8_t>{6, 7}));188  EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(4, 2),189                       llvm::HasValue(std::vector<uint8_t>{4, 5}));190}191 192TEST(NativeProcessProtocolTest, ReadCStringFromMemory) {193  NiceMock<MockDelegate> DummyDelegate;194  MockProcess<NativeProcessProtocol> Process(DummyDelegate,195                                             ArchSpec("aarch64-pc-linux"));196  FakeMemory M({'h', 'e', 'l', 'l', 'o', 0, 'w', 'o'});197  EXPECT_CALL(Process, ReadMemory(_, _))198      .WillRepeatedly(Invoke(&M, &FakeMemory::Read));199 200  char string[1024];201  size_t bytes_read;202  EXPECT_THAT_EXPECTED(Process.ReadCStringFromMemory(203                           0x0, &string[0], sizeof(string), bytes_read),204                       llvm::HasValue(llvm::StringRef("hello")));205  EXPECT_EQ(bytes_read, 6UL);206}207 208TEST(NativeProcessProtocolTest, ReadCStringFromMemory_MaxSize) {209  NiceMock<MockDelegate> DummyDelegate;210  MockProcess<NativeProcessProtocol> Process(DummyDelegate,211                                             ArchSpec("aarch64-pc-linux"));212  FakeMemory M({'h', 'e', 'l', 'l', 'o', 0, 'w', 'o'});213  EXPECT_CALL(Process, ReadMemory(_, _))214      .WillRepeatedly(Invoke(&M, &FakeMemory::Read));215 216  char string[4];217  size_t bytes_read;218  EXPECT_THAT_EXPECTED(Process.ReadCStringFromMemory(219                           0x0, &string[0], sizeof(string), bytes_read),220                       llvm::HasValue(llvm::StringRef("hel")));221  EXPECT_EQ(bytes_read, 3UL);222}223 224TEST(NativeProcessProtocolTest, ReadCStringFromMemory_CrossPageBoundary) {225  NiceMock<MockDelegate> DummyDelegate;226  MockProcess<NativeProcessProtocol> Process(DummyDelegate,227                                             ArchSpec("aarch64-pc-linux"));228  unsigned string_start = llvm::sys::Process::getPageSizeEstimate() - 3;229  FakeMemory M({'h', 'e', 'l', 'l', 'o', 0, 'w', 'o'}, string_start);230  EXPECT_CALL(Process, ReadMemory(_, _))231      .WillRepeatedly(Invoke(&M, &FakeMemory::Read));232 233  char string[1024];234  size_t bytes_read;235  EXPECT_THAT_EXPECTED(Process.ReadCStringFromMemory(string_start, &string[0],236                                                     sizeof(string),237                                                     bytes_read),238                       llvm::HasValue(llvm::StringRef("hello")));239  EXPECT_EQ(bytes_read, 6UL);240}241