// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

#include "src/developer/debug/debug_agent/software_breakpoint.h"

#include <string.h>
#include <zircon/syscalls/exception.h>

#include <gtest/gtest.h>

#include "src/developer/debug/debug_agent/arch.h"
#include "src/developer/debug/debug_agent/breakpoint.h"
#include "src/developer/debug/debug_agent/debug_agent.h"
#include "src/developer/debug/debug_agent/debugged_thread.h"
#include "src/developer/debug/debug_agent/mock_job_handle.h"
#include "src/developer/debug/debug_agent/mock_process.h"
#include "src/developer/debug/debug_agent/mock_system_interface.h"
#include "src/developer/debug/debug_agent/mock_thread.h"
#include "src/developer/debug/shared/logging/debug.h"

namespace debug_agent {

namespace {

// A no-op process delegate.
class TestProcessDelegate : public Breakpoint::ProcessDelegate {
 public:
  TestProcessDelegate() = default;

  std::map<uint64_t, std::unique_ptr<ProcessBreakpoint>>& bps() { return bps_; }

  void InjectMockProcess(std::unique_ptr<MockProcess> proc) {
    procs_[proc->koid()] = std::move(proc);
  }

  // This only gets called if Breakpoint.SetSettings() is called.
  debug::Status RegisterBreakpoint(Breakpoint* bp, zx_koid_t koid, uint64_t address) override {
    auto found = bps_.find(address);
    if (found == bps_.end()) {
      auto pbp = std::make_unique<SoftwareBreakpoint>(bp, procs_[koid].get(), address);

      auto status = pbp->Init();
      if (status.has_error()) {
        fprintf(stderr, "Failure initializing %s\n", status.message().c_str());
        return status;
      }

      bps_[address] = std::move(pbp);
    } else {
      found->second->RegisterBreakpoint(bp);
    }
    return debug::Status();
  }
  void UnregisterBreakpoint(Breakpoint* bp, zx_koid_t, uint64_t address) override {
    auto found = bps_.find(address);
    if (found == bps_.end())
      GTEST_FAIL();

    bool still_used = found->second->UnregisterBreakpoint(bp);
    if (!still_used)
      bps_.erase(found);
  }

 private:
  std::map<uint64_t, std::unique_ptr<ProcessBreakpoint>> bps_;
  std::map<zx_koid_t, std::unique_ptr<MockProcess>> procs_;
};

constexpr uintptr_t kAddress = 0x1234;
constexpr size_t kDataSize = 4u;
const uint8_t kOriginalData[kDataSize] = {0x01, 0x02, 0x03, 0x04};

std::vector<uint8_t> GetOriginalData() {
  return std::vector<uint8_t>(std::begin(kOriginalData), std::end(kOriginalData));
}

// Returns the memory data buffer with the beginning overwritten by a software breakpoint.
std::vector<uint8_t> GetOriginalDataWithBreakpoint() {
  auto result = GetOriginalData();
  memcpy(result.data(), &arch::kBreakInstruction, sizeof(arch::kBreakInstruction));
  return result;
}

// Writes the original data or breakpoint data at |kAddress| to the mock data backing the given
// process handle.
void LoadOriginalMemory(MockProcessHandle& handle) {
  handle.mock_memory().AddMemory(kAddress, GetOriginalData());
}

bool MemoryContains(MockProcessHandle& handle, uint64_t address, const void* data,
                    size_t data_len) {
  if (data_len == 0)
    return true;

  std::unique_ptr<uint8_t[]> read(new uint8_t[data_len]);
  size_t actual = 0;
  if (handle.ReadMemory(address, read.get(), data_len, &actual).has_error() || actual != data_len)
    return false;

  return memcmp(data, read.get(), data_len) == 0;
}

bool MemoryContainsBreak(MockProcessHandle& handle, uint64_t address) {
  return MemoryContains(handle, address, &arch::kBreakInstruction, sizeof(arch::kBreakInstruction));
}
bool MemoryContainsOriginal(MockProcessHandle& handle, uint64_t address) {
  return MemoryContains(handle, address, kOriginalData, sizeof(arch::kBreakInstruction));
}

template <typename T>
std::string ToString(const std::vector<T>& v) {
  std::stringstream ss;
  for (size_t i = 0; i < v.size(); i++) {
    if (i > 0)
      ss << ", ";
    ss << v[i];
  }

  return ss.str();
}

template <typename T>
void CheckVectorContainsElements(const debug_ipc::FileLineFunction& location,
                                 const std::vector<T>& got, const std::vector<T>& expected) {
  ASSERT_EQ(expected.size(), got.size())
      << location.ToString() << ": "
      << "Expected (" << ToString(expected) << "), Got (" << ToString(got) << ").";

  for (size_t i = 0; i < expected.size(); i++) {
    ASSERT_TRUE(expected[i] == got[i])
        << location.ToString() << ": "
        << "Expected (" << ToString(expected) << "), Got (" << ToString(got) << ").";
  }
}

}  // namespace

TEST(ProcessBreakpoint, InstallAndFixup) {
  TestProcessDelegate process_delegate;

  Breakpoint main_breakpoint(&process_delegate);
  debug_ipc::BreakpointSettings settings;
  settings.type = debug_ipc::BreakpointType::kSoftware;
  main_breakpoint.SetSettings(settings);

  zx_koid_t process_koid = 0x1234;
  const std::string process_name = "process";
  MockProcess process(nullptr, process_koid, process_name);

  LoadOriginalMemory(process.mock_process_handle());

  SoftwareBreakpoint bp(&main_breakpoint, &process, kAddress);
  ASSERT_TRUE(bp.Init().ok());

  // Should have written the breakpoint instruction.
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress));

  // Make a memory block that contains the address set as the breakpoint. Offset it by kBlockOffset
  // to make sure non-aligned cases are handled.
  debug_ipc::MemoryBlock block;
  constexpr size_t kBlockOffset = 4;
  block.address = kAddress - kBlockOffset;
  block.valid = true;
  block.size = 16;
  block.data.resize(block.size);

  // Fill with memory contents reflecting the breakpoint instruction.
  auto with_bp = GetOriginalDataWithBreakpoint();
  memcpy(&block.data[kBlockOffset], with_bp.data(), with_bp.size());

  // FixupMemoryBlock should give back the original data.
  bp.FixupMemoryBlock(&block);
  EXPECT_TRUE(
      std::equal(&block.data[kBlockOffset], &block.data[kBlockOffset + kDataSize], kOriginalData));
}

TEST(ProcessBreakpoint, StepSingle) {
  TestProcessDelegate process_delegate;

  Breakpoint main_breakpoint(&process_delegate);
  debug_ipc::BreakpointSettings settings;
  settings.type = debug_ipc::BreakpointType::kSoftware;
  main_breakpoint.SetSettings(settings);

  constexpr zx_koid_t process_koid = 0x1234;
  const std::string process_name = "process";
  MockProcess process(nullptr, process_koid, process_name);

  process.mock_process_handle().mock_memory().AddMemory(kAddress, GetOriginalData());

  // The step over strategy is as follows:
  //  - Thread 1, 2, 3 will hit the breakpoint and attempt a step over.
  //  - Thread 4 will remain oblivious to the breakpoint, as will 5.
  //  - Thread 5 is suspended from the client, so it should not be resumed by the agent during
  //    step over.

  constexpr zx_koid_t kThread1Koid = 1;
  constexpr zx_koid_t kThread2Koid = 2;
  constexpr zx_koid_t kThread3Koid = 3;
  constexpr zx_koid_t kThread4Koid = 4;
  constexpr zx_koid_t kThread5Koid = 5;
  MockThread* mock_thread1 = process.AddThread(kThread1Koid);
  MockThread* mock_thread2 = process.AddThread(kThread2Koid);
  MockThread* mock_thread3 = process.AddThread(kThread3Koid);
  MockThread* mock_thread4 = process.AddThread(kThread4Koid);
  MockThread* mock_thread5 = process.AddThread(kThread5Koid);

  mock_thread5->ClientSuspend();

  SoftwareBreakpoint bp(&main_breakpoint, &process, kAddress);
  ASSERT_TRUE(bp.Init().ok());

  // The breakpoint should be installed.
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress));

  // Thread 1 hits breakpoint ----------------------------------------------------------------------

  bp.BeginStepOver(mock_thread1);

  // Breakpoint should be removed.
  EXPECT_TRUE(MemoryContainsOriginal(process.mock_process_handle(), kAddress));

  // There should be one enqueued step over.
  ASSERT_EQ(process.step_over_queue().size(), 1u);
  ASSERT_EQ(process.step_over_queue()[0].process_breakpoint.get(), &bp);
  ASSERT_EQ(process.step_over_queue()[0].thread.get(), mock_thread1);

  // Only thread 1 should be still running. The rest should be suspended.
  EXPECT_TRUE(mock_thread1->running());
  EXPECT_TRUE(mock_thread2->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread3->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread4->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // Only thread 1 should be stepping over.
  EXPECT_TRUE(mock_thread1->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread2->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  CheckVectorContainsElements(FROM_HERE, bp.CurrentlySuspendedThreads(),
                              {kThread2Koid, kThread3Koid, kThread4Koid, kThread5Koid});

  // Thread 2 hits breakpoint ----------------------------------------------------------------------

  // Now the second thread gets the exception.
  bp.BeginStepOver(mock_thread2);

  // There should be 2 enqueued step overs.
  ASSERT_EQ(process.step_over_queue().size(), 2u);
  ASSERT_EQ(process.step_over_queue()[1].process_breakpoint.get(), &bp);
  ASSERT_EQ(process.step_over_queue()[1].thread.get(), mock_thread2);

  // Only thread 1 should be running.
  EXPECT_TRUE(mock_thread1->running());
  EXPECT_TRUE(mock_thread2->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread3->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread4->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // Only thread 1 should be stepping over.
  EXPECT_TRUE(mock_thread1->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread2->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  CheckVectorContainsElements(FROM_HERE, bp.CurrentlySuspendedThreads(),
                              {kThread2Koid, kThread3Koid, kThread4Koid, kThread5Koid});

  // Thread 3 hits breakpoint ----------------------------------------------------------------------

  bp.BeginStepOver(mock_thread3);

  // There should be 2 enqueued step overs.
  ASSERT_EQ(process.step_over_queue().size(), 3u);
  ASSERT_EQ(process.step_over_queue()[2].process_breakpoint.get(), &bp);
  ASSERT_EQ(process.step_over_queue()[2].thread.get(), mock_thread3);

  // Only thread 1 should be running.
  EXPECT_TRUE(mock_thread1->running());
  EXPECT_TRUE(mock_thread2->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread3->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread4->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // Only thread 1 should be stepping over right now.
  EXPECT_TRUE(mock_thread1->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread2->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  CheckVectorContainsElements(FROM_HERE, bp.CurrentlySuspendedThreads(),
                              {kThread2Koid, kThread3Koid, kThread4Koid, kThread5Koid});

  // The memory should be original.
  EXPECT_TRUE(MemoryContainsOriginal(process.mock_process_handle(), kAddress));

  // Thread 1 steps over ---------------------------------------------------------------------------

  bp.EndStepOver(mock_thread1);

  // There should be 2 enqueued step overs.
  ASSERT_EQ(process.step_over_queue().size(), 2u);
  ASSERT_EQ(process.step_over_queue()[0].process_breakpoint.get(), &bp);
  ASSERT_EQ(process.step_over_queue()[0].thread.get(), mock_thread2);
  ASSERT_EQ(process.step_over_queue()[1].process_breakpoint.get(), &bp);
  ASSERT_EQ(process.step_over_queue()[1].thread.get(), mock_thread3);

  // Only thread 2 should be running.
  EXPECT_TRUE(mock_thread1->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread2->running());
  EXPECT_TRUE(mock_thread3->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread4->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // Only thread 2 should be stepping over right now.
  EXPECT_FALSE(mock_thread1->stepping_over_breakpoint());
  EXPECT_TRUE(mock_thread2->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  CheckVectorContainsElements(FROM_HERE, bp.CurrentlySuspendedThreads(),
                              {kThread1Koid, kThread3Koid, kThread4Koid, kThread5Koid});

  // The memory should be original.
  EXPECT_TRUE(MemoryContainsOriginal(process.mock_process_handle(), kAddress));

  // Thread 2 steps over ---------------------------------------------------------------------------

  bp.EndStepOver(mock_thread2);

  // There should be 1 enqueued step overs.
  ASSERT_EQ(process.step_over_queue().size(), 1u);
  ASSERT_EQ(process.step_over_queue()[0].process_breakpoint.get(), &bp);
  ASSERT_EQ(process.step_over_queue()[0].thread.get(), mock_thread3);

  // Only thread 3 should be running, as it's the only one stepping over.
  EXPECT_TRUE(mock_thread1->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread2->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread3->running());
  EXPECT_TRUE(mock_thread4->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // Only thread 3 should be stepping over right now.
  EXPECT_FALSE(mock_thread1->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread2->stepping_over_breakpoint());
  EXPECT_TRUE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  CheckVectorContainsElements(FROM_HERE, bp.CurrentlySuspendedThreads(),
                              {kThread1Koid, kThread2Koid, kThread4Koid, kThread5Koid});

  // Breakpoint remains removed.
  EXPECT_TRUE(MemoryContainsOriginal(process.mock_process_handle(), kAddress));

  // Thread 3 steps over ---------------------------------------------------------------------------

  bp.EndStepOver(mock_thread3);

  // No more enqueued elements.
  ASSERT_EQ(process.step_over_queue().size(), 0u);

  // All threads should be resumed except 5, which was paused by the client.
  EXPECT_TRUE(mock_thread1->running());
  EXPECT_TRUE(mock_thread2->running());
  EXPECT_TRUE(mock_thread3->running());
  EXPECT_TRUE(mock_thread4->running());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // No thread should be stepping over.
  EXPECT_FALSE(mock_thread1->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread2->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  EXPECT_TRUE(bp.CurrentlySuspendedThreads().empty());

  // Breakpoint is set again.
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress));
}

TEST(ProcessBreakpoint, MultipleBreakpoints) {
  TestProcessDelegate process_delegate1;
  TestProcessDelegate process_delegate2;
  TestProcessDelegate process_delegate3;

  Breakpoint main_breakpoint1(&process_delegate1);
  Breakpoint main_breakpoint2(&process_delegate2);
  Breakpoint main_breakpoint3(&process_delegate3);

  debug_ipc::BreakpointSettings settings;
  settings.type = debug_ipc::BreakpointType::kSoftware;
  main_breakpoint1.SetSettings(settings);
  main_breakpoint2.SetSettings(settings);
  main_breakpoint3.SetSettings(settings);

  constexpr zx_koid_t process_koid = 0x1234;
  const std::string process_name = "process";
  MockProcess process(nullptr, process_koid, process_name);

  constexpr uint64_t kAddress1 = kAddress;
  constexpr uint64_t kAddress2 = kAddress + 0x100;
  constexpr uint64_t kAddress3 = kAddress + 0x200;
  process.mock_process_handle().mock_memory().AddMemory(kAddress1, GetOriginalData());
  process.mock_process_handle().mock_memory().AddMemory(kAddress2, GetOriginalData());
  process.mock_process_handle().mock_memory().AddMemory(kAddress3, GetOriginalData());

  // The step over strategy is as follows:
  // 1. Thread 1 hits breakpoint 1.
  // 2. Thread 2 hits breakpoint 2.
  // 3. Thread 3 hits breakpoint 3.
  // 4. Thread 1 finishes step over.
  // 5. Thread 4 hits breakpoint 2 (somehow).
  // 6. Thread 2 finishes step over.
  // 7. Thread 3 finishes step over.
  // 8. Thread 4 finishes step over.

  constexpr zx_koid_t kThread1Koid = 1;
  constexpr zx_koid_t kThread2Koid = 2;
  constexpr zx_koid_t kThread3Koid = 3;
  constexpr zx_koid_t kThread4Koid = 4;
  constexpr zx_koid_t kThread5Koid = 5;
  MockThread* mock_thread1 = process.AddThread(kThread1Koid);
  MockThread* mock_thread2 = process.AddThread(kThread2Koid);
  MockThread* mock_thread3 = process.AddThread(kThread3Koid);
  MockThread* mock_thread4 = process.AddThread(kThread4Koid);
  MockThread* mock_thread5 = process.AddThread(kThread5Koid);

  SoftwareBreakpoint breakpoint1(&main_breakpoint1, &process, kAddress1);
  SoftwareBreakpoint breakpoint2(&main_breakpoint2, &process, kAddress2);
  SoftwareBreakpoint breakpoint3(&main_breakpoint3, &process, kAddress3);

  ASSERT_TRUE(breakpoint1.Init().ok());
  ASSERT_TRUE(breakpoint2.Init().ok());
  ASSERT_TRUE(breakpoint3.Init().ok());

  // The breakpoint should be installed at all locations.
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress1));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress2));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress3));

  // Thread 1 hits breakpoint 1 --------------------------------------------------------------------

  breakpoint1.BeginStepOver(mock_thread1);

  // There should be one enqueued step over.
  ASSERT_EQ(process.step_over_queue().size(), 1u);
  ASSERT_EQ(process.step_over_queue()[0].process_breakpoint.get(), &breakpoint1);
  ASSERT_EQ(process.step_over_queue()[0].thread.get(), mock_thread1);

  // Only thread 1 should be still running. The rest should be suspended.
  EXPECT_TRUE(mock_thread1->running());
  EXPECT_TRUE(mock_thread2->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread3->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread4->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // Only thread 1 should be stepping over.
  EXPECT_TRUE(mock_thread1->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread2->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  CheckVectorContainsElements(FROM_HERE, breakpoint1.CurrentlySuspendedThreads(),
                              {kThread2Koid, kThread3Koid, kThread4Koid, kThread5Koid});
  CheckVectorContainsElements(FROM_HERE, breakpoint2.CurrentlySuspendedThreads(), {});
  CheckVectorContainsElements(FROM_HERE, breakpoint3.CurrentlySuspendedThreads(), {});

  // Breakpoint should be removed. Others breakpoints should remain set.
  EXPECT_TRUE(MemoryContainsOriginal(process.mock_process_handle(), kAddress1));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress2));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress3));

  // Thread 2 hits breakpoint 2 --------------------------------------------------------------------

  // Now the second thread gets the exception.
  breakpoint2.BeginStepOver(mock_thread2);

  // There should be 2 enqueued step overs.
  ASSERT_EQ(process.step_over_queue().size(), 2u);
  ASSERT_EQ(process.step_over_queue()[0].process_breakpoint.get(), &breakpoint1);
  ASSERT_EQ(process.step_over_queue()[0].thread.get(), mock_thread1);
  ASSERT_EQ(process.step_over_queue()[1].process_breakpoint.get(), &breakpoint2);
  ASSERT_EQ(process.step_over_queue()[1].thread.get(), mock_thread2);

  // Only thread 1 should be running.
  EXPECT_TRUE(mock_thread1->running());
  EXPECT_TRUE(mock_thread2->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread3->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread4->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // Only thread 1 should be stepping over.
  EXPECT_TRUE(mock_thread1->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread2->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  CheckVectorContainsElements(FROM_HERE, breakpoint1.CurrentlySuspendedThreads(),
                              {kThread2Koid, kThread3Koid, kThread4Koid, kThread5Koid});
  CheckVectorContainsElements(FROM_HERE, breakpoint2.CurrentlySuspendedThreads(), {});
  CheckVectorContainsElements(FROM_HERE, breakpoint3.CurrentlySuspendedThreads(), {});

  // Breakpoint should be removed. Others breakpoints should remain set.
  EXPECT_TRUE(MemoryContainsOriginal(process.mock_process_handle(), kAddress1));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress2));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress3));

  // Thread 3 hits breakpoint ----------------------------------------------------------------------

  breakpoint3.BeginStepOver(mock_thread3);

  // There should be 2 enqueued step overs.
  ASSERT_EQ(process.step_over_queue().size(), 3u);
  ASSERT_EQ(process.step_over_queue()[0].process_breakpoint.get(), &breakpoint1);
  ASSERT_EQ(process.step_over_queue()[0].thread.get(), mock_thread1);
  ASSERT_EQ(process.step_over_queue()[1].process_breakpoint.get(), &breakpoint2);
  ASSERT_EQ(process.step_over_queue()[1].thread.get(), mock_thread2);
  ASSERT_EQ(process.step_over_queue()[2].process_breakpoint.get(), &breakpoint3);
  ASSERT_EQ(process.step_over_queue()[2].thread.get(), mock_thread3);

  // Only thread 1 should be running.
  EXPECT_TRUE(mock_thread1->running());
  EXPECT_TRUE(mock_thread2->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread3->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread4->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // Only thread 1 should be stepping over right now.
  EXPECT_TRUE(mock_thread1->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread2->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  CheckVectorContainsElements(FROM_HERE, breakpoint1.CurrentlySuspendedThreads(),
                              {kThread2Koid, kThread3Koid, kThread4Koid, kThread5Koid});
  CheckVectorContainsElements(FROM_HERE, breakpoint2.CurrentlySuspendedThreads(), {});
  CheckVectorContainsElements(FROM_HERE, breakpoint3.CurrentlySuspendedThreads(), {});

  // Breakpoint should be removed. Others breakpoints should remain set.
  EXPECT_TRUE(MemoryContainsOriginal(process.mock_process_handle(), kAddress1));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress2));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress3));

  // Thread 1 steps over ---------------------------------------------------------------------------

  breakpoint1.EndStepOver(mock_thread1);

  // There should be 2 enqueued step overs.
  ASSERT_EQ(process.step_over_queue().size(), 2u);
  ASSERT_EQ(process.step_over_queue()[0].process_breakpoint.get(), &breakpoint2);
  ASSERT_EQ(process.step_over_queue()[0].thread.get(), mock_thread2);
  ASSERT_EQ(process.step_over_queue()[1].process_breakpoint.get(), &breakpoint3);
  ASSERT_EQ(process.step_over_queue()[1].thread.get(), mock_thread3);

  // Only thread 2 should be running.
  EXPECT_TRUE(mock_thread1->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread2->running());
  EXPECT_TRUE(mock_thread3->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread4->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // Only thread 2 should be stepping over right now.
  EXPECT_FALSE(mock_thread1->stepping_over_breakpoint());
  EXPECT_TRUE(mock_thread2->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  CheckVectorContainsElements(FROM_HERE, breakpoint1.CurrentlySuspendedThreads(), {});
  CheckVectorContainsElements(FROM_HERE, breakpoint2.CurrentlySuspendedThreads(),
                              {kThread1Koid, kThread3Koid, kThread4Koid, kThread5Koid});
  CheckVectorContainsElements(FROM_HERE, breakpoint3.CurrentlySuspendedThreads(), {});

  // Breakpoint 2 should be the only one removed.
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress1));
  EXPECT_TRUE(MemoryContainsOriginal(process.mock_process_handle(), kAddress2));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress3));

  // Thread 4 hits breakpoint 2 --------------------------------------------------------------------

  breakpoint2.BeginStepOver(mock_thread4);

  // There should be 3 enqueued step overs.
  ASSERT_EQ(process.step_over_queue().size(), 3u);
  ASSERT_EQ(process.step_over_queue()[0].process_breakpoint.get(), &breakpoint2);
  ASSERT_EQ(process.step_over_queue()[0].thread.get(), mock_thread2);
  ASSERT_EQ(process.step_over_queue()[1].process_breakpoint.get(), &breakpoint3);
  ASSERT_EQ(process.step_over_queue()[1].thread.get(), mock_thread3);
  ASSERT_EQ(process.step_over_queue()[2].process_breakpoint.get(), &breakpoint2);
  ASSERT_EQ(process.step_over_queue()[2].thread.get(), mock_thread4);

  // Only thread 2 should be running.
  EXPECT_TRUE(mock_thread1->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread2->running());
  EXPECT_TRUE(mock_thread3->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread4->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // Only thread 2 should be stepping over right now.
  EXPECT_FALSE(mock_thread1->stepping_over_breakpoint());
  EXPECT_TRUE(mock_thread2->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  CheckVectorContainsElements(FROM_HERE, breakpoint1.CurrentlySuspendedThreads(), {});
  CheckVectorContainsElements(FROM_HERE, breakpoint2.CurrentlySuspendedThreads(),
                              {kThread1Koid, kThread3Koid, kThread4Koid, kThread5Koid});
  CheckVectorContainsElements(FROM_HERE, breakpoint3.CurrentlySuspendedThreads(), {});

  // Breakpoint 2 should be the only one removed.
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress1));
  EXPECT_TRUE(MemoryContainsOriginal(process.mock_process_handle(), kAddress2));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress3));

  // Thread 2 steps over ---------------------------------------------------------------------------

  breakpoint2.EndStepOver(mock_thread2);

  // There should be 2 enqueued step overs.
  ASSERT_EQ(process.step_over_queue().size(), 2u);
  ASSERT_EQ(process.step_over_queue()[0].process_breakpoint.get(), &breakpoint3);
  ASSERT_EQ(process.step_over_queue()[0].thread.get(), mock_thread3);
  ASSERT_EQ(process.step_over_queue()[1].process_breakpoint.get(), &breakpoint2);
  ASSERT_EQ(process.step_over_queue()[1].thread.get(), mock_thread4);

  // Only thread 3 should be running, as it's the only one stepping over.
  EXPECT_TRUE(mock_thread1->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread2->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread3->running());
  EXPECT_TRUE(mock_thread4->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // Only thread 3 should be stepping over right now.
  EXPECT_FALSE(mock_thread1->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread2->stepping_over_breakpoint());
  EXPECT_TRUE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  CheckVectorContainsElements(FROM_HERE, breakpoint1.CurrentlySuspendedThreads(), {});
  CheckVectorContainsElements(FROM_HERE, breakpoint2.CurrentlySuspendedThreads(), {});
  CheckVectorContainsElements(FROM_HERE, breakpoint3.CurrentlySuspendedThreads(),
                              {kThread1Koid, kThread2Koid, kThread4Koid, kThread5Koid});
  // Breakpoint 3 should be the only one removed.
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress1));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress2));
  EXPECT_TRUE(MemoryContainsOriginal(process.mock_process_handle(), kAddress3));

  // Thread 3 steps over ---------------------------------------------------------------------------

  breakpoint3.EndStepOver(mock_thread3);

  // No more enqueued elements.
  ASSERT_EQ(process.step_over_queue().size(), 1u);
  ASSERT_EQ(process.step_over_queue()[0].process_breakpoint.get(), &breakpoint2);
  ASSERT_EQ(process.step_over_queue()[0].thread.get(), mock_thread4);

  // Only thread 4 should be running, as it's the only one stepping over.
  EXPECT_TRUE(mock_thread1->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread2->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread3->mock_thread_handle().is_suspended());
  EXPECT_TRUE(mock_thread4->running());
  EXPECT_TRUE(mock_thread5->mock_thread_handle().is_suspended());

  // Only thread 3 should be stepping over right now.
  EXPECT_FALSE(mock_thread1->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread2->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread3->stepping_over_breakpoint());
  EXPECT_TRUE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  CheckVectorContainsElements(FROM_HERE, breakpoint1.CurrentlySuspendedThreads(), {});
  CheckVectorContainsElements(FROM_HERE, breakpoint2.CurrentlySuspendedThreads(),
                              {kThread1Koid, kThread2Koid, kThread3Koid, kThread5Koid});
  CheckVectorContainsElements(FROM_HERE, breakpoint3.CurrentlySuspendedThreads(), {});

  // Breakpoint 2 should be the only one removed.
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress1));
  EXPECT_TRUE(MemoryContainsOriginal(process.mock_process_handle(), kAddress2));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress3));

  // Thread 4 steps over ---------------------------------------------------------------------------

  breakpoint2.EndStepOver(mock_thread4);

  // All threads should be resumed.
  EXPECT_TRUE(mock_thread1->running());
  EXPECT_TRUE(mock_thread2->running());
  EXPECT_TRUE(mock_thread3->running());
  EXPECT_TRUE(mock_thread4->running());
  EXPECT_TRUE(mock_thread5->running());

  // No thread should be stepping over.
  EXPECT_FALSE(mock_thread1->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread2->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread3->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread4->stepping_over_breakpoint());
  EXPECT_FALSE(mock_thread5->stepping_over_breakpoint());

  EXPECT_TRUE(breakpoint1.CurrentlySuspendedThreads().empty());
  EXPECT_TRUE(breakpoint2.CurrentlySuspendedThreads().empty());
  EXPECT_TRUE(breakpoint3.CurrentlySuspendedThreads().empty());

  // All breakpoints are set again.
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress1));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress2));
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress3));
}

// It's possible for a thread to try to step over the same breakpoint twice. This normally indicates
// an error removing the breakpoint to step over it. We must not enqueue the same thread twice in
// this error case or it will be forever stuck waiting for itself.
TEST(ProcessBreakpoint, RecursiveStep) {
  TestProcessDelegate process_delegate;

  Breakpoint main_breakpoint(&process_delegate);
  debug_ipc::BreakpointSettings settings;
  settings.type = debug_ipc::BreakpointType::kSoftware;
  main_breakpoint.SetSettings(settings);

  constexpr zx_koid_t process_koid = 0x1234;
  const std::string process_name = "process";
  MockProcess process(nullptr, process_koid, process_name);

  process.mock_process_handle().mock_memory().AddMemory(kAddress, GetOriginalData());

  constexpr zx_koid_t kThreadKoid = 1;
  MockThread* mock_thread = process.AddThread(kThreadKoid);

  SoftwareBreakpoint bp(&main_breakpoint, &process, kAddress);
  ASSERT_TRUE(bp.Init().ok());

  // The breakpoint should be installed.
  EXPECT_TRUE(MemoryContainsBreak(process.mock_process_handle(), kAddress));

  // Hit the breakpoint the first time.
  bp.BeginStepOver(mock_thread);

  // There should be one enqueued step over.
  ASSERT_EQ(process.step_over_queue().size(), 1u);
  ASSERT_EQ(process.step_over_queue()[0].process_breakpoint.get(), &bp);
  ASSERT_EQ(process.step_over_queue()[0].thread.get(), mock_thread);

  // Recursively hits the same breakpoint.
  bp.BeginStepOver(mock_thread);

  // There should still just be one enqueued step over.
  ASSERT_EQ(process.step_over_queue().size(), 1u);
  ASSERT_EQ(process.step_over_queue()[0].process_breakpoint.get(), &bp);
  ASSERT_EQ(process.step_over_queue()[0].thread.get(), mock_thread);
}

// This also tests registration and unregistration of ProcessBreakpoints via the Breakpoint object.
TEST(ProcessBreakpoint, HitCount) {
  // This test requires a debug agent because it causes a breakpoint hit which will try to suspend
  // all processes attached.
  DebugAgent debug_agent(std::make_unique<MockSystemInterface>(MockJobHandle(99999)));
  TestProcessDelegate process_delegate;

  constexpr zx_koid_t kProcess1 = 1;
  auto owning_process = std::make_unique<MockProcess>(&debug_agent, kProcess1);
  DebuggedProcess* process = owning_process.get();
  owning_process->mock_process_handle().mock_memory().AddMemory(kAddress, GetOriginalData());
  process_delegate.InjectMockProcess(std::move(owning_process));

  auto owning_thread = std::make_unique<MockThread>(process, 28374);
  MockThread* thread = owning_thread.get();
  process->InjectThreadForTest(std::move(owning_thread));

  constexpr uint32_t kBreakpointId1 = 12;
  debug_ipc::BreakpointSettings settings;
  settings.id = kBreakpointId1;
  settings.type = debug_ipc::BreakpointType::kSoftware;
  settings.locations.resize(1);

  debug_ipc::ProcessBreakpointSettings& pr_settings = settings.locations.back();
  pr_settings.id = {.process = kProcess1, .thread = 0};
  pr_settings.address = kAddress;

  // Create a ProcessBreakpoint referencing the two Breakpoint objects
  // (corresponds to two logical breakpoints at the same address).
  std::unique_ptr<Breakpoint> main_breakpoint1 = std::make_unique<Breakpoint>(&process_delegate);
  auto status = main_breakpoint1->SetSettings(settings);
  ASSERT_TRUE(status.ok());

  std::unique_ptr<Breakpoint> main_breakpoint2 = std::make_unique<Breakpoint>(&process_delegate);
  constexpr uint32_t kBreakpointId2 = 13;
  settings.id = kBreakpointId2;
  status = main_breakpoint2->SetSettings(settings);
  ASSERT_TRUE(status.ok());

  // There should only be one address with a breakpoint.
  ASSERT_EQ(1u, process_delegate.bps().size());
  EXPECT_EQ(kAddress, process_delegate.bps().begin()->first);

  // Hitting the ProcessBreakpoint should update both Breakpoints.
  std::vector<debug_ipc::BreakpointStats> stats;
  std::vector<debug_ipc::ThreadRecord> affected_threads;
  process_delegate.bps().begin()->second->OnHit(thread, debug_ipc::BreakpointType::kSoftware, stats,
                                                affected_threads);
  ASSERT_EQ(2u, stats.size());

  // Order of the vector is not defined so allow either.
  EXPECT_TRUE((stats[0].id == kBreakpointId1 && stats[1].id == kBreakpointId2) ||
              (stats[0].id == kBreakpointId2 && stats[1].id == kBreakpointId1));

  // The hit count of both should be 1 (order doesn't matter).
  EXPECT_EQ(1u, stats[0].hit_count);
  EXPECT_EQ(1u, stats[1].hit_count);

  // Unregistering one Breakpoint should keep the ProcessBreakpoint.
  main_breakpoint2.reset();
  ASSERT_EQ(1u, process_delegate.bps().size());

  // Unregistering the other should delete it.
  main_breakpoint1.reset();
  ASSERT_EQ(0u, process_delegate.bps().size());
}

}  // namespace debug_agent
