1// Copyright 2020 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef V8_DEBUG_WASM_GDB_SERVER_TARGET_H_ 6#define V8_DEBUG_WASM_GDB_SERVER_TARGET_H_ 7 8#include <atomic> 9#include <map> 10#include "src/base/macros.h" 11#include "src/debug/wasm/gdb-server/gdb-remote-util.h" 12 13namespace v8 { 14namespace internal { 15namespace wasm { 16namespace gdb_server { 17 18class GdbServer; 19class Packet; 20class Session; 21 22// Class Target represents a debugging target. It contains the logic to decode 23// incoming GDB-remote packets, execute them forwarding the debugger commands 24// and queries to the Wasm engine, and send back GDB-remote packets. 25class Target { 26 public: 27 // Contruct a Target object. 28 explicit Target(GdbServer* gdb_server); 29 Target(const Target&) = delete; 30 Target& operator=(const Target&) = delete; 31 32 // This function spin on a debugging session, until it closes. 33 void Run(Session* ses); 34 35 void Terminate(); 36 bool IsTerminated() const { return status_ == Status::Terminated; } 37 38 // Notifies that the debuggee thread suspended at a breakpoint. 39 void OnProgramBreak(Isolate* isolate, 40 const std::vector<wasm_addr_t>& call_frames); 41 // Notifies that the debuggee thread suspended because of an unhandled 42 // exception. 43 void OnException(Isolate* isolate, 44 const std::vector<wasm_addr_t>& call_frames); 45 46 // Returns the state at the moment of the thread suspension. 47 const std::vector<wasm_addr_t> GetCallStack() const; 48 wasm_addr_t GetCurrentPc() const; 49 Isolate* GetCurrentIsolate() const { return current_isolate_; } 50 51 private: 52 void OnSuspended(Isolate* isolate, int signal, 53 const std::vector<wasm_addr_t>& call_frames); 54 55 // Initializes a map used to make fast lookups when handling query packets 56 // that have a constant response. 57 void InitQueryPropertyMap(); 58 59 // Blocks waiting for one of these two events to occur: 60 // - A network packet arrives from the debugger, or the debugger connection is 61 // closed; 62 // - The debuggee suspends execution because of a trap or breakpoint. 63 void WaitForDebugEvent(); 64 void ProcessDebugEvent(); 65 66 // Processes GDB-remote packets that arrive from the debugger. 67 // This method should be called when the debuggee has suspended its execution. 68 void ProcessCommands(); 69 70 // Requests that the thread suspends execution at the next Wasm instruction. 71 void Suspend(); 72 73 enum class ErrorCode { None = 0, BadFormat = 1, BadArgs = 2, Failed = 3 }; 74 75 enum class ProcessPacketResult { 76 Paused, // The command was processed, debuggee still paused. 77 Continue, // The debuggee should resume execution. 78 Detach, // Request to detach from the debugger. 79 Kill // Request to terminate the debuggee process. 80 }; 81 // This function always succeedes, since all errors are reported as an error 82 // string "Exx" where xx is a two digit number. 83 // The return value indicates if the target can resume execution or it is 84 // still paused. 85 ProcessPacketResult ProcessPacket(Packet* pkt_in, Packet* pkt_out); 86 87 // Processes a general query packet 88 ErrorCode ProcessQueryPacket(const Packet* pkt_in, Packet* pkt_out); 89 90 // Formats a 'Stop-reply' packet, which is sent in response of a 'c' 91 // (continue), 's' (step) and '?' (query halt reason) commands. 92 void SetStopReply(Packet* pkt_out) const; 93 94 enum class Status { Running, WaitingForSuspension, Suspended, Terminated }; 95 96 void SetStatus(Status status, int8_t signal = 0, 97 std::vector<wasm_addr_t> call_frames_ = {}, 98 Isolate* isolate = nullptr); 99 100 GdbServer* gdb_server_; 101 102 std::atomic<Status> status_; 103 104 // Signal being processed. 105 std::atomic<int8_t> cur_signal_; 106 107 // Session object not owned by the Target. 108 Session* session_; 109 110 // Map used to make fast lookups when handling query packets. 111 typedef std::map<std::string, std::string> QueryPropertyMap; 112 QueryPropertyMap query_properties_; 113 114 bool debugger_initial_suspension_; 115 116 // Used to block waiting for suspension 117 v8::base::Semaphore semaphore_; 118 119 mutable v8::base::Mutex mutex_; 120 ////////////////////////////////////////////////////////////////////////////// 121 // Protected by {mutex_}: 122 123 // Current isolate. This is not null only when the target is in a Suspended 124 // state and it is the isolate associated to the current call stack and used 125 // for all debugging activities. 126 Isolate* current_isolate_; 127 128 // Call stack when the execution is suspended. 129 std::vector<wasm_addr_t> call_frames_; 130 131 // End of fields protected by {mutex_}. 132 ////////////////////////////////////////////////////////////////////////////// 133}; 134 135} // namespace gdb_server 136} // namespace wasm 137} // namespace internal 138} // namespace v8 139 140#endif // V8_DEBUG_WASM_GDB_SERVER_TARGET_H_ 141