// Copyright 2018 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.

#ifndef SRC_DEVELOPER_DEBUG_DEBUG_AGENT_DEBUGGED_PROCESS_H_
#define SRC_DEVELOPER_DEBUG_DEBUG_AGENT_DEBUGGED_PROCESS_H_

#include <map>
#include <memory>
#include <vector>

#include <fbl/unique_fd.h>

#include "src/developer/debug/debug_agent/debugged_thread.h"
#include "src/developer/debug/debug_agent/module_list.h"
#include "src/developer/debug/debug_agent/process_handle.h"
#include "src/developer/debug/debug_agent/process_handle_observer.h"
#include "src/developer/debug/debug_agent/stdio_handles.h"
#include "src/developer/debug/ipc/protocol.h"
#include "src/developer/debug/shared/buffered_zx_socket.h"
#include "src/developer/debug/shared/message_loop.h"
#include "src/lib/fxl/macros.h"

namespace debug_agent {

class Breakpoint;
class DebugAgent;
class HardwareBreakpoint;
class ProcessBreakpoint;
class ProcessWatchpoint;
class SoftwareBreakpoint;
class Watchpoint;

struct DebuggedProcessCreateInfo {
  explicit DebuggedProcessCreateInfo(std::unique_ptr<ProcessHandle> handle);

  // Required.
  std::unique_ptr<ProcessHandle> handle;

  // Optional.
  StdioHandles stdio;

  // Whether this process was obtained via a process limbo.
  // This is relevant when attempting to kill the process, as handles obtained via the limbo do not
  // have the ZX_RIGHT_DESTROY right. The way to "kill" them is to re send them to the limbo and
  // then release it from it.
  bool from_limbo = false;
};

class DebuggedProcess : public ProcessHandleObserver {
 public:
  using WatchpointMap = std::map<debug_ipc::AddressRange, std::unique_ptr<Watchpoint>,
                                 debug_ipc::AddressRangeBeginCmp>;

  // Caller must call Init immediately after construction and delete the
  // object if that fails.
  DebuggedProcess(DebugAgent*, DebuggedProcessCreateInfo&&);
  virtual ~DebuggedProcess();

  zx_koid_t koid() const { return process_handle_->GetKoid(); }
  DebugAgent* debug_agent() const { return debug_agent_; }

  const ProcessHandle& process_handle() const { return *process_handle_; }
  ProcessHandle& process_handle() { return *process_handle_; }

  // TODO(brettw) remove this and have all callers use thread_handle().
  zx::process& handle() { return process_handle_->GetNativeHandle(); }
  const zx::process& handle() const { return process_handle_->GetNativeHandle(); }

  const ModuleList& module_list() const { return module_list_; }

  // Returns true on success. On failure, the object may not be used further.
  debug::Status Init();

  // IPC handlers.
  void OnResume(const debug_ipc::ResumeRequest& request);
  void OnReadMemory(const debug_ipc::ReadMemoryRequest& request, debug_ipc::ReadMemoryReply* reply);
  void OnKill(const debug_ipc::KillRequest& request, debug_ipc::KillReply* reply);
  void OnAddressSpace(const debug_ipc::AddressSpaceRequest& request,
                      debug_ipc::AddressSpaceReply* reply);
  void OnModules(debug_ipc::ModulesReply* reply);
  void OnWriteMemory(const debug_ipc::WriteMemoryRequest& request,
                     debug_ipc::WriteMemoryReply* reply);
  void OnLoadInfoHandleTable(const debug_ipc::LoadInfoHandleTableRequest& request,
                             debug_ipc::LoadInfoHandleTableReply* reply);

  void InjectThreadForTest(std::unique_ptr<DebuggedThread> thread);

  // Synchronously pauses all threads in the process from the perspective of the client. This issues
  // ClientSuspend() on all threads (see that for more on what "client" means).
  //
  // The except_thread can be passed which indicates a thread to ship when suspending. This is for
  // certain operations that want to do something to all other threads.
  //
  // The affected thread koids are returned. If a thread is already in a client suspend, it will
  // not be affected and it will not be returned in the result.
  std::vector<zx_koid_t> ClientSuspendAllThreads(zx_koid_t except_thread = ZX_KOID_INVALID);

  // Returns the thread or null if there is no known thread for this koid.
  DebuggedThread* GetThread(zx_koid_t thread_koid) const;
  std::vector<DebuggedThread*> GetThreads() const;

  // Populates the thread map with the current threads for this process.
  // This function does not notify the client of thread start, but rather updates the internal
  // thread state according to the underlying zircon truth.
  void PopulateCurrentThreads();

  // Returns the information for all current threads. This gets minimal stacks.
  std::vector<debug_ipc::ThreadRecord> GetThreadRecords() const;

  // Checks if this breakpoint is a special internal one. If it is, handles it and returns true.
  // If it's not special, does nothing and returns false. The parameter indicates the breakpoint
  // that was hit. If the breakpoint was a hardcoded one, the parameter should be null.
  //
  // This will check for the different types of loader breakpoints.
  enum class SpecialBreakpointResult { kNotSpecial, kContinue, kKeepSuspended };
  SpecialBreakpointResult HandleSpecialBreakpoint(ProcessBreakpoint* optional_bp);

  // If the process can know its modules, suspend all thread and send the module list. This does not
  // refresh the module list.
  //
  // This is used in the case where we attach to an existing process or a new forked process and the
  // debug address is known. The client expects the threads to be suspended so it can resolve
  // breakpoints and resume them.
  virtual void SuspendAndSendModulesIfKnown();

  // Looks for breakpoints at the given address. Null if no breakpoints are at that address.
  virtual SoftwareBreakpoint* FindSoftwareBreakpoint(uint64_t address) const;
  virtual HardwareBreakpoint* FindHardwareBreakpoint(uint64_t address) const;
  virtual Watchpoint* FindWatchpoint(const debug_ipc::AddressRange&) const;

  debug::Status RegisterBreakpoint(Breakpoint* bp, uint64_t address);
  void UnregisterBreakpoint(Breakpoint* bp, uint64_t address);

  debug::Status RegisterWatchpoint(Breakpoint* bp, const debug_ipc::AddressRange& range);
  void UnregisterWatchpoint(Breakpoint* bp, const debug_ipc::AddressRange& range);

  // Each time a thread attempts to step over a breakpoint, the breakpoint will enqueue itself and
  // the thread into the step over queue. The step over queue is used so that there is only one
  // breakpoint being stepped over at a time.
  //
  // Enqueuing the breakpoint does not mean that the step over begins immediately, but rather the
  // process will call the |ExecuteStepOver| method on the breakpoint once its turn has come up in
  // the queue.
  //
  // In some error cases this might happen twice for the same thread. For example, if there is an
  // error clearing the breakpoint instruction, attempting to clear it and then single-step it will
  // just hit the same breakpoint again and the "step over" will never complete.
  //
  // If this happens the original "step over" request will be silently dropped. Otherwise, the
  // step queue will be recursively waiting for itself and can never continue. All other breakpoints
  // will still be waiting behind this failed step, but at least it could theoretically continue if
  // the breakpoint clearing works in a future try.
  void EnqueueStepOver(ProcessBreakpoint* process_breakpoint, DebuggedThread* thread);

  // Called by the currently stepping over breakpoint when it's done. It will execute the next
  // enqueued breakpoint. If there are no more breakpoints enqueued, this will let all the
  // breakpoints know so that it can resume the stepped over threads.
  void OnBreakpointFinishedSteppingOver();

  // Queue of breakpoints that are currently being stepped over.
  //
  // As stepping over requires suspending all the threads, doing multiple at a time has a fair
  // chance of introducing deadlocks. We use this queue to serialize the stepping over, so only
  // one process breakpoint is being stepped over at a time.
  struct StepOverTicket {
    fxl::WeakPtr<ProcessBreakpoint> process_breakpoint;
    fxl::WeakPtr<DebuggedThread> thread;

    bool is_valid() const { return !!process_breakpoint && !!thread; }
  };
  const std::deque<StepOverTicket>& step_over_queue() const { return step_over_queue_; }

  const std::map<uint64_t, std::unique_ptr<SoftwareBreakpoint>>& software_breakpoints() const {
    return software_breakpoints_;
  }

  const std::map<uint64_t, std::unique_ptr<HardwareBreakpoint>>& hardware_breakpoints() const {
    return hardware_breakpoints_;
  }

  const WatchpointMap& watchpoints() const { return watchpoints_; }

  bool from_limbo() const { return from_limbo_; }

 private:
  // ProcessHandleObserver implementation.
  void OnProcessTerminated() override;
  void OnThreadStarting(std::unique_ptr<ExceptionHandle> exception) override;
  void OnThreadExiting(std::unique_ptr<ExceptionHandle> exception) override;
  void OnException(std::unique_ptr<ExceptionHandle> exception) override;

  void OnStdout(bool close);
  void OnStderr(bool close);

  // Sends the currently loaded modules to the client with the current list of threads. This does
  // not refresh the module cache. All threads are assumed to be paused before this call.
  void SendModuleNotification();

  // Sends a IO notification over to the client.
  void SendIO(debug_ipc::NotifyIO::Type, const std::vector<char>& data);

  // This function will gracefully detach from the underlying zircon process.
  // Detaching correctly requires several steps:
  //
  // 1. Remove the installed breakpoints.
  //
  // 2. Resume threads from the exception. Only threads that are stopped on an
  // exception should be resumed. This is because otherwise zircon will treat
  // this exception as unhandled and will bubble up the exception upwards,
  // probably resulting in a crash.
  //
  // 3. Unbind the exception port.
  void DetachFromProcess();

  // Deletes any elements in the step over queue that are no longer valid. This happens when either
  // the thread or the breakpoint went away while the ticket was waiting within the queue.
  //
  // If the |thread| parameter is non-null, ALL requests from that thread will be deleted in
  // addition to the normal pruning behavior.
  void PruneStepOverQueue(DebuggedThread* optional_thread);

  // Attempts to load the debug_state_ value from the
  // ZX_PROP_PROCESS_DEBUG_ADDR of the debugged process. Returns true if it
  // is now set. False means it remains unset. Normally the first time this
  // returns true would need to be followed up with a SendModuleNotification.
  bool RegisterDebugState();

  debug::Status RegisterSoftwareBreakpoint(Breakpoint* bp, uint64_t address);
  void UnregisterSoftwareBreakpoint(Breakpoint* bp, uint64_t address);
  debug::Status RegisterHardwareBreakpoint(Breakpoint* bp, uint64_t address);
  void UnregisterHardwareBreakpoint(Breakpoint* bp, uint64_t address);

  DebugAgent* debug_agent_ = nullptr;  // Non-owning.

  std::unique_ptr<ProcessHandle> process_handle_;

  // Address in the debugged program of the dl_debug_state in ld.so.
  uint64_t dl_debug_addr_ = 0;

  // Current modules loaded in the process.
  ModuleList module_list_;

  // Breakpoint used to catch shared library loads. This will be set when the dl_debug_addr_ is
  // known.
  std::unique_ptr<Breakpoint> loader_breakpoint_;

  std::map<zx_koid_t, std::unique_ptr<DebuggedThread>> threads_;

  // Maps addresses to the ProcessBreakpoint at a location.
  std::map<uint64_t, std::unique_ptr<SoftwareBreakpoint>> software_breakpoints_;
  std::map<uint64_t, std::unique_ptr<HardwareBreakpoint>> hardware_breakpoints_;
  WatchpointMap watchpoints_;

  std::deque<StepOverTicket> step_over_queue_;

  // Non-null only if the corresponding stream is hooked up.
  std::unique_ptr<BufferedStdioHandle> stdout_;
  std::unique_ptr<BufferedStdioHandle> stderr_;

  // Whether this process was obtained from limbo or not. The agent will check this information
  // when it tries to kill this process in order to determine whether the ZX_ERR_BAD_ACCESS is
  // expected (limbo handles do not have ZX_RIGHT_DESTROY right) or it is an actual error.
  bool from_limbo_ = false;

  FXL_DISALLOW_COPY_AND_ASSIGN(DebuggedProcess);
};

}  // namespace debug_agent

#endif  // SRC_DEVELOPER_DEBUG_DEBUG_AGENT_DEBUGGED_PROCESS_H_
