// Copyright 2016 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 "cmd_handler.h"

#include <algorithm>
#include <cinttypes>
#include <string>

#include "garnet/lib/debugger_utils/util.h"

#include "garnet/lib/inferior_control/registers.h"
#include "garnet/lib/inferior_control/thread.h"

#include "src/lib/fxl/arraysize.h"
#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/strings/split_string.h"
#include "src/lib/fxl/strings/string_number_conversions.h"
#include "src/lib/fxl/strings/string_printf.h"

#include "registers.h"
#include "server.h"
#include "thread_action_list.h"
#include "util.h"

namespace debugserver {

namespace {

const char kSupportedFeatures[] =
    "QNonStop+;"
#if 0  // TODO(dje)
  "QThreadEvents+;"
#endif
#if 0  // TODO(dje)
  "swbreak+;"
#endif
    "qXfer:auxv:read+";

const char kAttached[] = "Attached";
const char kCurrentThreadId[] = "C";
const char kFirstThreadInfo[] = "fThreadInfo";
const char kNonStop[] = "NonStop";
const char kRcmd[] = "Rcmd,";
const char kSubsequentThreadInfo[] = "sThreadInfo";
const char kSupported[] = "Supported";
const char kXfer[] = "Xfer";

// v Commands
const char kAttach[] = "Attach;";
const char kCont[] = "Cont;";
const char kKill[] = "Kill;";
const char kRun[] = "Run;";

// qRcmd commands
const char kExit[] = "exit";
const char kHelp[] = "help";
const char kQuit[] = "quit";
const char kSet[] = "set";
const char kShow[] = "show";

// This always returns true so that command handlers can simple call "return
// ReplyOK()" rather than "ReplyOK(); return true;
bool ReplyOK(CommandHandler::ResponseCallback callback) {
  callback("OK");
  return true;
}

// This always returns true so that command handlers can simple call "return
// ReplyWithError()" rather than "ReplyWithError(); return true;
bool ReplyWithError(ErrorCode error_code,
                    CommandHandler::ResponseCallback callback) {
  std::string error_rsp = BuildErrorPacket(error_code);
  callback(error_rsp);
  return true;
}

// Returns true if |str| starts with |prefix|.
bool StartsWith(const fxl::StringView& str, const fxl::StringView& prefix) {
  return str.substr(0, prefix.size()) == prefix;
}

debugger_utils::Argv BuildArgvFor_vRun(const fxl::StringView& packet) {
  debugger_utils::Argv argv;
  size_t len = packet.size();
  size_t s = 0;

  while (s < len) {
    size_t semi = packet.find(';', s);
    size_t n;
    if (semi == fxl::StringView::npos)
      n = len - s;
    else
      n = semi - s;
    std::vector<uint8_t> arg =
        debugger_utils::DecodeByteArrayString(packet.substr(s, n));
    auto char_arg = reinterpret_cast<char*>(arg.data());
    argv.push_back(std::string(char_arg, arg.size()));
    if (semi == fxl::StringView::npos)
      s = len;
    else
      s = semi + 1;
  }

  return argv;
}

}  // namespace

CommandHandler::CommandHandler(RspServer* server)
    : server_(server), in_thread_info_sequence_(false) {
  FXL_DCHECK(server_);
}

bool CommandHandler::HandleCommand(const fxl::StringView& packet,
                                   ResponseCallback callback) {
  // GDB packets are prefixed with a letter that maps to a particular command
  // "family". We do the initial multiplexing here and let each individual
  // sub-handler deal with the rest.
  if (packet.empty()) {
    // TODO(armansito): Is there anything meaningful that we can do here?
    FXL_LOG(ERROR) << "Empty packet received";
    return false;
  }

  switch (packet[0]) {
    case '?':  // Indicate the reason the target halted
      if (packet.size() > 1)
        break;
      return HandleQuestionMark(std::move(callback));
    case 'c':  // Continue (at addr)
      return Handle_c(packet.substr(1), std::move(callback));
    case 'C':  // Continue with signal (optionally at addr)
      return Handle_C(packet.substr(1), std::move(callback));
    case 'D':  // Detach
      return Handle_D(packet.substr(1), std::move(callback));
    case 'g':  // Read general registers
      if (packet.size() > 1)
        break;
      return Handle_g(std::move(callback));
    case 'G':  // Write general registers
      return Handle_G(packet.substr(1), std::move(callback));
    case 'H':  // Set a thread for subsequent operations
      return Handle_H(packet.substr(1), std::move(callback));
    case 'm':  // Read memory
      return Handle_m(packet.substr(1), std::move(callback));
    case 'M':  // Write memory
      return Handle_M(packet.substr(1), std::move(callback));
    case 'q':  // General query packet
    case 'Q':  // General set packet
    {
      fxl::StringView prefix, params;
      ExtractParameters(packet.substr(1), &prefix, &params);

      FXL_VLOG(1) << "\'" << packet[0] << "\' packet - prefix: " << prefix
                  << ", params: " << params;

      if (packet[0] == 'q')
        return Handle_q(prefix, params, std::move(callback));
      return Handle_Q(prefix, params, std::move(callback));
    }
    case 'T':  // Is thread alive?
      return Handle_T(packet.substr(1), std::move(callback));
    case 'v':  // v-packets
      return Handle_v(packet.substr(1), std::move(callback));
    case 'z':  // Remove software breakpoint
    case 'Z':  // Insert software breakpoint
      return Handle_zZ(packet[0] == 'Z', packet.substr(1), std::move(callback));
    default:
      break;
  }

  return false;
}

bool CommandHandler::HandleQuestionMark(ResponseCallback callback) {
  // TODO(armansito): Implement this once we actually listen to thread/process
  // exceptions. The logic for NonStop mode is fairly simple:
  //    1. Tell Server to drop any pending and/or queued Stop Reply
  //    notifications.
  //
  //    2. Go through all processes and send a notification for the status of
  //    each.
  //
  //    3. If there is no inferior or the current inferior is not started, then
  //    reply "OK".
  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_c(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "c: No inferior";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  inferior_control::Thread* current_thread = server_->current_thread();

  // If the packet contains an address parameter, then try to set the program
  // counter to then continue at that address. Otherwise, the PC register will
  // remain untouched.
  zx_vaddr_t addr;
  if (!packet.empty()) {
    if (!fxl::StringToNumberWithError<zx_vaddr_t>(packet, &addr,
                                                  fxl::Base::k16)) {
      FXL_LOG(ERROR) << "c: Malformed address given: " << packet;
      return ReplyWithError(ErrorCode::INVAL, std::move(callback));
    }

    // If there is no current thread, then report error. This is a special case
    // that means that the process hasn't started yet.
    if (!current_thread) {
      FXL_DCHECK(!current_process->IsLive());
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }

    if (!current_thread->registers()->RefreshGeneralRegisters()) {
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }
    if (!current_thread->registers()->SetRegister(
            GetPCRegisterNumber(), &addr, sizeof(addr))) {
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }
    if (!current_thread->registers()->WriteGeneralRegisters()) {
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }

    // TODO(armansito): Restore the PC register to its original state in case of
    // a failure condition below?
  }

  // If there is a current thread, then tell it to continue.
  if (current_thread) {
    if (!current_thread->ResumeFromException(server_->exception_port_handle()))
      return ReplyWithError(ErrorCode::PERM, std::move(callback));

    return ReplyOK(std::move(callback));
  }

  // There is no current thread. This means that the process hasn't been started
  // yet. We start it and set the current thread to the first one the kernel
  // gives us.
  // TODO(armansito): Remove this logic now that we handle
  // ZX_EXCP_THREAD_STARTING?
  FXL_DCHECK(!current_process->IsLive());
  if (!current_process->Start()) {
    FXL_LOG(ERROR) << "c: Failed to start the current inferior";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // Try to set the current thread.
  // TODO(armansito): Can this be racy?
  current_thread = current_process->PickOneThread();
  if (current_thread)
    server_->SetCurrentThread(current_thread);

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_C(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "C: No inferior";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  inferior_control::Thread* current_thread = server_->current_thread();
  if (!current_thread) {
    FXL_LOG(ERROR) << "C: No current thread";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // Parse the parameters. The packet format is: sig[;addr]
  size_t semicolon = packet.find(';');
  if (semicolon == fxl::StringView::npos)
    semicolon = packet.size();

  int signo;
  if (!fxl::StringToNumberWithError<int>(packet.substr(0, semicolon), &signo,
                                         fxl::Base::k16)) {
    FXL_LOG(ERROR) << "C: Malformed packet: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  inferior_control::GdbSignal thread_signo = current_thread->GetGdbSignal();
  // TODO(dje): kNone may be a better value to use here.
  if (thread_signo == inferior_control::GdbSignal::kUnsupported) {
    FXL_LOG(ERROR) << "C: Current thread has received no signal";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }
  int int_thread_signo = static_cast<int>(thread_signo);

  if (int_thread_signo != signo) {
    FXL_LOG(ERROR) << "C: Signal numbers don't match - actual: "
                   << int_thread_signo << ", received: " << signo;
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  auto addr_param = packet.substr(semicolon);

  // If the packet contains an address parameter, then try to set the program
  // counter to then continue at that address. Otherwise, the PC register will
  // remain untouched.
  // TODO(armansito): Make Thread::Resume take an optional address argument so
  // we don't have to keep repeating this code.
  if (!addr_param.empty()) {
    zx_vaddr_t addr;
    if (!fxl::StringToNumberWithError<zx_vaddr_t>(addr_param, &addr,
                                                  fxl::Base::k16)) {
      FXL_LOG(ERROR) << "C: Malformed address given: " << packet;
      return ReplyWithError(ErrorCode::INVAL, std::move(callback));
    }

    if (!current_thread->registers()->RefreshGeneralRegisters()) {
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }
    if (!current_thread->registers()->SetRegister(
            GetPCRegisterNumber(), &addr, sizeof(addr))) {
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }
    if (!current_thread->registers()->WriteGeneralRegisters()) {
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }

    // TODO(armansito): Restore the PC register to its original state in case of
    // a failure condition below?
  }

  if (!current_thread->ResumeFromException(server_->exception_port_handle())) {
    FXL_LOG(ERROR) << "Failed to resume thread";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_D(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "D: No inferior";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // For now we only support detaching from the one process we have.
  if (packet[0] == ';') {
    zx_koid_t pid;
    if (!fxl::StringToNumberWithError<zx_koid_t>(packet.substr(1), &pid,
                                                 fxl::Base::k16)) {
      FXL_LOG(ERROR) << "D: bad pid: " << packet;
      return ReplyWithError(ErrorCode::INVAL, std::move(callback));
    }
    if (pid != current_process->id()) {
      FXL_LOG(ERROR) << "D: unknown pid: " << pid;
      return ReplyWithError(ErrorCode::INVAL, std::move(callback));
    }
  } else if (packet != "") {
    FXL_LOG(ERROR) << "D: Malformed packet: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  if (!current_process->IsAttached()) {
    FXL_LOG(ERROR) << "D: Not attached to process " << current_process->id();
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  if (!current_process->Detach()) {
    // At the moment this shouldn't happen, but we don't want to kill the
    // debug session because of it. The details of the failure are already
    // logged by Detach().
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }
  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_g(ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "g: No inferior";
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  // If there is no current thread, then we reply with "0"s for all registers.
  // TODO(armansito): gG packets are technically used to read/write "ALL"
  // registers, not just the general registers. We'll have to take this into
  // account in the future, though for now we're just supporting general
  // registers.
  std::string result;
  if (!server_->current_thread()) {
    result = GetUninitializedGeneralRegistersAsString();
  } else {
    result = GetGeneralRegistersAsString(server_->current_thread());
  }

  if (result.empty()) {
    FXL_LOG(ERROR) << "g: Failed to read register values";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  callback(result);
  return true;
}

bool CommandHandler::Handle_G(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "G: No inferior";
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  // If there is no current thread report an error.
  inferior_control::Thread* current_thread = server_->current_thread();
  if (!current_thread) {
    FXL_LOG(ERROR) << "G: No current thread";
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  // We pass the packet here directly since Registers handles the parsing.
  // TODO(armansito): gG packets are technically used to read/write "ALL"
  // registers, not just the general registers. We'll have to take this into
  // account in the future, though for now we're just supporting general
  // registers.
  if (SetGeneralRegistersFromString(current_thread, packet)) {
    FXL_LOG(ERROR) << "G: Failed to write to general registers";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }
  if (!current_thread->registers()->WriteGeneralRegisters()) {
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_H(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // Here we set the "current thread" for subsequent operations
  // (‘m’, ‘M’, ‘g’, ‘G’, et.al.).
  // There are two types of an H packet. 'c' and 'g'. We claim to not support
  // 'c' because it's specified as deprecated.

  // Packet should at least contain 'c' or 'g' and some characters for the
  // thread id.
  if (packet.size() < 2)
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));

  switch (packet[0]) {
    case 'c':  // fall through
    case 'g': {
      int64_t pid, tid;
      bool has_pid;
      if (!ParseThreadId(packet.substr(1), &has_pid, &pid, &tid))
        return ReplyWithError(ErrorCode::INVAL, std::move(callback));

      // We currently support debugging only one process.
      // TODO(armansito): What to do with a process ID? Replying with an empty
      // packet for now.
      if (has_pid) {
        FXL_LOG(WARNING)
            << "Specifying a pid while setting the current thread is"
            << " not supported";
        return false;
      }

      // Setting the current thread to "all threads" doesn't make much sense.
      if (tid < 0) {
        FXL_LOG(ERROR) << "Cannot set the current thread to all threads";
        return ReplyWithError(ErrorCode::INVAL, std::move(callback));
      }

      inferior_control::Process* current_process = server_->current_process();

      // Note that at this point we may have a process but are not necessarily
      // attached yet. GDB sends the Hg0 packet early on, and expects it to
      // succeed.
      if (!current_process) {
        FXL_LOG(ERROR) << "No inferior exists";

        // If we're given a positive thread ID but there is currently no
        // inferior, then report error?
        if (!tid) {
          FXL_LOG(ERROR) << "Cannot set a current thread with no inferior";
          return ReplyWithError(ErrorCode::PERM, std::move(callback));
        }

        FXL_LOG(WARNING) << "Setting current thread to NULL for tid=0";

        server_->SetCurrentThread(nullptr);
        return ReplyOK(std::move(callback));
      }

      // If the process hasn't started yet it will have no threads. Since "Hg0"
      // is one of the first things that GDB sends after a connection (and
      // since we don't run the process right away), we lie to GDB and set the
      // current thread to null.
      if (!current_process->IsLive()) {
        FXL_LOG(INFO) << "Current process has no threads yet but we pretend to "
                      << "set one";
        server_->SetCurrentThread(nullptr);
        return ReplyOK(std::move(callback));
      }

      current_process->EnsureThreadMapFresh();

      inferior_control::Thread* thread;

      // A thread ID value of 0 means "pick an arbitrary thread".
      if (tid == 0)
        thread = current_process->PickOneThread();
      else
        thread = current_process->FindThreadById(tid);

      if (!thread) {
        FXL_LOG(ERROR) << "Failed to set the current thread";
        return ReplyWithError(ErrorCode::PERM, std::move(callback));
      }

      server_->SetCurrentThread(thread);
      return ReplyOK(std::move(callback));
    }
    default:
      break;
  }

  return false;
}

bool CommandHandler::Handle_m(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "m: No inferior";
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  // The "m" packet should have two arguments for addr and length, separated by
  // a single comma.
  auto params = fxl::SplitString(packet, ",", fxl::kKeepWhitespace,
                                 fxl::kSplitWantNonEmpty);
  if (params.size() != 2) {
    FXL_LOG(ERROR) << "m: Malformed packet: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  uintptr_t addr;
  size_t length;
  if (!fxl::StringToNumberWithError<uintptr_t>(params[0], &addr,
                                               fxl::Base::k16) ||
      !fxl::StringToNumberWithError<size_t>(params[1], &length,
                                            fxl::Base::k16)) {
    FXL_LOG(ERROR) << "m: Malformed params: " << packet;
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  std::unique_ptr<uint8_t[]> buffer(new uint8_t[length]);
  if (!current_process->ReadMemory(addr, buffer.get(), length)) {
    FXL_LOG(ERROR) << "m: Failed to read memory";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  std::string result =
      debugger_utils::EncodeByteArrayString(buffer.get(), length);
  callback(result);
  return true;
}

bool CommandHandler::Handle_M(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "M: No inferior";
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  // The "M" packet parameters look like this: "addr,length:XX...".
  // First, extract the addr,len and data sections. Using fxl::kSplitWantAll
  // here since the data portion could technically be empty if the given length
  // is 0.
  auto params =
      fxl::SplitString(packet, ":", fxl::kKeepWhitespace, fxl::kSplitWantAll);
  if (params.size() != 2) {
    FXL_LOG(ERROR) << "M: Malformed packet: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  fxl::StringView data = params[1];

  // Extract addr and len
  params = fxl::SplitString(params[0], ",", fxl::kKeepWhitespace,
                            fxl::kSplitWantNonEmpty);
  if (params.size() != 2) {
    FXL_LOG(ERROR) << "M: Malformed packet: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  uintptr_t addr;
  size_t length;
  if (!fxl::StringToNumberWithError<uintptr_t>(params[0], &addr,
                                               fxl::Base::k16) ||
      !fxl::StringToNumberWithError<size_t>(params[1], &length,
                                            fxl::Base::k16)) {
    FXL_LOG(ERROR) << "M: Malformed params: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  FXL_VLOG(1) << fxl::StringPrintf("M: addr=0x%" PRIxPTR ", len=%lu", addr,
                                   length);

  auto data_bytes = debugger_utils::DecodeByteArrayString(data);
  if (data_bytes.size() != length) {
    FXL_LOG(ERROR) << "M: payload length doesn't match length argument - "
                   << "payload size: " << data_bytes.size()
                   << ", length requested: " << length;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  // Short-circuit if |length| is 0.
  if (length &&
      !current_process->WriteMemory(addr, data_bytes.data(), length)) {
    FXL_LOG(ERROR) << "M: Failed to write memory";

    // TODO(armansito): The error code definitions from GDB aren't really
    // granular enough to aid debug various error conditions (e.g. we may want
    // to report why the memory write failed based on the zx_status_t returned
    // from Zircon). (See TODO in util.h).
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_q(const fxl::StringView& prefix,
                              const fxl::StringView& params,
                              ResponseCallback callback) {
  if (prefix == kAttached)
    return HandleQueryAttached(params, std::move(callback));

  if (prefix == kCurrentThreadId)
    return HandleQueryCurrentThreadId(params, std::move(callback));

  if (prefix == kFirstThreadInfo)
    return HandleQueryThreadInfo(true, std::move(callback));

  // The qRcmd packet is different than most. It uses , as a delimiter, not :.
  if (StartsWith(prefix, kRcmd))
    return HandleQueryRcmd(prefix.substr(std::strlen(kRcmd)),
                           std::move(callback));

  if (prefix == kSubsequentThreadInfo)
    return HandleQueryThreadInfo(false, std::move(callback));

  if (prefix == kSupported)
    return HandleQuerySupported(params, std::move(callback));

  if (prefix == kXfer)
    return HandleQueryXfer(params, std::move(callback));

  // TODO(dje): TO-195
  // - QDisableRandomization:VALUE ?
  // - qGetTLSAddr:THREAD-ID,OFFSET,LM
  // - qThreadExtraInfo,THREAD-ID ?

  return false;
}

bool CommandHandler::Handle_Q(const fxl::StringView& prefix,
                              const fxl::StringView& params,
                              ResponseCallback callback) {
  if (prefix == kNonStop)
    return HandleSetNonStop(params, std::move(callback));

  return false;
}

bool CommandHandler::Handle_T(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "T: No inferior";
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  zx_koid_t tid;
  if (!fxl::StringToNumberWithError<zx_koid_t>(packet, &tid, fxl::Base::k16)) {
    FXL_LOG(ERROR) << "T: Malformed thread id given: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  inferior_control::Thread* thread = current_process->FindThreadById(tid);
  if (!thread) {
    FXL_LOG(ERROR) << "T: no such thread: " << packet;
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }
  if (!thread->IsLive()) {
    FXL_LOG(ERROR) << "T: thread found, but not live: " << packet;
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_v(const fxl::StringView& packet,
                              ResponseCallback callback) {
  if (StartsWith(packet, kAttach))
    return Handle_vAttach(packet.substr(std::strlen(kAttach)),
                          std::move(callback));
  if (StartsWith(packet, kCont))
    return Handle_vCont(packet.substr(std::strlen(kCont)), std::move(callback));
  if (StartsWith(packet, kKill))
    return Handle_vKill(packet.substr(std::strlen(kKill)), std::move(callback));
  if (StartsWith(packet, kRun))
    return Handle_vRun(packet.substr(std::strlen(kRun)), std::move(callback));

  return false;
}

bool CommandHandler::Handle_zZ(bool insert, const fxl::StringView& packet,
                               ResponseCallback callback) {
// Z0 needs more work. Disabled until ready.
// One issue is we need to support the swbreak feature.
#if 0
  // A Z packet contains the "type,addr,kind" parameters before all other
  // optional parameters, which follow an optional ';' character. Check to see
  // if there are any optional parameters:
  size_t semicolon = packet.find(';');

  // fxl::StringView::find returns npos if it can't find the character. Adjust
  // |semicolon| to point just beyond the end of |packet| so that
  // packet.substr() works..
  if (semicolon == fxl::StringView::npos)
    semicolon = packet.size();

  auto params = fxl::SplitString(packet.substr(0, semicolon), ",",
                                 fxl::kKeepWhitespace, fxl::kSplitWantNonEmpty);
  if (params.size() != 3) {
    FXL_LOG(ERROR) << "zZ: 3 required parameters missing";
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  size_t type;
  uintptr_t addr;
  size_t kind;
  if (!fxl::StringToNumberWithError<uintptr_t>(params[0], &type,
                                               fxl::Base::k16) ||
      !fxl::StringToNumberWithError<uintptr_t>(params[1], &addr,
                                               fxl::Base::k16) ||
      !fxl::StringToNumberWithError<size_t>(params[2], &kind, fxl::Base::k16)) {
    FXL_LOG(ERROR) << "zZ: Failed to parse |type|, |addr| and |kind|";
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  auto optional_params = packet.substr(semicolon);

  // "Remove breakpoint" packets don't contain any optional fields.
  if (!insert && !optional_params.empty()) {
    FXL_LOG(ERROR) << "zZ: Malformed packet";
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  switch (type) {
    case 0:
      if (kind != inferior_control::SoftwareBreakpoint::Size()) {
        FXL_LOG(ERROR) << "zZ0: unsupported kind field: "  << kind;
        return ReplyWithError(ErrorCode::INVAL, std::move(callback));
      }
      if (insert) {
        return InsertSoftwareBreakpoint(addr, optional_params, std::move(callback));
      }
      return RemoveSoftwareBreakpoint(addr, std::move(callback));
    default:
      break;
  }

  FXL_LOG(WARNING) << "Breakpoints of type " << type
                   << " currently not supported";
#endif
  return false;
}

bool CommandHandler::HandleQueryAttached(const fxl::StringView& params,
                                         ResponseCallback callback) {
  // We don't support multiprocessing yet, so make sure we received the version
  // of qAttached that doesn't have a "pid" parameter.
  if (!params.empty())
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));

  // The response is "1" if we attached to an existing process, or "0" if we
  // created a new one. We currently don't support the former, so always send
  // "0".
  callback("0");
  return true;
}

bool CommandHandler::HandleQueryCurrentThreadId(const fxl::StringView& params,
                                                ResponseCallback callback) {
  // The "qC" packet has no parameters.
  if (!params.empty())
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));

  inferior_control::Thread* current_thread = server_->current_thread();
  if (!current_thread) {
    // If there is a current process and it has been started, pick one thread
    // and set that as the current one. This is our work around for lying to GDB
    // about setting a current thread in response to an early Hg0 packet.
    inferior_control::Process* current_process = server_->current_process();
    if (!current_process || !current_process->IsLive()) {
      FXL_LOG(ERROR) << "qC: Current thread has not been set";
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }

    FXL_VLOG(1) << "qC: Picking one arbitrary thread";
    current_thread = current_process->PickOneThread();
    if (!current_thread) {
      FXL_VLOG(1) << "qC: Failed to pick a thread";
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }
  }

  std::string thread_id =
      fxl::NumberToString<zx_koid_t>(current_thread->id(), fxl::Base::k16);

  std::string reply = "QC" + thread_id;
  callback(reply);
  return true;
}

bool CommandHandler::HandleQueryRcmd(const fxl::StringView& command,
                                     ResponseCallback callback) {
  auto cmd_string = debugger_utils::DecodeString(command);
  std::vector<fxl::StringView> argv = fxl::SplitString(
      cmd_string, " ", fxl::kTrimWhitespace, fxl::kSplitWantNonEmpty);
  if (argv.size() == 0) {
    // No command, just reply OK.
    return ReplyOK(std::move(callback));
  }
  auto cmd = argv[0];

  // We support both because qemu uses "quit" and GNU gdbserver uses "exit".
  if (cmd == kQuit || cmd == kExit) {
    if (argv.size() != 1)
      goto bad_command;
    ReplyOK(std::move(callback));
    server_->PostQuitMessageLoop(true);
  } else if (cmd == kHelp) {
    if (argv.size() != 1)
      goto bad_command;
    static constexpr char kHelpText[] =
        "help - print this help text\n"
        "exit - quit debugserver\n"
        "quit - quit debugserver\n"
        "set <parameter> <value>\n"
        "show <parameter>\n"
        "\n"
        "Parameters:\n"
        "  verbosity - useful range is -2 to 3 (-2 is most verbose)\n";
    callback(debugger_utils::EncodeString(kHelpText));
  } else if (cmd == kSet) {
    if (argv.size() != 3)
      goto bad_command;
    if (!server_->SetParameter(argv[1], argv[2]))
      goto bad_command;
    ReplyOK(std::move(callback));
  } else if (cmd == kShow) {
    if (argv.size() != 2)
      goto bad_command;
    std::string value;
    if (!server_->GetParameter(argv[1], &value))
      goto bad_command;
    callback(debugger_utils::EncodeString("Value is " + value + "\n"));
  } else {
    callback(debugger_utils::EncodeString("Invalid monitor command\n"));
  }

  return true;

bad_command:
  // Errors are not reported via the usual mechanism. For rCmd, the usual
  // mechanism is for things like protocol errors. Instead we just want to
  // return the desired error message.
  callback(debugger_utils::EncodeString("Invalid command\n"));
  return true;
}

bool CommandHandler::HandleQuerySupported(const fxl::StringView& params,
                                          ResponseCallback callback) {
  // We ignore the parameters for qSupported. Respond with the supported
  // features.
  callback(kSupportedFeatures);
  return true;
}

bool CommandHandler::HandleSetNonStop(const fxl::StringView& params,
                                      ResponseCallback callback) {
  // The only values we accept are "1" and "0".
  if (params.size() != 1)
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));

  // We currently only support non-stop mode.
  char value = params[0];
  if (value == '1')
    return ReplyOK(std::move(callback));

  if (value == '0')
    return ReplyWithError(ErrorCode::PERM, std::move(callback));

  FXL_LOG(ERROR) << "QNonStop received with invalid value: " << (unsigned)value;
  return ReplyWithError(ErrorCode::INVAL, std::move(callback));
}

bool CommandHandler::HandleQueryThreadInfo(bool is_first,
                                           ResponseCallback callback) {
  FXL_DCHECK(server_);

  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "Current process is not set";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // For the "first" thread info query we reply with the complete list of
  // threads and always report "end of list" for subsequent queries. The GDB
  // Remote Protocol does not seem to define a MTU, however, we could be running
  // on a platform with resource constraints that may require us to break up the
  // sequence into multiple packets. For now we do not worry about this.

  if (!is_first) {
    // This is a subsequent query. Check that a thread info query sequence was
    // started (just for sanity) and report end of list.
    if (!in_thread_info_sequence_) {
      FXL_LOG(ERROR) << "qsThreadInfo received without first receiving "
                     << "qfThreadInfo";
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }

    in_thread_info_sequence_ = false;
    callback("l");
    return true;
  }

  // This is the first query. Check the sequence state for sanity.
  if (in_thread_info_sequence_) {
    FXL_LOG(ERROR) << "qfThreadInfo received while already in an active "
                   << "sequence";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  current_process->EnsureThreadMapFresh();

  std::deque<std::string> thread_ids;
  size_t buf_size = 0;
  current_process->ForEachLiveThread(
      [&thread_ids, &buf_size](inferior_control::Thread* thread) {
        std::string thread_id =
            fxl::NumberToString<zx_koid_t>(thread->id(), fxl::Base::k16);
        buf_size += thread_id.length();
        thread_ids.push_back(thread_id);
      });

  if (thread_ids.empty()) {
    // No ids to report. End of sequence.
    callback("l");
    return true;
  }

  in_thread_info_sequence_ = true;

  // Add the number of commas (|thread_ids.size() - 1|) plus the prefix "m")
  buf_size += thread_ids.size();

  std::unique_ptr<char[]> buffer(new char[buf_size]);
  buffer.get()[0] = 'm';
  debugger_utils::JoinStrings(thread_ids, ',', buffer.get() + 1, buf_size - 1);

  callback(fxl::StringView(buffer.get(), buf_size));

  return true;
}

bool CommandHandler::HandleQueryXfer(const fxl::StringView& params,
                                     ResponseCallback callback) {
  // We only support qXfer:auxv:read::
  // TODO(dje): TO-195
  // - qXfer::osdata::read::OFFSET,LENGTH
  // - qXfer:memory-map:read::OFFSET,LENGTH ?
  // - qXfer:libraries-svr4:read:ANNEX:OFFSET,LENGTH ?
  // - qXfer:features:read:ANNEX:OFFSET,LENGTH ?
  fxl::StringView auxv_read("auxv:read::");
  if (!StartsWith(params, auxv_read))
    return false;

  // Parse offset,length
  auto args = fxl::SplitString(params.substr(auxv_read.size()), ",",
                               fxl::kKeepWhitespace, fxl::kSplitWantNonEmpty);
  if (args.size() != 2) {
    FXL_LOG(ERROR) << "qXfer:auxv:read:: Malformed params: " << params;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  size_t offset, length;
  if (!fxl::StringToNumberWithError<size_t>(args[0], &offset, fxl::Base::k16) ||
      !fxl::StringToNumberWithError<size_t>(args[1], &length, fxl::Base::k16)) {
    FXL_LOG(ERROR) << "qXfer:auxv:read:: Malformed params: " << params;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "qXfer:auxv:read: No current process is not set";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // Build the auxiliary vector. This definition is provided by the Linux manual
  // page for the proc pseudo-filesystem (i.e. 'man proc'):
  // "This contains the contents of the ELF interpreter information passed to
  // the process at exec time. The format is one unsigned long ID plus one
  // unsigned long value for each entry. The last entry contains two zeros."
  // On Fuchsia we borrow this concept to save inventing something new.
  // We may have to eventually, but this works for now.
  // There is an extra complication that all the needed values aren't available
  // when the process starts: e.g., AT_ENTRY - the executable isn't loaded
  // until sometime after the process starts.
  constexpr size_t kMaxAuxvEntries = 10;
  struct {
    unsigned long key;
    unsigned long value;
  } auxv[kMaxAuxvEntries];

#define ADD_AUXV(_key, _value) \
  do {                         \
    auxv[n].key = (_key);      \
    auxv[n].value = (_value);  \
    ++n;                       \
  } while (0)

  size_t n = 0;
  ADD_AUXV(AT_BASE, current_process->base_address());
  if (current_process->DsosLoaded()) {
    const debugger_utils::dsoinfo_t* exec = current_process->GetExecDso();
    if (exec) {
      ADD_AUXV(AT_ENTRY, exec->entry);
      ADD_AUXV(AT_PHDR, exec->phdr);
      ADD_AUXV(AT_PHENT, exec->phentsize);
      ADD_AUXV(AT_PHNUM, exec->phnum);
    }
  }
  ADD_AUXV(AT_NULL, 0);
  FXL_DCHECK(n <= arraysize(auxv));

#undef ADD_AUXV

  // We allow setting sizeof(auxv) as the offset, which would effectively result
  // in reading 0 bytes.
  if (offset > sizeof(auxv)) {
    FXL_LOG(ERROR) << "qXfer:auxv:read: invalid offset";
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  size_t end = n * sizeof(auxv[0]);
  size_t rsp_len = std::min(end - offset, length);
  char rsp[1 + rsp_len];

  rsp[0] = 'l';
  memcpy(rsp + 1, auxv + offset, rsp_len);

  callback(fxl::StringView(rsp, sizeof(rsp)));
  return true;
}

bool CommandHandler::Handle_vAttach(const fxl::StringView& packet,
                                    ResponseCallback callback) {
  inferior_control::Process* inferior = server_->current_process();
  if (!inferior) {
    FXL_LOG(ERROR) << "vAttach: no inferior selected";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  zx_koid_t pid;
  if (!fxl::StringToNumberWithError<zx_koid_t>(packet, &pid, fxl::Base::k16)) {
    FXL_LOG(ERROR) << "vAttach:: Malformed pid: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  switch (inferior->state()) {
    case inferior_control::Process::State::kNew:
    case inferior_control::Process::State::kGone:
      break;
    default:
      FXL_LOG(ERROR)
          << "vAttach: need to kill the currently running process first";
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  zx::process process = server_->FindProcess(pid);
  if (!process) {
    FXL_LOG(ERROR) << "vAttach: cannot find process " << pid;
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }
  if (!inferior->AttachToRunning(std::move(process))) {
    FXL_LOG(ERROR) << "vAttach: failed to attach to inferior";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // It's Attach()'s job to mark the process as live, since it knows we just
  // attached to an already running program.
  FXL_DCHECK(inferior->IsLive());

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_vCont(const fxl::StringView& packet,
                                  ResponseCallback callback) {
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "vCont: no current process to run!";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  ThreadActionList actions(packet, current_process->id());
  if (!actions.valid()) {
    FXL_LOG(ERROR) << "vCont: \"" << packet << "\": error / not supported.";
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  FXL_DCHECK(current_process->IsLive());
  FXL_DCHECK(current_process->IsAttached());

  // Before we start calling GetAction we need to resolve "pick one" thread
  // values.
  for (auto e : actions.actions()) {
    if (e.tid() == 0) {
      FXL_DCHECK(e.pid() > 0);
      // TODO(dje): For now we assume there is only one process.
      FXL_DCHECK(current_process->id() == e.pid() ||
                 e.pid() == ThreadActionList::kAll);
      inferior_control::Thread* t = current_process->PickOneThread();
      if (t)
        e.set_picked_tid(t->id());
    }
  }
  actions.MarkPickOnesResolved();

  // First pass over all actions: Find any errors that we can so that we
  // don't cause any thread to run if there's an error.

  bool action_list_ok = true;
  current_process->ForEachLiveThread(
      [&actions, ok_ptr = &action_list_ok](inferior_control::Thread* thread) {
        zx_koid_t pid = thread->process()->id();
        zx_koid_t tid = thread->id();
        ThreadActionList::Action action = actions.GetAction(pid, tid);
        switch (action) {
          case ThreadActionList::Action::kStep:
            switch (thread->state()) {
              case inferior_control::Thread::State::kNew:
                FXL_LOG(ERROR) << "vCont;s: can't step thread in kNew state";
                *ok_ptr = false;
                return;
              default:
                break;
            }
          default:
            break;
        }
      });
  if (!action_list_ok)
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));

  current_process->ForEachLiveThread(
      [&actions](inferior_control::Thread* thread) {
        inferior_control::Process* process = thread->process();
        zx_koid_t pid = process->id();
        zx_koid_t tid = thread->id();
        ThreadActionList::Action action = actions.GetAction(pid, tid);
        FXL_VLOG(1) << "vCont; Thread " << thread->GetDebugName()
                    << " state: " << thread->StateName(thread->state())
                    << " action: " << ThreadActionList::ActionToString(action);
        switch (action) {
          case ThreadActionList::Action::kContinue:
            switch (thread->state()) {
              case inferior_control::Thread::State::kNew:
              case inferior_control::Thread::State::kInException:
                thread->ResumeFromException(
                  process->server()->exception_port_handle());
                break;
              default:
                break;
            }
          case ThreadActionList::Action::kStep:
            switch (thread->state()) {
              case inferior_control::Thread::State::kInException:
                thread->Step();
                break;
              default:
                break;
            }
          default:
            break;
        }
      });

  // We defer sending a stop-reply packet. Server will send it out when threads
  // stop. At this point in time GDB is just expecting "OK".
  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_vKill(const fxl::StringView& packet,
                                  ResponseCallback callback) {
  FXL_VLOG(2) << "Handle_vKill: " << packet;

  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    // This can't happen today, but it might eventually.
    FXL_LOG(ERROR) << "vRun: no current process to kill!";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  zx_koid_t pid;
  if (!fxl::StringToNumberWithError<zx_koid_t>(packet, &pid, fxl::Base::k16)) {
    FXL_LOG(ERROR) << "vAttach:: Malformed pid: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  // Since we only support one process at the moment, only allow killing
  // that one.
  if (pid != current_process->id()) {
    FXL_LOG(ERROR) << "vAttach:: not our pid: " << pid;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  switch (current_process->state()) {
    case inferior_control::Process::State::kNew:
    case inferior_control::Process::State::kGone:
      FXL_LOG(ERROR) << "vKill: process not running";
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    default:
      break;
  }

  if (!current_process->Kill()) {
    FXL_LOG(ERROR) << "Failed to kill inferior";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_vRun(const fxl::StringView& packet,
                                 ResponseCallback callback) {
  FXL_VLOG(2) << "Handle_vRun: " << packet;

  inferior_control::Process* inferior = server_->current_process();
  if (!inferior) {
    // This can't happen today, but it might eventually.
    FXL_LOG(ERROR) << "vRun: no current process to run!";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  if (!packet.empty()) {
    server_->set_inferior_argv(BuildArgvFor_vRun(packet));
  }
  if (server_->inferior_argv().empty()) {
    FXL_LOG(ERROR) << "vRun: no program to run";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  switch (inferior->state()) {
    case inferior_control::Process::State::kNew:
    case inferior_control::Process::State::kGone:
      break;
    default:
      FXL_LOG(ERROR)
          << "vRun: need to kill the currently running process first";
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  std::unique_ptr<process::ProcessBuilder> builder;
  if (!server_->CreateProcessViaBuilder(server_->inferior_argv()[0],
                                        server_->inferior_argv(),
                                        &builder)) {
    FXL_LOG(ERROR) << "vRun: unable to initialize process builder";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  builder->CloneAll();

  if (!inferior->InitializeFromBuilder(std::move(builder))) {
    FXL_LOG(ERROR) << "vRun: unable to initialize inferior process";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // On Linux, the program is considered "live" after vRun, e.g. $pc is set. On
  // Zircon, calling zx_process_start (called by Process::Start()) creates a
  // synthetic exception of type ZX_EXCP_START if a debugger is attached to the
  // process and halts until a call to zx_task_resume_from_exception (i.e.
  // called by Thread::Resume() in gdbserver).
  if (!inferior->Start()) {
    FXL_LOG(ERROR) << "vRun: unable to start process";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }
  FXL_DCHECK(inferior->IsLive());

  // We defer sending a stop-reply packet. Server will send it out when it
  // receives an OnThreadStarting() event from |current_process|.

  return true;
}

bool CommandHandler::InsertSoftwareBreakpoint(
    uintptr_t addr, const fxl::StringView& optional_params,
    ResponseCallback callback) {
  FXL_VLOG(1) << fxl::StringPrintf(
      "Insert software breakpoint at 0x%lx", addr);

  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "No current process exists";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // TODO(armansito): Handle |optional_params|.

  if (!current_process->breakpoints()->InsertSoftwareBreakpoint(addr)) {
    FXL_LOG(ERROR) << "Failed to insert software breakpoint";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

bool CommandHandler::RemoveSoftwareBreakpoint(uintptr_t addr,
                                              ResponseCallback callback) {
  FXL_VLOG(1) << fxl::StringPrintf(
      "Remove software breakpoint at 0x%lx", addr);

  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "No current process exists";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  if (!current_process->breakpoints()->RemoveSoftwareBreakpoint(addr)) {
    FXL_LOG(ERROR) << "Failed to remove software breakpoint";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

}  // namespace debugserver
