• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
13 namespace v8 {
14 namespace internal {
15 namespace wasm {
16 namespace gdb_server {
17 
18 class GdbServer;
19 class Packet;
20 class 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.
25 class 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();
IsTerminated()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;
GetCurrentIsolate()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