11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_DEBUG_WASM_GDB_SERVER_TARGET_H_ 61cb0ef41Sopenharmony_ci#define V8_DEBUG_WASM_GDB_SERVER_TARGET_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <atomic> 91cb0ef41Sopenharmony_ci#include <map> 101cb0ef41Sopenharmony_ci#include "src/base/macros.h" 111cb0ef41Sopenharmony_ci#include "src/debug/wasm/gdb-server/gdb-remote-util.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace v8 { 141cb0ef41Sopenharmony_cinamespace internal { 151cb0ef41Sopenharmony_cinamespace wasm { 161cb0ef41Sopenharmony_cinamespace gdb_server { 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciclass GdbServer; 191cb0ef41Sopenharmony_ciclass Packet; 201cb0ef41Sopenharmony_ciclass Session; 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci// Class Target represents a debugging target. It contains the logic to decode 231cb0ef41Sopenharmony_ci// incoming GDB-remote packets, execute them forwarding the debugger commands 241cb0ef41Sopenharmony_ci// and queries to the Wasm engine, and send back GDB-remote packets. 251cb0ef41Sopenharmony_ciclass Target { 261cb0ef41Sopenharmony_ci public: 271cb0ef41Sopenharmony_ci // Contruct a Target object. 281cb0ef41Sopenharmony_ci explicit Target(GdbServer* gdb_server); 291cb0ef41Sopenharmony_ci Target(const Target&) = delete; 301cb0ef41Sopenharmony_ci Target& operator=(const Target&) = delete; 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci // This function spin on a debugging session, until it closes. 331cb0ef41Sopenharmony_ci void Run(Session* ses); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci void Terminate(); 361cb0ef41Sopenharmony_ci bool IsTerminated() const { return status_ == Status::Terminated; } 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci // Notifies that the debuggee thread suspended at a breakpoint. 391cb0ef41Sopenharmony_ci void OnProgramBreak(Isolate* isolate, 401cb0ef41Sopenharmony_ci const std::vector<wasm_addr_t>& call_frames); 411cb0ef41Sopenharmony_ci // Notifies that the debuggee thread suspended because of an unhandled 421cb0ef41Sopenharmony_ci // exception. 431cb0ef41Sopenharmony_ci void OnException(Isolate* isolate, 441cb0ef41Sopenharmony_ci const std::vector<wasm_addr_t>& call_frames); 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci // Returns the state at the moment of the thread suspension. 471cb0ef41Sopenharmony_ci const std::vector<wasm_addr_t> GetCallStack() const; 481cb0ef41Sopenharmony_ci wasm_addr_t GetCurrentPc() const; 491cb0ef41Sopenharmony_ci Isolate* GetCurrentIsolate() const { return current_isolate_; } 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci private: 521cb0ef41Sopenharmony_ci void OnSuspended(Isolate* isolate, int signal, 531cb0ef41Sopenharmony_ci const std::vector<wasm_addr_t>& call_frames); 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci // Initializes a map used to make fast lookups when handling query packets 561cb0ef41Sopenharmony_ci // that have a constant response. 571cb0ef41Sopenharmony_ci void InitQueryPropertyMap(); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci // Blocks waiting for one of these two events to occur: 601cb0ef41Sopenharmony_ci // - A network packet arrives from the debugger, or the debugger connection is 611cb0ef41Sopenharmony_ci // closed; 621cb0ef41Sopenharmony_ci // - The debuggee suspends execution because of a trap or breakpoint. 631cb0ef41Sopenharmony_ci void WaitForDebugEvent(); 641cb0ef41Sopenharmony_ci void ProcessDebugEvent(); 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci // Processes GDB-remote packets that arrive from the debugger. 671cb0ef41Sopenharmony_ci // This method should be called when the debuggee has suspended its execution. 681cb0ef41Sopenharmony_ci void ProcessCommands(); 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci // Requests that the thread suspends execution at the next Wasm instruction. 711cb0ef41Sopenharmony_ci void Suspend(); 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci enum class ErrorCode { None = 0, BadFormat = 1, BadArgs = 2, Failed = 3 }; 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci enum class ProcessPacketResult { 761cb0ef41Sopenharmony_ci Paused, // The command was processed, debuggee still paused. 771cb0ef41Sopenharmony_ci Continue, // The debuggee should resume execution. 781cb0ef41Sopenharmony_ci Detach, // Request to detach from the debugger. 791cb0ef41Sopenharmony_ci Kill // Request to terminate the debuggee process. 801cb0ef41Sopenharmony_ci }; 811cb0ef41Sopenharmony_ci // This function always succeedes, since all errors are reported as an error 821cb0ef41Sopenharmony_ci // string "Exx" where xx is a two digit number. 831cb0ef41Sopenharmony_ci // The return value indicates if the target can resume execution or it is 841cb0ef41Sopenharmony_ci // still paused. 851cb0ef41Sopenharmony_ci ProcessPacketResult ProcessPacket(Packet* pkt_in, Packet* pkt_out); 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci // Processes a general query packet 881cb0ef41Sopenharmony_ci ErrorCode ProcessQueryPacket(const Packet* pkt_in, Packet* pkt_out); 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci // Formats a 'Stop-reply' packet, which is sent in response of a 'c' 911cb0ef41Sopenharmony_ci // (continue), 's' (step) and '?' (query halt reason) commands. 921cb0ef41Sopenharmony_ci void SetStopReply(Packet* pkt_out) const; 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci enum class Status { Running, WaitingForSuspension, Suspended, Terminated }; 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci void SetStatus(Status status, int8_t signal = 0, 971cb0ef41Sopenharmony_ci std::vector<wasm_addr_t> call_frames_ = {}, 981cb0ef41Sopenharmony_ci Isolate* isolate = nullptr); 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci GdbServer* gdb_server_; 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci std::atomic<Status> status_; 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci // Signal being processed. 1051cb0ef41Sopenharmony_ci std::atomic<int8_t> cur_signal_; 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci // Session object not owned by the Target. 1081cb0ef41Sopenharmony_ci Session* session_; 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci // Map used to make fast lookups when handling query packets. 1111cb0ef41Sopenharmony_ci typedef std::map<std::string, std::string> QueryPropertyMap; 1121cb0ef41Sopenharmony_ci QueryPropertyMap query_properties_; 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci bool debugger_initial_suspension_; 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci // Used to block waiting for suspension 1171cb0ef41Sopenharmony_ci v8::base::Semaphore semaphore_; 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci mutable v8::base::Mutex mutex_; 1201cb0ef41Sopenharmony_ci ////////////////////////////////////////////////////////////////////////////// 1211cb0ef41Sopenharmony_ci // Protected by {mutex_}: 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci // Current isolate. This is not null only when the target is in a Suspended 1241cb0ef41Sopenharmony_ci // state and it is the isolate associated to the current call stack and used 1251cb0ef41Sopenharmony_ci // for all debugging activities. 1261cb0ef41Sopenharmony_ci Isolate* current_isolate_; 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci // Call stack when the execution is suspended. 1291cb0ef41Sopenharmony_ci std::vector<wasm_addr_t> call_frames_; 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci // End of fields protected by {mutex_}. 1321cb0ef41Sopenharmony_ci ////////////////////////////////////////////////////////////////////////////// 1331cb0ef41Sopenharmony_ci}; 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci} // namespace gdb_server 1361cb0ef41Sopenharmony_ci} // namespace wasm 1371cb0ef41Sopenharmony_ci} // namespace internal 1381cb0ef41Sopenharmony_ci} // namespace v8 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci#endif // V8_DEBUG_WASM_GDB_SERVER_TARGET_H_ 141