// 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 "interception_workflow.h"

#include <thread>
#undef __TA_REQUIRES
#include <zircon/fidl.h>

#include "gtest/gtest.h"
#include "src/developer/debug/ipc/protocol.h"
#include "src/developer/debug/zxdb/client/mock_remote_api.h"
#include "src/developer/debug/zxdb/client/remote_api_test.h"
#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/symbols/mock_module_symbols.h"

namespace fidlcat {

// This class encapsulates the data needed for the zx_channel tests.
// TODO: This is obviously not extensible to more than one test.
class DataForZxChannelTest {
 public:
  DataForZxChannelTest(debug_ipc::Arch arch) : arch_(arch) {
    header_.txid = kTxId;
    header_.reserved0 = kReserved;
    header_.flags = kFlags;
    header_.ordinal = kOrdinal;

    // Fill out the stack with the expected values for zx_channel_read (which
    // will be ignored / irrelevant for zx_channel_write).
    memset(stack_, 0, sizeof(stack_));
    uint64_t* stack_ptr = reinterpret_cast<uint64_t*>(stack_);
    stack_ptr[1] = kActualBytesPtr;
    stack_ptr[2] = kActualHandlesPtr;

    current_stack_ptr_ = kStackPointer;
    current_symbol_address_ = 0x0;
  }

  const uint8_t* data() const {
    return reinterpret_cast<const uint8_t*>(&header_);
  }

  size_t num_bytes() const { return sizeof(header_); }

  const zx_handle_t* handles() const { return handles_; }

  size_t num_handles() const { return sizeof(handles_) / sizeof(handles_[0]); }

  uint64_t current_stack_ptr() { return current_stack_ptr_; }

  void SetCurrentAddress(uint64_t address) {
    current_symbol_address_ = address;
  }

  fxl::RefPtr<zxdb::SystemSymbols::ModuleRef> GetModuleRef(
      zxdb::Session* session) {
    // Create a module with zx_channel_write and zx_channel_read
    std::unique_ptr<zxdb::MockModuleSymbols> module =
        std::make_unique<zxdb::MockModuleSymbols>("zx.so");
    module->AddSymbolLocations(
        zx_channel_write_name_,
        {zxdb::Location(zxdb::Location::State::kSymbolized,
                        kWriteElfSymbolAddress)});
    module->AddSymbolLocations(
        zx_channel_read_name_,
        {zxdb::Location(zxdb::Location::State::kSymbolized,
                        kReadElfSymbolAddress)});

    return session->system().GetSymbols()->InjectModuleForTesting(
        kElfSymbolBuildID, std::move(module));
  }

  void PopulateModules(std::vector<debug_ipc::Module>& modules) {
    const uint64_t kModuleBase = 0x1000000;
    debug_ipc::Module load;
    load.name = "test";
    load.base = kModuleBase;
    load.build_id = kElfSymbolBuildID;
    modules.push_back(load);
  }

  void PopulateMemoryBlockForAddress(uint64_t address, uint64_t size,
                                     debug_ipc::MemoryBlock& block) {
    block.address = address;
    block.size = size;
    block.valid = true;
    switch (address) {
      case kBytesAddress: {
        const uint8_t* bytes = data();
        std::copy(bytes, bytes + num_bytes(), std::back_inserter(block.data));
        break;
      }
      case kHandlesAddress: {
        const zx_handle_t* h = handles();
        std::copy(reinterpret_cast<const uint8_t*>(h),
                  reinterpret_cast<const uint8_t*>(h + num_handles()),
                  std::back_inserter(block.data));
        break;
      }
      case kStackPointer: {
        // Should only be requested for zx_channel_read.  Having this
        // available for zx_channel_write should not affect behavior, though.
        std::copy(stack_, stack_ + sizeof(stack_),
                  std::back_inserter(block.data));
        break;
      }
      case kActualBytesPtr: {
        uint32_t byte_count = num_bytes();
        uint8_t* num_bytes_ptr = reinterpret_cast<uint8_t*>(&byte_count);
        std::copy(num_bytes_ptr, num_bytes_ptr + sizeof(byte_count),
                  std::back_inserter(block.data));
        break;
      }
      case kActualHandlesPtr: {
        uint32_t handle_count = num_handles();
        uint8_t* num_handles_ptr = reinterpret_cast<uint8_t*>(&handle_count);
        std::copy(num_handles_ptr, num_handles_ptr + sizeof(handle_count),
                  std::back_inserter(block.data));
        break;
      }
      default:
        FXL_NOTREACHED() << "Unknown memory address requested.";
    }
    FXL_DCHECK(size == block.data.size())
        << "expected size: " << size
        << " and actual size: " << block.data.size();
  }

  void PopulateRegisters(debug_ipc::RegisterCategory& category) {
    category.type = debug_ipc::RegisterCategory::Type::kGeneral;
    // Assumes Little Endian
    const uint8_t* address_as_bytes =
        reinterpret_cast<const uint8_t*>(&kBytesAddress);

    const uint8_t* handles_address_as_bytes =
        reinterpret_cast<const uint8_t*>(&kHandlesAddress);

    const uint8_t* stack_pointer_as_bytes =
        reinterpret_cast<const uint8_t*>(&current_stack_ptr_);

    const uint8_t* actual_bytes_ptr_as_bytes =
        reinterpret_cast<const uint8_t*>(&kActualBytesPtr);

    const uint8_t* actual_handles_ptr_as_bytes =
        reinterpret_cast<const uint8_t*>(&kActualHandlesPtr);

    std::map<debug_ipc::RegisterID, std::vector<uint8_t>> values;
    if (current_symbol_address_ == kWriteElfSymbolAddress) {
      if (arch_ == debug_ipc::Arch::kArm64) {
        values = {
            // zx_handle_t handle
            {debug_ipc::RegisterID::kARMv8_x0, {0xb0, 0x1d, 0xfa, 0xce}},
            // uint32_t options
            {debug_ipc::RegisterID::kARMv8_x1, {0x00, 0x00, 0x00, 0x00}},
            // bytes_address
            {debug_ipc::RegisterID::kARMv8_x2,
             std::vector<uint8_t>(address_as_bytes,
                                  address_as_bytes + num_bytes())},
            // num_bytes
            {debug_ipc::RegisterID::kARMv8_x3,
             {static_cast<unsigned char>(num_bytes()), 0x00, 0x00, 0x00}},
            // handles_address
            {debug_ipc::RegisterID::kARMv8_x4,
             std::vector<uint8_t>(handles_address_as_bytes,
                                  handles_address_as_bytes +
                                      (sizeof(zx_handle_t) * num_handles()))},
            // num_handles
            {debug_ipc::RegisterID::kARMv8_x5,
             {static_cast<unsigned char>(num_handles()), 0x00, 0x00, 0x00}},
            // stack pointer
            {debug_ipc::RegisterID::kARMv8_sp,
             std::vector<uint8_t>(
                 stack_pointer_as_bytes,
                 stack_pointer_as_bytes + sizeof(current_stack_ptr_))}};
      } else if (arch_ == debug_ipc::Arch::kX64) {
        values = {
            // zx_handle_t handle
            {debug_ipc::RegisterID::kX64_rdi, {0xb0, 0x1d, 0xfa, 0xce}},
            // uint32_t options
            {debug_ipc::RegisterID::kX64_rsi, {0x00, 0x00, 0x00, 0x00}},
            // bytes_address
            {debug_ipc::RegisterID::kX64_rdx,
             std::vector<uint8_t>(address_as_bytes,
                                  address_as_bytes + num_bytes())},
            // num_bytes
            {debug_ipc::RegisterID::kX64_rcx,
             {static_cast<unsigned char>(num_bytes()), 0x00, 0x00, 0x00}},
            // handles_address
            {debug_ipc::RegisterID::kX64_r8,
             std::vector<uint8_t>(handles_address_as_bytes,
                                  handles_address_as_bytes +
                                      (sizeof(zx_handle_t) * num_handles()))},
            // num_handles
            {debug_ipc::RegisterID::kX64_r9,
             {static_cast<unsigned char>(num_handles()), 0x00, 0x00, 0x00}},
            // stack pointer
            {debug_ipc::RegisterID::kX64_rsp,
             std::vector<uint8_t>(
                 stack_pointer_as_bytes,
                 stack_pointer_as_bytes + sizeof(current_stack_ptr_))}};
      }
    } else if (current_symbol_address_ == kReadElfSymbolAddress) {
      if (arch_ == debug_ipc::Arch::kArm64) {
        values = {
            // zx_handle_t handle
            {debug_ipc::RegisterID::kARMv8_x0, {0xb0, 0x1d, 0xfa, 0xce}},
            // uint32_t options
            {debug_ipc::RegisterID::kARMv8_x1, {0x00, 0x00, 0x00, 0x00}},
            // bytes_address
            {debug_ipc::RegisterID::kARMv8_x2,
             std::vector<uint8_t>(address_as_bytes,
                                  address_as_bytes + num_bytes())},
            // handles_address
            {debug_ipc::RegisterID::kARMv8_x3,
             std::vector<uint8_t>(handles_address_as_bytes,
                                  handles_address_as_bytes +
                                      (sizeof(zx_handle_t) * num_handles()))},
            // num_bytes
            {debug_ipc::RegisterID::kARMv8_x4,
             {static_cast<unsigned char>(num_bytes()), 0x00, 0x00, 0x00}},
            // num_handles
            {debug_ipc::RegisterID::kARMv8_x5,
             {static_cast<unsigned char>(num_handles()), 0x00, 0x00, 0x00}},
            {debug_ipc::RegisterID::kARMv8_x6,
             std::vector<uint8_t>(
                 actual_bytes_ptr_as_bytes,
                 actual_bytes_ptr_as_bytes + sizeof(kActualBytesPtr))},
            {debug_ipc::RegisterID::kARMv8_x7,
             std::vector<uint8_t>(
                 actual_handles_ptr_as_bytes,
                 actual_handles_ptr_as_bytes + sizeof(kActualHandlesPtr))},
            // stack pointer
            {debug_ipc::RegisterID::kARMv8_sp,
             std::vector<uint8_t>(
                 stack_pointer_as_bytes,
                 stack_pointer_as_bytes + sizeof(current_stack_ptr_))}};
      } else if (arch_ == debug_ipc::Arch::kX64) {
        values = {
            // zx_handle_t handle
            {debug_ipc::RegisterID::kX64_rdi, {0xb0, 0x1d, 0xfa, 0xce}},
            // uint32_t options
            {debug_ipc::RegisterID::kX64_rsi, {0x00, 0x00, 0x00, 0x00}},
            // bytes_address
            {debug_ipc::RegisterID::kX64_rdx,
             std::vector<uint8_t>(address_as_bytes,
                                  address_as_bytes + num_bytes())},
            // handles_address
            {debug_ipc::RegisterID::kX64_rcx,
             std::vector<uint8_t>(handles_address_as_bytes,
                                  handles_address_as_bytes +
                                      (sizeof(zx_handle_t) * num_handles()))},
            // num_bytes
            {debug_ipc::RegisterID::kX64_r8,
             {static_cast<unsigned char>(num_bytes()), 0x00, 0x00, 0x00}},
            // num_handles
            {debug_ipc::RegisterID::kX64_r9,
             {static_cast<unsigned char>(num_handles()), 0x00, 0x00, 0x00}},
            // stack pointer
            {debug_ipc::RegisterID::kX64_rsp,
             std::vector<uint8_t>(
                 stack_pointer_as_bytes,
                 stack_pointer_as_bytes + sizeof(current_stack_ptr_))}};
      }
    } else {
      FXL_NOTREACHED() << "do not know what the registers should be at this IP";
    }

    std::vector<debug_ipc::Register>& registers = category.registers;
    for (auto value : values) {
      debug_ipc::Register& reg = registers.emplace_back();
      reg.id = value.first;
      reg.data = value.second;
    }
  }

  void Step() {
    // Increment the stack pointer to make it look as if we've stepped out of
    // the zx_channel function.
    current_stack_ptr_ += 16;
  }

  static constexpr uint64_t kWriteElfSymbolAddress = 0x100060;
  static constexpr uint64_t kReadElfSymbolAddress = 0x1000b0;
  static constexpr uint64_t kStackPointer = 0x57accadde5500;

 private:
  static const zx_txid_t kTxId = 0xaaaaaaaa;
  static const uint32_t kReserved = 0x0;
  static const uint32_t kFlags = 0x0;
  static const uint32_t kOrdinal = 2011483371;
  static constexpr char kElfSymbolBuildID[] = "123412341234";
  static constexpr uint64_t kBytesAddress = 0x7e57ab1eba5eba11;
  static constexpr uint64_t kHandlesAddress = 0xca11ab1e7e57;
  static constexpr uint64_t kActualBytesPtr = 0x2000;
  static constexpr uint64_t kActualHandlesPtr = 0x3000;
  static const char* zx_channel_write_name_;
  static const char* zx_channel_read_name_;

  uint64_t current_stack_ptr_;
  uint64_t current_symbol_address_;
  fidl_message_header_t header_;
  zx_handle_t handles_[2] = {0x01234567, 0x89abcdef};
  uint8_t stack_[3 * sizeof(uint64_t)];
  debug_ipc::Arch arch_;
};

const char* DataForZxChannelTest::zx_channel_write_name_ =
    InterceptionWorkflow::kZxChannelWriteName;
const char* DataForZxChannelTest::zx_channel_read_name_ =
    InterceptionWorkflow::kZxChannelReadName;

struct BreakpointCmp {
  bool operator()(const debug_ipc::BreakpointSettings& lhs,
                  const debug_ipc::BreakpointSettings& rhs) const {
    return lhs.id < rhs.id;
  }
};

// Provides the infrastructure needed to provide the data above.
class InterceptionRemoteAPI : public zxdb::MockRemoteAPI {
 public:
  explicit InterceptionRemoteAPI(DataForZxChannelTest& data) : data_(data) {}

  void AddOrChangeBreakpoint(
      const debug_ipc::AddOrChangeBreakpointRequest& request,
      std::function<void(const zxdb::Err&,
                         debug_ipc::AddOrChangeBreakpointReply)>
          cb) override {
    breakpoints_.insert(request.breakpoint);
    MockRemoteAPI::AddOrChangeBreakpoint(request, cb);
  }

  void Attach(const debug_ipc::AttachRequest& request,
              std::function<void(const zxdb::Err&, debug_ipc::AttachReply)> cb)
      override {
    debug_ipc::MessageLoop::Current()->PostTask(
        FROM_HERE, [cb]() { cb(zxdb::Err(), debug_ipc::AttachReply()); });
  }

  void Modules(const debug_ipc::ModulesRequest& request,
               std::function<void(const zxdb::Err&, debug_ipc::ModulesReply)>
                   cb) override {
    debug_ipc::ModulesReply reply;
    data_.PopulateModules(reply.modules);
    debug_ipc::MessageLoop::Current()->PostTask(
        FROM_HERE, [cb, reply]() { cb(zxdb::Err(), reply); });
  }

  void ReadMemory(
      const debug_ipc::ReadMemoryRequest& request,
      std::function<void(const zxdb::Err&, debug_ipc::ReadMemoryReply)> cb)
      override {
    debug_ipc::ReadMemoryReply reply;
    data_.PopulateMemoryBlockForAddress(request.address, request.size,
                                        reply.blocks.emplace_back());
    debug_ipc::MessageLoop::Current()->PostTask(
        FROM_HERE, [cb, reply]() { cb(zxdb::Err(), reply); });
  }

  void ReadRegisters(
      const debug_ipc::ReadRegistersRequest& request,
      std::function<void(const zxdb::Err&, debug_ipc::ReadRegistersReply)> cb)
      override {
    // TODO: Parameterize this so we can have more than one test.
    debug_ipc::ReadRegistersReply reply;
    data_.PopulateRegisters(reply.categories.emplace_back());
    debug_ipc::MessageLoop::Current()->PostTask(
        FROM_HERE, [cb, reply]() { cb(zxdb::Err(), reply); });
  }

  void Resume(const debug_ipc::ResumeRequest& request,
              std::function<void(const zxdb::Err&, debug_ipc::ResumeReply)> cb)
      override {
    debug_ipc::ResumeReply reply;
    if (data_.current_stack_ptr() == DataForZxChannelTest::kStackPointer) {
      // This means we need to step out of the zx_channel_read function.
      data_.Step();
    }
    debug_ipc::MessageLoop::Current()->PostTask(FROM_HERE, [cb, reply]() {
      cb(zxdb::Err(), reply);
      // This is so that the test can inject the next exception.
      debug_ipc::MessageLoop::Current()->QuitNow();
    });
  }

  const std::set<debug_ipc::BreakpointSettings, BreakpointCmp>& breakpoints()
      const {
    return breakpoints_;
  }

  void PopulateBreakpointIds(uint64_t address,
                             debug_ipc::NotifyException& notification) {
    for (auto& breakpoint : breakpoints_) {
      if (address == breakpoint.locations[0].address) {
        notification.hit_breakpoints.emplace_back();
        notification.hit_breakpoints.back().id = breakpoint.id;
        data_.SetCurrentAddress(address);
      }
    }
  }

 private:
  std::set<debug_ipc::BreakpointSettings, BreakpointCmp> breakpoints_;
  DataForZxChannelTest& data_;
};

class InterceptionWorkflowTest : public zxdb::RemoteAPITest {
 public:
  explicit InterceptionWorkflowTest(debug_ipc::Arch arch) : data_(arch) {}
  ~InterceptionWorkflowTest() override = default;

  InterceptionRemoteAPI& mock_remote_api() { return *mock_remote_api_; }

  std::unique_ptr<zxdb::RemoteAPI> GetRemoteAPIImpl() override {
    auto remote_api = std::make_unique<InterceptionRemoteAPI>(data_);
    mock_remote_api_ = remote_api.get();
    return std::move(remote_api);
  }

  DataForZxChannelTest& data() { return data_; }

  void WriteTest();

  void ReadTest();

 protected:
  DataForZxChannelTest data_;

 private:
  InterceptionRemoteAPI* mock_remote_api_;  // Owned by the session.
};

class InterceptionWorkflowTestX64 : public InterceptionWorkflowTest {
 public:
  InterceptionWorkflowTestX64() : InterceptionWorkflowTest(GetArch()) {}
  ~InterceptionWorkflowTestX64() override = default;

  virtual debug_ipc::Arch GetArch() const override {
    return debug_ipc::Arch::kX64;
  }
};

class InterceptionWorkflowTestArm : public InterceptionWorkflowTest {
 public:
  InterceptionWorkflowTestArm() : InterceptionWorkflowTest(GetArch()) {}
  ~InterceptionWorkflowTestArm() override = default;

  virtual debug_ipc::Arch GetArch() const override {
    return debug_ipc::Arch::kArm64;
  }
};

// This does process setup for the test.  It creates a fake process, injects
// modules with the appropriate symbols, attaches to the process, etc.
class ProcessController {
 public:
  ProcessController(InterceptionWorkflowTest* remote_api,
                    zxdb::Session& session,
                    debug_ipc::PlatformMessageLoop& loop);
  ~ProcessController();

  void Detach();

  InterceptionWorkflow& workflow() { return workflow_; }

  static constexpr uint64_t kProcessKoid = 1234;
  static constexpr uint64_t kThreadKoid = 5678;

 private:
  InterceptionWorkflow workflow_;

  zxdb::Process* process_;
  zxdb::Target* target_;
};

namespace {

template <typename T>
void AppendElements(std::string& result, size_t num, const T* a, const T* b) {
  std::ostringstream os;
  os << "actual      expected\n";
  for (size_t i = 0; i < num; i++) {
    os << std::left << std::setw(11) << a[i];
    os << " ";
    os << std::left << std::setw(11) << b[i];
    os << std::endl;
  }
  result.append(os.str());
}

class AlwaysQuit {
 public:
  AlwaysQuit(ProcessController* controller) : controller_(controller) {}
  ~AlwaysQuit() { controller_->Detach(); }

 private:
  ProcessController* controller_;
};

}  // namespace

ProcessController::ProcessController(InterceptionWorkflowTest* remote_api,
                                     zxdb::Session& session,
                                     debug_ipc::PlatformMessageLoop& loop)
    : workflow_(&session, &loop) {
  zxdb::Err err;
  std::vector<std::string> blank;
  workflow_.Initialize(blank);

  // Create a fake process and thread.
  process_ = remote_api->InjectProcess(kProcessKoid);
  zxdb::Thread* the_thread =
      remote_api->InjectThread(kProcessKoid, kThreadKoid);

  // Observe thread.  This is usually done in workflow_::Attach, but
  // RemoteAPITest has its own ideas about attaching, so that method only
  // half-works (the half that registers the target with the workflow). We have
  // to register the observer manually.
  target_ = session.system().GetTargets()[0];
  workflow_.AddObserver(target_);
  workflow_.observer_.DidCreateProcess(target_, process_, false);
  workflow_.observer_.process_observer().DidCreateThread(process_, the_thread);

  // Attach to process.
  debug_ipc::MessageLoop::Current()->PostTask(FROM_HERE, [this]() {
    workflow_.Attach(kProcessKoid, [](const zxdb::Err& err) {
      // Because we are already attached, we don't get here.
      FAIL() << "Should not be reached";
    });
    debug_ipc::MessageLoop::Current()->QuitNow();
  });
  debug_ipc::MessageLoop::Current()->Run();

  // Load modules into program (including the one with the zx_channel_write
  // and zx_channel_read symbols)
  fxl::RefPtr<zxdb::SystemSymbols::ModuleRef> module_ref =
      remote_api->data().GetModuleRef(&session);

  for (zxdb::Target* target : session.system().GetTargets()) {
    zxdb::Err err;
    std::vector<debug_ipc::Module> modules;
    // Force system to load modules.  Callback doesn't need to do anything
    // interesting.
    target->GetProcess()->GetModules(
        [](const zxdb::Err&, std::vector<debug_ipc::Module>) {
          debug_ipc::MessageLoop::Current()->QuitNow();
        });
    debug_ipc::MessageLoop::Current()->Run();
  }
}

ProcessController::~ProcessController() {
  process_->RemoveObserver(&workflow_.observer_.process_observer());
  target_->RemoveObserver(&workflow_.observer_);
}

void ProcessController::Detach() { workflow_.Detach(); }

void InterceptionWorkflowTest::WriteTest() {
  ProcessController controller(this, session(), loop());
  bool hit_breakpoint = false;
  // This will be executed when the zx_channel_write breakpoint is triggered.
  controller.workflow().SetZxChannelWriteCallback(
      [this, &controller, &hit_breakpoint](const zxdb::Err& err,
                                           const ZxChannelParams& params) {
        AlwaysQuit aq(&controller);
        hit_breakpoint = true;
        ASSERT_EQ(zxdb::ErrType::kNone, err.type()) << err.msg();

        std::string result;

        const uint8_t* data = data_.data();
        uint32_t num_bytes = params.GetNumBytes();
        ASSERT_EQ(num_bytes, data_.num_bytes());
        if (memcmp(params.GetBytes().get(), data, num_bytes) != 0) {
          result.append("bytes not equivalent");
          AppendElements<uint8_t>(result, num_bytes, params.GetBytes().get(),
                                  data);
          FAIL() << result;
        }

        const zx_handle_t* handles = data_.handles();
        uint32_t num_handles = params.GetNumHandles();
        ASSERT_EQ(num_handles, data_.num_handles());
        if (memcmp(params.GetHandles().get(), handles,
                   num_handles * sizeof(zx_handle_t)) != 0) {
          result.append("handles not equivalent\n");
          AppendElements<zx_handle_t>(result, num_handles,
                                      params.GetHandles().get(), handles);
          FAIL() << result;
        }
      });

  // Trigger breakpoint.
  debug_ipc::NotifyException notification;
  notification.type = debug_ipc::NotifyException::Type::kGeneral;
  notification.thread.process_koid = ProcessController::kProcessKoid;
  notification.thread.thread_koid = ProcessController::kThreadKoid;
  notification.thread.state = debug_ipc::ThreadRecord::State::kBlocked;
  mock_remote_api().PopulateBreakpointIds(
      DataForZxChannelTest::kWriteElfSymbolAddress, notification);
  InjectException(notification);

  debug_ipc::MessageLoop::Current()->Run();

  // At this point, the ZxChannelWrite callback should have been executed.
  ASSERT_TRUE(hit_breakpoint);

  // Making sure shutdown works.
  debug_ipc::MessageLoop::Current()->Run();
}

TEST_F(InterceptionWorkflowTestX64, ZxChannelWrite) { WriteTest(); }

TEST_F(InterceptionWorkflowTestArm, ZxChannelWrite) { WriteTest(); }

void InterceptionWorkflowTest::ReadTest() {
  ProcessController controller(this, session(), loop());
  bool hit_breakpoint = false;
  // This will be executed when the zx_channel_write breakpoint is triggered.
  controller.workflow().SetZxChannelReadCallback(
      [this, &controller, &hit_breakpoint](const zxdb::Err& err,
                                           const ZxChannelParams& params) {
        AlwaysQuit aq(&controller);
        hit_breakpoint = true;
        ASSERT_EQ(zxdb::ErrType::kNone, err.type()) << err.msg();

        std::string result;

        const uint8_t* data = data_.data();
        uint32_t num_bytes = params.GetNumBytes();
        ASSERT_EQ(num_bytes, data_.num_bytes());
        if (memcmp(params.GetBytes().get(), data, num_bytes) != 0) {
          result.append("bytes not equivalent");
          AppendElements<uint8_t>(result, num_bytes, params.GetBytes().get(),
                                  data);
          FAIL() << result;
        }

        const zx_handle_t* handles = data_.handles();
        uint32_t num_handles = params.GetNumHandles();
        ASSERT_EQ(num_handles, data_.num_handles());
        if (memcmp(params.GetHandles().get(), handles,
                   num_handles * sizeof(zx_handle_t)) != 0) {
          result.append("handles not equivalent\n");
          AppendElements<zx_handle_t>(result, num_handles,
                                      params.GetHandles().get(), handles);
          FAIL() << result;
        }
      });

  {
    // Trigger initial breakpoint, on zx_channel_read
    debug_ipc::NotifyException notification;
    notification.type = debug_ipc::NotifyException::Type::kGeneral;
    notification.thread.process_koid = ProcessController::kProcessKoid;
    notification.thread.thread_koid = ProcessController::kThreadKoid;
    notification.thread.state = debug_ipc::ThreadRecord::State::kBlocked;
    notification.thread.stack_amount =
        debug_ipc::ThreadRecord::StackAmount::kMinimal;
    debug_ipc::StackFrame frame(1, 3);
    notification.thread.frames.push_back(frame);
    mock_remote_api().PopulateBreakpointIds(
        DataForZxChannelTest::kReadElfSymbolAddress, notification);
    InjectException(notification);
  }

  debug_ipc::MessageLoop::Current()->Run();

  {
    // Trigger next breakpoint, when zx_channel_read has completed.
    debug_ipc::NotifyException notification;
    notification.type = debug_ipc::NotifyException::Type::kGeneral;
    notification.thread.process_koid = ProcessController::kProcessKoid;
    notification.thread.thread_koid = ProcessController::kThreadKoid;
    notification.thread.state = debug_ipc::ThreadRecord::State::kBlocked;
    InjectException(notification);
  }

  debug_ipc::MessageLoop::Current()->Run();

  // At this point, the ZxChannelWrite callback should have been executed.
  ASSERT_TRUE(hit_breakpoint);

  // Making sure shutdown works.
  debug_ipc::MessageLoop::Current()->Run();
}

TEST_F(InterceptionWorkflowTestX64, ZxChannelRead) { ReadTest(); }

TEST_F(InterceptionWorkflowTestArm, ZxChannelRead) { ReadTest(); }

}  // namespace fidlcat
