blob: b92a7dec0e8125ce567cef3b5c2d3a48df168220 [file] [log] [blame]
Dan Albertdb6fe642015-03-19 15:21:08 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Josh Gao9eaf33c2016-05-13 15:28:34 -070017#if !ADB_HOST
Dan Albertdb6fe642015-03-19 15:21:08 -070018
Yabin Cui19bec5b2015-09-22 15:52:57 -070019#define TRACE_TAG JDWP
Dan Albertdb6fe642015-03-19 15:21:08 -070020
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080021#include "sysdeps.h"
Dan Albertdb6fe642015-03-19 15:21:08 -070022
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080023#include <errno.h>
24#include <stdio.h>
Elliott Hughes43df1092015-07-23 17:12:58 -070025#include <stdlib.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080026#include <string.h>
Josh Gao9eaf33c2016-05-13 15:28:34 -070027#include <sys/socket.h>
28#include <sys/un.h>
Teddie Stenvif56e7f52010-02-15 12:20:44 +010029#include <unistd.h>
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080030
Josh Gao9eaf33c2016-05-13 15:28:34 -070031#include <list>
32#include <memory>
Josh Gaoeb5e6052019-06-19 14:14:57 -070033#include <thread>
Josh Gao9eaf33c2016-05-13 15:28:34 -070034#include <vector>
35
Josh Gaoeb5e6052019-06-19 14:14:57 -070036#include <adbconnection/server.h>
Josh Gao2d83b542019-01-10 14:29:29 -080037#include <android-base/cmsg.h>
Josh Gaoeb5e6052019-06-19 14:14:57 -070038#include <android-base/unique_fd.h>
Josh Gao2d83b542019-01-10 14:29:29 -080039
Dan Albertdb6fe642015-03-19 15:21:08 -070040#include "adb.h"
Josh Gao9eaf33c2016-05-13 15:28:34 -070041#include "adb_io.h"
Josh Gaoea7457b2016-08-30 15:39:25 -070042#include "adb_unique_fd.h"
Yabin Cui5fc22312015-10-06 15:10:05 -070043#include "adb_utils.h"
Dan Albertdb6fe642015-03-19 15:21:08 -070044
Josh Gaoeb5e6052019-06-19 14:14:57 -070045using android::base::borrowed_fd;
46using android::base::unique_fd;
47
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080048/* here's how these things work.
49
50 when adbd starts, it creates a unix server socket
Josh Gao9eaf33c2016-05-13 15:28:34 -070051 named @jdwp-control (@ is a shortcut for "first byte is zero"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080052 to use the private namespace instead of the file system)
53
54 when a new JDWP daemon thread starts in a new VM process, it creates
Josh Gao9eaf33c2016-05-13 15:28:34 -070055 a connection to @jdwp-control to announce its availability.
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080056
57
Josh Gao9eaf33c2016-05-13 15:28:34 -070058 JDWP thread @jdwp-control
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080059 | |
60 |-------------------------------> |
61 | hello I'm in process <pid> |
62 | |
63 | |
64
65 the connection is kept alive. it will be closed automatically if
66 the JDWP process terminates (this allows adbd to detect dead
67 processes).
68
69 adbd thus maintains a list of "active" JDWP processes. it can send
70 its content to clients through the "device:debug-ports" service,
71 or even updates through the "device:track-debug-ports" service.
72
73 when a debugger wants to connect, it simply runs the command
74 equivalent to "adb forward tcp:<hostport> jdwp:<pid>"
75
76 "jdwp:<pid>" is a new forward destination format used to target
77 a given JDWP process on the device. when sutch a request arrives,
78 adbd does the following:
79
80 - first, it calls socketpair() to create a pair of equivalent
81 sockets.
82
83 - it attaches the first socket in the pair to a local socket
84 which is itself attached to the transport's remote socket:
85
86
87 - it sends the file descriptor of the second socket directly
88 to the JDWP process with the help of sendmsg()
89
90
Josh Gao9eaf33c2016-05-13 15:28:34 -070091 JDWP thread @jdwp-control
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080092 | |
93 | <----------------------|
94 | OK, try this file descriptor |
95 | |
96 | |
97
98 then, the JDWP thread uses this new socket descriptor as its
99 pass-through connection to the debugger (and receives the
100 JDWP-Handshake message, answers to it, etc...)
101
102 this gives the following graphics:
103 ____________________________________
104 | |
105 | ADB Server (host) |
106 | |
107 Debugger <---> LocalSocket <----> RemoteSocket |
108 | ^^ |
109 |___________________________||_______|
110 ||
111 Transport ||
112 (TCP for emulator - USB for device) ||
113 ||
114 ___________________________||_______
115 | || |
116 | ADBD (device) || |
117 | VV |
118 JDWP <======> LocalSocket <----> RemoteSocket |
119 | |
120 |____________________________________|
121
122 due to the way adb works, this doesn't need a special socket
123 type or fancy handling of socket termination if either the debugger
124 or the JDWP process closes the connection.
125
126 THIS IS THE SIMPLEST IMPLEMENTATION I COULD FIND, IF YOU HAPPEN
127 TO HAVE A BETTER IDEA, LET ME KNOW - Digit
128
129**********************************************************************/
130
131/** JDWP PID List Support Code
132 ** for each JDWP process, we record its pid and its connected socket
133 **/
134
Josh Gao9eaf33c2016-05-13 15:28:34 -0700135static void jdwp_process_event(int socket, unsigned events, void* _proc);
136static void jdwp_process_list_updated(void);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800137
Josh Gao9eaf33c2016-05-13 15:28:34 -0700138struct JdwpProcess;
Josh Gao361148b2018-01-02 12:01:43 -0800139static auto& _jdwp_list = *new std::list<std::unique_ptr<JdwpProcess>>();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800140
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800141struct JdwpProcess {
Josh Gaoeb5e6052019-06-19 14:14:57 -0700142 JdwpProcess(unique_fd socket, pid_t pid) {
143 CHECK(pid != 0);
144
Josh Gao9eaf33c2016-05-13 15:28:34 -0700145 this->socket = socket;
Josh Gaoeb5e6052019-06-19 14:14:57 -0700146 this->pid = pid;
147 this->fde = fdevent_create(socket.release(), jdwp_process_event, this);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800148
Josh Gao9eaf33c2016-05-13 15:28:34 -0700149 if (!this->fde) {
Elliott Hughese64126b2018-10-19 13:59:44 -0700150 LOG(FATAL) << "could not create fdevent for new JDWP process";
Josh Gao9eaf33c2016-05-13 15:28:34 -0700151 }
Josh Gao9eaf33c2016-05-13 15:28:34 -0700152 }
153
154 ~JdwpProcess() {
155 if (this->socket >= 0) {
156 adb_shutdown(this->socket);
Josh Gao9eaf33c2016-05-13 15:28:34 -0700157 this->socket = -1;
158 }
159
160 if (this->fde) {
161 fdevent_destroy(this->fde);
162 this->fde = nullptr;
163 }
164
165 out_fds.clear();
166 }
167
168 void RemoveFromList() {
Josh Gao9eaf33c2016-05-13 15:28:34 -0700169 auto pred = [this](const auto& proc) { return proc.get() == this; };
170 _jdwp_list.remove_if(pred);
171 }
172
Josh Gaoeb5e6052019-06-19 14:14:57 -0700173 borrowed_fd socket = -1;
Josh Gao03e4ab22018-02-12 15:05:05 -0800174 int32_t pid = -1;
Josh Gao9eaf33c2016-05-13 15:28:34 -0700175 fdevent* fde = nullptr;
176
177 std::vector<unique_fd> out_fds;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800178};
179
Josh Gao9eaf33c2016-05-13 15:28:34 -0700180static size_t jdwp_process_list(char* buffer, size_t bufferlen) {
181 std::string temp;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800182
Josh Gao9eaf33c2016-05-13 15:28:34 -0700183 for (auto& proc : _jdwp_list) {
Josh Gao9eaf33c2016-05-13 15:28:34 -0700184 std::string next = std::to_string(proc->pid) + "\n";
185 if (temp.length() + next.length() > bufferlen) {
186 D("truncating JDWP process list (max len = %zu)", bufferlen);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800187 break;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800188 }
Josh Gao9eaf33c2016-05-13 15:28:34 -0700189 temp.append(next);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800190 }
Josh Gao9eaf33c2016-05-13 15:28:34 -0700191
192 memcpy(buffer, temp.data(), temp.length());
193 return temp.length();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800194}
195
Josh Gao9eaf33c2016-05-13 15:28:34 -0700196static size_t jdwp_process_list_msg(char* buffer, size_t bufferlen) {
197 // Message is length-prefixed with 4 hex digits in ASCII.
198 static constexpr size_t header_len = 4;
199 if (bufferlen < header_len) {
Elliott Hughese64126b2018-10-19 13:59:44 -0700200 LOG(FATAL) << "invalid JDWP process list buffer size: " << bufferlen;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800201 }
202
Josh Gao9eaf33c2016-05-13 15:28:34 -0700203 char head[header_len + 1];
204 size_t len = jdwp_process_list(buffer + header_len, bufferlen - header_len);
205 snprintf(head, sizeof head, "%04zx", len);
206 memcpy(buffer, head, header_len);
207 return len + header_len;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800208}
209
Josh Gao9eaf33c2016-05-13 15:28:34 -0700210static void jdwp_process_event(int socket, unsigned events, void* _proc) {
211 JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(_proc);
Josh Gaoeb5e6052019-06-19 14:14:57 -0700212 CHECK_EQ(socket, proc->socket.get());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800213
214 if (events & FDE_READ) {
Josh Gaoeb5e6052019-06-19 14:14:57 -0700215 // We already have the PID, if we can read from the socket, we've probably hit EOF.
216 D("terminating JDWP connection %d", proc->pid);
217 goto CloseProcess;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800218 }
219
220 if (events & FDE_WRITE) {
Josh Gao9eaf33c2016-05-13 15:28:34 -0700221 D("trying to send fd to JDWP process (count = %zu)", proc->out_fds.size());
Josh Gaocc1dcc82018-10-05 17:09:41 -0700222 CHECK(!proc->out_fds.empty());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800223
Josh Gaocc1dcc82018-10-05 17:09:41 -0700224 int fd = proc->out_fds.back().get();
Josh Gao2d83b542019-01-10 14:29:29 -0800225 if (android::base::SendFileDescriptors(socket, "", 1, fd) != 1) {
Josh Gaocc1dcc82018-10-05 17:09:41 -0700226 D("sending new file descriptor to JDWP %d failed: %s", proc->pid, strerror(errno));
227 goto CloseProcess;
228 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800229
Josh Gaocc1dcc82018-10-05 17:09:41 -0700230 D("sent file descriptor %d to JDWP process %d", fd, proc->pid);
Josh Gao9eaf33c2016-05-13 15:28:34 -0700231
Josh Gaocc1dcc82018-10-05 17:09:41 -0700232 proc->out_fds.pop_back();
233 if (proc->out_fds.empty()) {
234 fdevent_del(proc->fde, FDE_WRITE);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800235 }
236 }
Josh Gao9eaf33c2016-05-13 15:28:34 -0700237
238 return;
239
240CloseProcess:
241 proc->RemoveFromList();
242 jdwp_process_list_updated();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800243}
244
Josh Gao5607e922018-07-25 18:15:52 -0700245unique_fd create_jdwp_connection_fd(int pid) {
Yabin Cui815ad882015-09-02 17:44:28 -0700246 D("looking for pid %d in JDWP process list", pid);
Josh Gao9eaf33c2016-05-13 15:28:34 -0700247
248 for (auto& proc : _jdwp_list) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800249 if (proc->pid == pid) {
Josh Gao9eaf33c2016-05-13 15:28:34 -0700250 int fds[2];
251
252 if (adb_socketpair(fds) < 0) {
253 D("%s: socket pair creation failed: %s", __FUNCTION__, strerror(errno));
Josh Gao5607e922018-07-25 18:15:52 -0700254 return unique_fd{};
Josh Gao9eaf33c2016-05-13 15:28:34 -0700255 }
256 D("socketpair: (%d,%d)", fds[0], fds[1]);
257
258 proc->out_fds.emplace_back(fds[1]);
259 if (proc->out_fds.size() == 1) {
260 fdevent_add(proc->fde, FDE_WRITE);
261 }
262
Josh Gao5607e922018-07-25 18:15:52 -0700263 return unique_fd{fds[0]};
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800264 }
265 }
Yabin Cui815ad882015-09-02 17:44:28 -0700266 D("search failed !!");
Josh Gao5607e922018-07-25 18:15:52 -0700267 return unique_fd{};
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800268}
269
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800270/** "jdwp" local service implementation
271 ** this simply returns the list of known JDWP process pids
272 **/
273
Josh Gao9eaf33c2016-05-13 15:28:34 -0700274struct JdwpSocket : public asocket {
Josh Gao5cb76ce2018-02-12 17:24:00 -0800275 bool pass = false;
Elliott Hughesfe7ff812015-04-17 09:47:42 -0700276};
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800277
Josh Gao9eaf33c2016-05-13 15:28:34 -0700278static void jdwp_socket_close(asocket* s) {
279 D("LS(%d): closing jdwp socket", s->id);
280
281 if (s->peer) {
282 D("LS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd);
283 s->peer->peer = nullptr;
284 s->peer->close(s->peer);
285 s->peer = nullptr;
286 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800287
288 remove_socket(s);
Josh Gao5cb76ce2018-02-12 17:24:00 -0800289 delete s;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800290}
291
Josh Gaocd2a5292018-03-07 16:52:28 -0800292static int jdwp_socket_enqueue(asocket* s, apacket::payload_type) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800293 /* you can't write to this asocket */
Josh Gao9eaf33c2016-05-13 15:28:34 -0700294 D("LS(%d): JDWP socket received data?", s->id);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800295 s->peer->close(s->peer);
296 return -1;
297}
298
Josh Gao9eaf33c2016-05-13 15:28:34 -0700299static void jdwp_socket_ready(asocket* s) {
300 JdwpSocket* jdwp = (JdwpSocket*)s;
301 asocket* peer = jdwp->peer;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800302
Josh Gao9eaf33c2016-05-13 15:28:34 -0700303 /* on the first call, send the list of pids,
304 * on the second one, close the connection
305 */
306 if (!jdwp->pass) {
Josh Gaocd2a5292018-03-07 16:52:28 -0800307 apacket::payload_type data;
Josh Gaoa7d9d712018-02-01 13:17:50 -0800308 data.resize(s->get_max_payload());
309 size_t len = jdwp_process_list(&data[0], data.size());
310 data.resize(len);
311 peer->enqueue(peer, std::move(data));
Josh Gao9eaf33c2016-05-13 15:28:34 -0700312 jdwp->pass = true;
313 } else {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800314 peer->close(peer);
315 }
316}
317
Josh Gao9eaf33c2016-05-13 15:28:34 -0700318asocket* create_jdwp_service_socket(void) {
Josh Gao5cb76ce2018-02-12 17:24:00 -0800319 JdwpSocket* s = new JdwpSocket();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800320
Josh Gao9eaf33c2016-05-13 15:28:34 -0700321 if (!s) {
Elliott Hughese64126b2018-10-19 13:59:44 -0700322 LOG(FATAL) << "failed to allocate JdwpSocket";
Josh Gao9eaf33c2016-05-13 15:28:34 -0700323 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800324
Josh Gao9eaf33c2016-05-13 15:28:34 -0700325 install_local_socket(s);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800326
Josh Gao9eaf33c2016-05-13 15:28:34 -0700327 s->ready = jdwp_socket_ready;
328 s->enqueue = jdwp_socket_enqueue;
329 s->close = jdwp_socket_close;
330 s->pass = false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800331
Josh Gao9eaf33c2016-05-13 15:28:34 -0700332 return s;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800333}
334
335/** "track-jdwp" local service implementation
336 ** this periodically sends the list of known JDWP process pids
337 ** to the client...
338 **/
339
Josh Gao9eaf33c2016-05-13 15:28:34 -0700340struct JdwpTracker : public asocket {
341 bool need_initial;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800342};
343
Josh Gao361148b2018-01-02 12:01:43 -0800344static auto& _jdwp_trackers = *new std::vector<std::unique_ptr<JdwpTracker>>();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800345
Josh Gao9eaf33c2016-05-13 15:28:34 -0700346static void jdwp_process_list_updated(void) {
Josh Gaoa7d9d712018-02-01 13:17:50 -0800347 std::string data;
348 data.resize(1024);
349 data.resize(jdwp_process_list_msg(&data[0], data.size()));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800350
Josh Gao9eaf33c2016-05-13 15:28:34 -0700351 for (auto& t : _jdwp_trackers) {
Josh Gao9eaf33c2016-05-13 15:28:34 -0700352 if (t->peer) {
353 // The tracker might not have been connected yet.
Josh Gaocd2a5292018-03-07 16:52:28 -0800354 apacket::payload_type payload(data.begin(), data.end());
355 t->peer->enqueue(t->peer, std::move(payload));
Josh Gao9eaf33c2016-05-13 15:28:34 -0700356 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800357 }
358}
359
Josh Gao9eaf33c2016-05-13 15:28:34 -0700360static void jdwp_tracker_close(asocket* s) {
361 D("LS(%d): destroying jdwp tracker service", s->id);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800362
Josh Gao9eaf33c2016-05-13 15:28:34 -0700363 if (s->peer) {
364 D("LS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd);
365 s->peer->peer = nullptr;
366 s->peer->close(s->peer);
367 s->peer = nullptr;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800368 }
369
370 remove_socket(s);
371
Josh Gao9eaf33c2016-05-13 15:28:34 -0700372 auto pred = [s](const auto& tracker) { return tracker.get() == s; };
Josh Gaoeea5fea2017-03-10 11:19:48 -0800373 _jdwp_trackers.erase(std::remove_if(_jdwp_trackers.begin(), _jdwp_trackers.end(), pred),
374 _jdwp_trackers.end());
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800375}
376
Josh Gao9eaf33c2016-05-13 15:28:34 -0700377static void jdwp_tracker_ready(asocket* s) {
378 JdwpTracker* t = (JdwpTracker*)s;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800379
Josh Gao9eaf33c2016-05-13 15:28:34 -0700380 if (t->need_initial) {
Josh Gaocd2a5292018-03-07 16:52:28 -0800381 apacket::payload_type data;
Josh Gaoa7d9d712018-02-01 13:17:50 -0800382 data.resize(s->get_max_payload());
383 data.resize(jdwp_process_list_msg(&data[0], data.size()));
Josh Gao9eaf33c2016-05-13 15:28:34 -0700384 t->need_initial = false;
Josh Gaoa7d9d712018-02-01 13:17:50 -0800385 s->peer->enqueue(s->peer, std::move(data));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800386 }
387}
388
Josh Gaocd2a5292018-03-07 16:52:28 -0800389static int jdwp_tracker_enqueue(asocket* s, apacket::payload_type) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800390 /* you can't write to this socket */
Josh Gao9eaf33c2016-05-13 15:28:34 -0700391 D("LS(%d): JDWP tracker received data?", s->id);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800392 s->peer->close(s->peer);
393 return -1;
394}
395
Josh Gao9eaf33c2016-05-13 15:28:34 -0700396asocket* create_jdwp_tracker_service_socket(void) {
397 auto t = std::make_unique<JdwpTracker>();
398 if (!t) {
Elliott Hughese64126b2018-10-19 13:59:44 -0700399 LOG(FATAL) << "failed to allocate JdwpTracker";
Josh Gao9eaf33c2016-05-13 15:28:34 -0700400 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800401
Josh Gao9eaf33c2016-05-13 15:28:34 -0700402 memset(t.get(), 0, sizeof(asocket));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800403
Josh Gao9eaf33c2016-05-13 15:28:34 -0700404 install_local_socket(t.get());
405 D("LS(%d): created new jdwp tracker service", t->id);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800406
Josh Gao9eaf33c2016-05-13 15:28:34 -0700407 t->ready = jdwp_tracker_ready;
408 t->enqueue = jdwp_tracker_enqueue;
409 t->close = jdwp_tracker_close;
410 t->need_initial = true;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800411
Josh Gao9eaf33c2016-05-13 15:28:34 -0700412 asocket* result = t.get();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800413
Josh Gao9eaf33c2016-05-13 15:28:34 -0700414 _jdwp_trackers.emplace_back(std::move(t));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800415
Josh Gao9eaf33c2016-05-13 15:28:34 -0700416 return result;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800417}
418
Josh Gao9eaf33c2016-05-13 15:28:34 -0700419int init_jdwp(void) {
Josh Gaoeb5e6052019-06-19 14:14:57 -0700420 std::thread([]() {
421 adb_thread_setname("jdwp control");
422 adbconnection_listen([](int fd, pid_t pid) {
423 LOG(INFO) << "jdwp connection from " << pid;
424 fdevent_run_on_main_thread([fd, pid] {
425 unique_fd ufd(fd);
426 auto proc = std::make_unique<JdwpProcess>(std::move(ufd), pid);
427 if (!proc) {
428 LOG(FATAL) << "failed to allocate JdwpProcess";
429 }
430 _jdwp_list.emplace_back(std::move(proc));
431 jdwp_process_list_updated();
432 });
433 });
434 }).detach();
435 return 0;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800436}
437
438#endif /* !ADB_HOST */