target.h 4.76 KB
Newer Older
1 2 3 4 5 6 7 8
// Copyright 2020 the V8 project 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 V8_DEBUG_WASM_GDB_SERVER_TARGET_H_
#define V8_DEBUG_WASM_GDB_SERVER_TARGET_H_

#include <atomic>
9
#include <map>
10
#include "src/base/macros.h"
11
#include "src/debug/wasm/gdb-server/gdb-remote-util.h"
12 13 14 15 16 17 18

namespace v8 {
namespace internal {
namespace wasm {
namespace gdb_server {

class GdbServer;
19
class Packet;
20 21 22 23 24 25 26 27 28
class Session;

// Class Target represents a debugging target. It contains the logic to decode
// incoming GDB-remote packets, execute them forwarding the debugger commands
// and queries to the Wasm engine, and send back GDB-remote packets.
class Target {
 public:
  // Contruct a Target object.
  explicit Target(GdbServer* gdb_server);
29 30
  Target(const Target&) = delete;
  Target& operator=(const Target&) = delete;
31 32 33 34 35 36 37

  // This function spin on a debugging session, until it closes.
  void Run(Session* ses);

  void Terminate();
  bool IsTerminated() const { return status_ == Status::Terminated; }

38 39 40 41 42 43 44 45 46 47 48 49 50
  // Notifies that the debuggee thread suspended at a breakpoint.
  void OnProgramBreak(Isolate* isolate,
                      const std::vector<wasm_addr_t>& call_frames);
  // Notifies that the debuggee thread suspended because of an unhandled
  // exception.
  void OnException(Isolate* isolate,
                   const std::vector<wasm_addr_t>& call_frames);

  // Returns the state at the moment of the thread suspension.
  const std::vector<wasm_addr_t> GetCallStack() const;
  wasm_addr_t GetCurrentPc() const;
  Isolate* GetCurrentIsolate() const { return current_isolate_; }

51
 private:
52 53 54
  void OnSuspended(Isolate* isolate, int signal,
                   const std::vector<wasm_addr_t>& call_frames);

55 56 57 58
  // Initializes a map used to make fast lookups when handling query packets
  // that have a constant response.
  void InitQueryPropertyMap();

59 60 61 62 63
  // Blocks waiting for one of these two events to occur:
  // - A network packet arrives from the debugger, or the debugger connection is
  //   closed;
  // - The debuggee suspends execution because of a trap or breakpoint.
  void WaitForDebugEvent();
64
  void ProcessDebugEvent();
65 66 67 68 69

  // Processes GDB-remote packets that arrive from the debugger.
  // This method should be called when the debuggee has suspended its execution.
  void ProcessCommands();

70 71 72
  // Requests that the thread suspends execution at the next Wasm instruction.
  void Suspend();

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
  enum class ErrorCode { None = 0, BadFormat = 1, BadArgs = 2, Failed = 3 };

  enum class ProcessPacketResult {
    Paused,    // The command was processed, debuggee still paused.
    Continue,  // The debuggee should resume execution.
    Detach,    // Request to detach from the debugger.
    Kill       // Request to terminate the debuggee process.
  };
  // This function always succeedes, since all errors are reported as an error
  // string "Exx" where xx is a two digit number.
  // The return value indicates if the target can resume execution or it is
  // still paused.
  ProcessPacketResult ProcessPacket(Packet* pkt_in, Packet* pkt_out);

  // Processes a general query packet
  ErrorCode ProcessQueryPacket(const Packet* pkt_in, Packet* pkt_out);

  // Formats a 'Stop-reply' packet, which is sent in response of a 'c'
  // (continue), 's' (step) and '?' (query halt reason) commands.
  void SetStopReply(Packet* pkt_out) const;

94 95 96 97 98
  enum class Status { Running, WaitingForSuspension, Suspended, Terminated };

  void SetStatus(Status status, int8_t signal = 0,
                 std::vector<wasm_addr_t> call_frames_ = {},
                 Isolate* isolate = nullptr);
99 100

  GdbServer* gdb_server_;
101

102 103
  std::atomic<Status> status_;

104
  // Signal being processed.
105
  std::atomic<int8_t> cur_signal_;
106

107 108
  // Session object not owned by the Target.
  Session* session_;
109

110 111 112 113
  // Map used to make fast lookups when handling query packets.
  typedef std::map<std::string, std::string> QueryPropertyMap;
  QueryPropertyMap query_properties_;

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
  bool debugger_initial_suspension_;

  // Used to block waiting for suspension
  v8::base::Semaphore semaphore_;

  mutable v8::base::Mutex mutex_;
  //////////////////////////////////////////////////////////////////////////////
  // Protected by {mutex_}:

  // Current isolate. This is not null only when the target is in a Suspended
  // state and it is the isolate associated to the current call stack and used
  // for all debugging activities.
  Isolate* current_isolate_;

  // Call stack when the execution is suspended.
  std::vector<wasm_addr_t> call_frames_;

  // End of fields protected by {mutex_}.
  //////////////////////////////////////////////////////////////////////////////
133 134 135 136 137 138 139 140
};

}  // namespace gdb_server
}  // namespace wasm
}  // namespace internal
}  // namespace v8

#endif  // V8_DEBUG_WASM_GDB_SERVER_TARGET_H_