v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
gdb-server-thread.cc
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
6
9#include "src/flags/flags.h"
10
11namespace v8 {
12namespace internal {
13namespace wasm {
14namespace gdb_server {
15
17 : Thread(v8::base::Thread::Options("GdbServerThread")),
18 gdb_server_(gdb_server),
19 start_semaphore_(0) {}
20
22 // Executed in the Isolate thread.
23 if (!Start()) {
24 return false;
25 }
26
27 // We need to make sure that {Stop} is never called before the thread has
28 // completely initialized {transport_} and {target_}. Otherwise there could be
29 // a race condition where in the main thread {Stop} might get called before
30 // the transport is created, and then in the GDBServer thread we may have time
31 // to setup the transport and block on accept() before the main thread blocks
32 // on joining the thread.
33 // The small performance hit caused by this Wait should be negligeable because
34 // this operation happensat most once per process and only when the
35 // --wasm-gdb-remote flag is set.
37 return !!target_;
38}
39
41 // Executed in the GdbServer thread.
43
44 target_ = nullptr;
45 transport_ = nullptr;
46
47#if _WIN32
48 ::WSACleanup();
49#endif
50}
51
53 // Executed in the GdbServer thread.
54#ifdef _WIN32
55 // Initialize Winsock
56 WSADATA wsaData;
57 int iResult = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
58 if (iResult != 0) {
59 TRACE_GDB_REMOTE("GdbServerThread::Run: WSAStartup failed\n");
60 return;
61 }
62#endif
63
64 // If the default port is not available, try any port.
65 SocketBinding socket_binding =
66 SocketBinding::Bind(v8_flags.wasm_gdb_remote_port);
67 if (!socket_binding.IsValid()) {
68 socket_binding = SocketBinding::Bind(0);
69 }
70 if (!socket_binding.IsValid()) {
71 TRACE_GDB_REMOTE("GdbServerThread::Run: Failed to bind any TCP port\n");
72 return;
73 }
74 TRACE_GDB_REMOTE("gdb-remote(%d) : Connect GDB with 'target remote :%d\n",
75 __LINE__, socket_binding.GetBoundPort());
76
77 transport_ = socket_binding.CreateTransport();
78 target_ = std::make_unique<Target>(gdb_server_);
79
80 // Here we have completed the initialization, and the thread that called
81 // {StartAndInitialize} may resume execution.
83
84 while (!target_->IsTerminated()) {
85 // Wait for incoming connections.
86 if (!transport_->AcceptConnection()) {
87 continue;
88 }
89
90 // Create a new session for this connection
91 Session session(transport_.get());
92 TRACE_GDB_REMOTE("GdbServerThread: Connected\n");
93
94 // Run this session for as long as it lasts
95 target_->Run(&session);
96 }
98}
99
101 // Executed in the Isolate thread.
102
103 // Synchronized, becauses {Stop} might be called while {Run} is still
104 // initializing {transport_} and {target_}. If this happens and the thread is
105 // blocked waiting for an incoming connection or GdbServer for incoming
106 // packets, it will unblocked when {transport_} is closed.
108
109 if (target_) {
110 target_->Terminate();
111 }
112
113 if (transport_) {
114 transport_->Close();
115 }
116}
117
118} // namespace gdb_server
119} // namespace wasm
120} // namespace internal
121} // namespace v8
V8_WARN_UNUSED_RESULT bool Start()
std::unique_ptr< TransportBase > transport_
static SocketBinding Bind(uint16_t tcp_port)
Definition transport.cc:22
std::unique_ptr< SocketTransport > CreateTransport()
Definition transport.cc:77
#define TRACE_GDB_REMOTE(...)
V8_EXPORT_PRIVATE FlagValues v8_flags
Definition c-api.cc:87