v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
gdb-server.h
Go to the documentation of this file.
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_GDB_SERVER_H_
6#define V8_DEBUG_WASM_GDB_SERVER_GDB_SERVER_H_
7
8#include <map>
9#include <memory>
12
13namespace v8 {
14namespace internal {
15namespace wasm {
16namespace gdb_server {
17
18class TaskRunner;
19
20// class GdbServer acts as a manager for the GDB-remote stub. It is instantiated
21// as soon as the first Wasm module is loaded in the Wasm engine and spawns a
22// separate thread to accept connections and exchange messages with a debugger.
23// It will contain the logic to serve debugger queries and access the state of
24// the Wasm engine.
25class GdbServer {
26 public:
27 GdbServer(const GdbServer&) = delete;
28 GdbServer& operator=(const GdbServer&) = delete;
29
30 // Factory method: creates and returns a GdbServer. Spawns a "GDB-remote"
31 // thread that will be used to communicate with the debugger.
32 // May return null on failure.
33 // This should be called once, the first time a Wasm module is loaded in the
34 // Wasm engine.
35 static std::unique_ptr<GdbServer> Create();
36
37 // Stops the "GDB-remote" thread and waits for it to complete. This should be
38 // called once, when the Wasm engine shuts down.
39 ~GdbServer();
40
41 // Queries the set of the Wasm modules currently loaded. Each module is
42 // identified by a unique integer module id.
44 uint32_t module_id;
45 std::string module_name;
46 };
47 std::vector<WasmModuleInfo> GetLoadedModules(
48 bool clear_module_list_changed_flag = false);
49
51
52 // Queries the value of the {index} global value in the Wasm module identified
53 // by {frame_index}.
54 //
55 bool GetWasmGlobal(uint32_t frame_index, uint32_t index, uint8_t* buffer,
56 uint32_t buffer_size, uint32_t* size);
57
58 // Queries the value of the {index} local value in the {frame_index}th stack
59 // frame in the Wasm module identified by {frame_index}.
60 //
61 bool GetWasmLocal(uint32_t frame_index, uint32_t index, uint8_t* buffer,
62 uint32_t buffer_size, uint32_t* size);
63
64 // Queries the value of the {index} value in the operand stack.
65 //
66 bool GetWasmStackValue(uint32_t frame_index, uint32_t index, uint8_t* buffer,
67 uint32_t buffer_size, uint32_t* size);
68
69 // Reads {size} bytes, starting from {offset}, from the Memory instance
70 // associated to the Wasm module identified by {module_id}.
71 // Returns the number of bytes copied to {buffer}, or 0 is case of error.
72 // Note: only one Memory for Module is currently supported.
73 //
74 uint32_t GetWasmMemory(uint32_t module_id, uint32_t offset, uint8_t* buffer,
75 uint32_t size);
76
77 // Reads {size} bytes, starting from {offset}, from the first Data segment
78 // in the Wasm module identified by {module_id}.
79 // Returns the number of bytes copied to {buffer}, or 0 is case of error.
80 // Note: only one Memory for Module is currently supported.
81 //
82 uint32_t GetWasmData(uint32_t module_id, uint32_t offset, uint8_t* buffer,
83 uint32_t size);
84
85 // Reads {size} bytes, starting from the low dword of {address}, from the Code
86 // space of th Wasm module identified by high dword of {address}.
87 // Returns the number of bytes copied to {buffer}, or 0 is case of error.
88 uint32_t GetWasmModuleBytes(wasm_addr_t address, uint8_t* buffer,
89 uint32_t size);
90
91 // Inserts a breakpoint at the offset {offset} of the Wasm module identified
92 // by {wasm_module_id}.
93 // Returns true if the breakpoint was successfully added.
94 bool AddBreakpoint(uint32_t wasm_module_id, uint32_t offset);
95
96 // Removes a breakpoint at the offset {offset} of the Wasm module identified
97 // by {wasm_module_id}.
98 // Returns true if the breakpoint was successfully removed.
99 bool RemoveBreakpoint(uint32_t wasm_module_id, uint32_t offset);
100
101 // Returns the current call stack as a vector of program counters.
102 std::vector<wasm_addr_t> GetWasmCallStack() const;
103
104 // Manage the set of Isolates for this GdbServer.
105 void AddIsolate(Isolate* isolate);
106 void RemoveIsolate(Isolate* isolate);
107
108 // Requests that the thread suspend execution at the next Wasm instruction.
109 void Suspend();
110
111 // Handle stepping in wasm functions via the wasm interpreter.
112 void PrepareStep();
113
114 // Called when the target debuggee can resume execution (for example after
115 // having been suspended on a breakpoint). Terminates the task runner leaving
116 // all pending tasks in the queue.
118
119 private:
120 GdbServer();
121
122 // When the target debuggee is suspended for a breakpoint or exception, blocks
123 // the main (isolate) thread and enters in a message loop. Here it waits on a
124 // queue of Task objects that are posted by the GDB-stub thread and that
125 // represent queries received from the debugger via the GDB-remote protocol.
127
128 // Post a task to run a callback in the isolate thread.
129 template <typename Callback>
130 auto RunSyncTask(Callback&& callback) const;
131
132 void AddWasmModule(uint32_t module_id, Local<debug::WasmScript> wasm_script);
133
134 // Given a Wasm module id, retrieves the corresponding debugging WasmScript
135 // object.
136 bool GetModuleDebugHandler(uint32_t module_id,
137 WasmModuleDebug** wasm_module_debug);
138
139 // Returns the debugging target.
140 Target& GetTarget() const;
141
142 // Class DebugDelegate implements the debug::DebugDelegate interface to
143 // receive notifications when debug events happen in a given isolate, like a
144 // script being loaded, a breakpoint being hit, an exception being thrown.
146 public:
147 DebugDelegate(Isolate* isolate, GdbServer* gdb_server);
149
150 // debug::DebugDelegate
151 void ScriptCompiled(Local<debug::Script> script, bool is_live_edited,
152 bool has_compile_error) override;
154 Local<v8::Context> paused_context,
155 const std::vector<debug::BreakpointId>& inspector_break_points_hit,
156 v8::debug::BreakReasons break_reasons) override;
157 void ExceptionThrown(Local<v8::Context> paused_context,
158 Local<Value> exception, Local<Value> promise,
159 bool is_uncaught,
160 debug::ExceptionType exception_type) override;
162 const debug::Location& start,
163 const debug::Location& end) override;
164
165 private:
166 // Calculates module_id as:
167 // +--------------------+------------------- +
168 // | DebugDelegate::id_ | Script::Id() |
169 // +--------------------+------------------- +
170 // <----- 16 bit -----> <----- 16 bit ----->
171 uint32_t GetModuleId(uint32_t script_id) const {
172 DCHECK_LT(script_id, 0x10000);
173 DCHECK_LT(id_, 0x10000);
174 return id_ << 16 | script_id;
175 }
176
178 uint32_t id_;
180
181 static std::atomic<uint32_t> id_s;
182 };
183
184 // The GDB-stub thread where all the communication with the debugger happens.
185 std::unique_ptr<GdbServerThread> thread_;
186
187 // Used to transform the queries that arrive in the GDB-stub thread into
188 // tasks executed in the main (isolate) thread.
189 std::unique_ptr<TaskRunner> task_runner_;
190
191 std::atomic<bool> has_module_list_changed_;
192
194 // Always accessed in the isolate thread.
195
196 // Set of breakpoints currently defines in Wasm code.
197 typedef std::map<uint64_t, int> BreakpointsMap;
199
200 typedef std::map<uint32_t, WasmModuleDebug> ScriptsMap;
202
203 typedef std::map<Isolate*, std::unique_ptr<DebugDelegate>>
206
207 // End of fields always accessed in the isolate thread.
209};
210
211} // namespace gdb_server
212} // namespace wasm
213} // namespace internal
214} // namespace v8
215
216#endif // V8_DEBUG_WASM_GDB_SERVER_GDB_SERVER_H_
DebugDelegate(Isolate *isolate, GdbServer *gdb_server)
void ScriptCompiled(Local< debug::Script > script, bool is_live_edited, bool has_compile_error) override
bool IsFunctionBlackboxed(Local< debug::Script > script, const debug::Location &start, const debug::Location &end) override
void ExceptionThrown(Local< v8::Context > paused_context, Local< Value > exception, Local< Value > promise, bool is_uncaught, debug::ExceptionType exception_type) override
uint32_t GetModuleId(uint32_t script_id) const
Definition gdb-server.h:171
void BreakProgramRequested(Local< v8::Context > paused_context, const std::vector< debug::BreakpointId > &inspector_break_points_hit, v8::debug::BreakReasons break_reasons) override
IsolateDebugDelegateMap isolate_delegates_
Definition gdb-server.h:205
bool GetWasmLocal(uint32_t frame_index, uint32_t index, uint8_t *buffer, uint32_t buffer_size, uint32_t *size)
std::unique_ptr< TaskRunner > task_runner_
Definition gdb-server.h:189
bool AddBreakpoint(uint32_t wasm_module_id, uint32_t offset)
GdbServer(const GdbServer &)=delete
std::unique_ptr< GdbServerThread > thread_
Definition gdb-server.h:185
uint32_t GetWasmModuleBytes(wasm_addr_t address, uint8_t *buffer, uint32_t size)
uint32_t GetWasmData(uint32_t module_id, uint32_t offset, uint8_t *buffer, uint32_t size)
bool GetModuleDebugHandler(uint32_t module_id, WasmModuleDebug **wasm_module_debug)
std::vector< WasmModuleInfo > GetLoadedModules(bool clear_module_list_changed_flag=false)
bool GetWasmStackValue(uint32_t frame_index, uint32_t index, uint8_t *buffer, uint32_t buffer_size, uint32_t *size)
std::vector< wasm_addr_t > GetWasmCallStack() const
auto RunSyncTask(Callback &&callback) const
uint32_t GetWasmMemory(uint32_t module_id, uint32_t offset, uint8_t *buffer, uint32_t size)
std::map< uint32_t, WasmModuleDebug > ScriptsMap
Definition gdb-server.h:200
std::map< uint64_t, int > BreakpointsMap
Definition gdb-server.h:197
bool GetWasmGlobal(uint32_t frame_index, uint32_t index, uint8_t *buffer, uint32_t buffer_size, uint32_t *size)
bool RemoveBreakpoint(uint32_t wasm_module_id, uint32_t offset)
static std::unique_ptr< GdbServer > Create()
GdbServer & operator=(const GdbServer &)=delete
std::map< Isolate *, std::unique_ptr< DebugDelegate > > IsolateDebugDelegateMap
Definition gdb-server.h:204
void AddWasmModule(uint32_t module_id, Local< debug::WasmScript > wasm_script)
int start
int end
int32_t offset
TNode< Object > callback
v8::TaskRunner TaskRunner
Definition platform.h:25
Definition c-api.cc:87
#define DCHECK_LT(v1, v2)
Definition logging.h:489