22 using namespace platform_android;
29 llvm::StringRef remote_socket_name,
30 const llvm::Optional<AdbClient::UnixSocketNamespace> &socket_namespace,
35 auto error = AdbClient::CreateByDeviceID(device_id, adb);
40 LLDB_LOGF(log,
"Connected to Android device \"%s\"", device_id.c_str());
42 if (remote_port != 0) {
43 LLDB_LOGF(log,
"Forwarding remote TCP port %d to local TCP port %d",
44 remote_port, local_port);
48 LLDB_LOGF(log,
"Forwarding remote socket \"%s\" to local TCP port %d",
49 remote_socket_name.str().c_str(), local_port);
51 if (!socket_namespace)
52 return Status(
"Invalid socket namespace");
66 std::unique_ptr<TCPSocket> tcp_socket(
new TCPSocket(
true,
false));
70 error = tcp_socket->Listen(
"127.0.0.1:0", 1);
72 port = tcp_socket->GetLocalPortNumber();
77 PlatformAndroidRemoteGDBServer::~PlatformAndroidRemoteGDBServer() {
78 for (
const auto &it : m_port_forwards)
82 bool PlatformAndroidRemoteGDBServer::LaunchGDBServer(
lldb::pid_t &pid,
84 assert(IsConnected());
87 if (!m_gdb_client_up->LaunchGDBServer(
"127.0.0.1", pid, remote_port,
94 MakeConnectURL(pid, remote_port, socket_name.c_str(), connect_url);
95 if (
error.Success() && log)
96 LLDB_LOGF(log,
"gdbserver connect URL: %s", connect_url.c_str());
98 return error.Success();
101 bool PlatformAndroidRemoteGDBServer::KillSpawnedProcess(
lldb::pid_t pid) {
102 assert(IsConnected());
103 DeleteForwardPort(pid);
104 return m_gdb_client_up->KillSpawnedProcess(pid);
107 Status PlatformAndroidRemoteGDBServer::ConnectRemote(
Args &args) {
112 "\"platform connect\" takes a single argument: <connect-url>");
116 return Status(
"URL is null.");
117 llvm::Optional<URI> parsed_url = URI::Parse(url);
119 return Status(
"Invalid URL: %s", url);
120 if (parsed_url->hostname !=
"localhost")
121 m_device_id = parsed_url->hostname.str();
123 m_socket_namespace.reset();
124 if (parsed_url->scheme ==
"unix-connect")
125 m_socket_namespace = AdbClient::UnixSocketNamespaceFileSystem;
126 else if (parsed_url->scheme ==
"unix-abstract-connect")
127 m_socket_namespace = AdbClient::UnixSocketNamespaceAbstract;
132 parsed_url->path, connect_url);
140 LLDB_LOGF(log,
"Rewritten platform connect URL: %s", connect_url.c_str());
142 error = PlatformRemoteGDBServer::ConnectRemote(args);
149 Status PlatformAndroidRemoteGDBServer::DisconnectRemote() {
151 return PlatformRemoteGDBServer::DisconnectRemote();
154 void PlatformAndroidRemoteGDBServer::DeleteForwardPort(
lldb::pid_t pid) {
157 auto it = m_port_forwards.find(pid);
158 if (it == m_port_forwards.end())
161 const auto port = it->second;
165 "Failed to delete port forwarding (pid=%" PRIu64
166 ", port=%d, device=%s): %s",
167 pid, port, m_device_id.c_str(),
error.AsCString());
169 m_port_forwards.erase(it);
172 Status PlatformAndroidRemoteGDBServer::MakeConnectURL(
174 llvm::StringRef remote_socket_name,
std::string &connect_url) {
175 static const int kAttempsNum = 5;
181 for (
auto i = 0; i < kAttempsNum; ++i) {
188 m_socket_namespace, m_device_id);
189 if (
error.Success()) {
190 m_port_forwards[pid] = local_port;
191 std::ostringstream url_str;
192 url_str <<
"connect://127.0.0.1:" << local_port;
193 connect_url = url_str.str();
201 lldb::ProcessSP PlatformAndroidRemoteGDBServer::ConnectProcess(
202 llvm::StringRef connect_url, llvm::StringRef plugin_name,
209 static lldb::pid_t s_remote_gdbserver_fake_pid = 0xffffffffffffffffULL;
211 llvm::Optional<URI> parsed_url = URI::Parse(connect_url);
213 error.SetErrorStringWithFormat(
"Invalid URL: %s",
214 connect_url.str().c_str());
219 error = MakeConnectURL(s_remote_gdbserver_fake_pid--,
220 parsed_url->port.value_or(0), parsed_url->path,
225 return PlatformRemoteGDBServer::ConnectProcess(new_connect_url, plugin_name,
226 debugger, target,
error);