diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp --- a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp +++ b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -151,8 +151,7 @@ llvm::Optional parsed_url = URI::Parse(url); if (!parsed_url) return Status("Invalid URL: %s", url); - if (parsed_url->hostname != "localhost") - m_device_id = parsed_url->hostname.str(); + m_device_id = PlatformAndroidRemoteGDBServer::GetDeviceIDFromURL(url, parsed_url); auto error = PlatformLinux::ConnectRemote(args); if (error.Success()) { diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h --- a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h +++ b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h @@ -28,6 +28,9 @@ ~PlatformAndroidRemoteGDBServer() override; + static std::string GetDeviceIDFromURL(llvm::StringRef url, + llvm::Optional parsed_url); + Status ConnectRemote(Args &args) override; Status DisconnectRemote() override; diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp --- a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp @@ -79,6 +79,23 @@ DeleteForwardPortWithAdb(it.second, m_device_id); } +std::string PlatformAndroidRemoteGDBServer::GetDeviceIDFromURL( + const llvm::StringRef url, llvm::Optional parsed_url) { + const llvm::StringRef kSchemeSepWithIPv6Bracket("://["); + auto pos = url.find(kSchemeSepWithIPv6Bracket); + std::string hostname; + if (pos == std::string::npos) + hostname = parsed_url->hostname.str(); + else + hostname = "[" + parsed_url->hostname.str() + "]"; + + if (parsed_url->port.hasValue()) + return hostname + ":" + std::to_string(parsed_url->port.value()); + if (hostname != "localhost") + return hostname; + return std::string(); +} + bool PlatformAndroidRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid, std::string &connect_url) { assert(IsConnected()); @@ -122,8 +139,7 @@ llvm::Optional parsed_url = URI::Parse(url); if (!parsed_url) return Status("Invalid URL: %s", url); - if (parsed_url->hostname != "localhost") - m_device_id = parsed_url->hostname.str(); + m_device_id = GetDeviceIDFromURL(url, parsed_url); m_socket_namespace.reset(); if (parsed_url->scheme == "unix-connect") @@ -137,9 +153,8 @@ local_port = std::stoi(platform_local_port); std::string connect_url; - auto error = MakeConnectURL(g_remote_platform_pid, local_port, - parsed_url->port.value_or(0), parsed_url->path, - connect_url); + auto error = MakeConnectURL(g_remote_platform_pid, local_port, 0, + parsed_url->path, connect_url); if (error.Fail()) return error; @@ -236,8 +251,7 @@ } std::string new_connect_url; - error = MakeConnectURL(s_remote_gdbserver_fake_pid--, 0, - parsed_url->port.value_or(0), parsed_url->path, + error = MakeConnectURL(s_remote_gdbserver_fake_pid--, 0, 0, parsed_url->path, new_connect_url); if (error.Fail()) return nullptr; diff --git a/lldb/unittests/Platform/Android/CMakeLists.txt b/lldb/unittests/Platform/Android/CMakeLists.txt --- a/lldb/unittests/Platform/Android/CMakeLists.txt +++ b/lldb/unittests/Platform/Android/CMakeLists.txt @@ -2,6 +2,7 @@ add_lldb_unittest(AdbClientTests AdbClientTest.cpp + PlatformAndroidRemoteGDBServerTest.cpp LINK_LIBS lldbPluginPlatformAndroid diff --git a/lldb/unittests/Platform/Android/PlatformAndroidRemoteGDBServerTest.cpp b/lldb/unittests/Platform/Android/PlatformAndroidRemoteGDBServerTest.cpp new file mode 100644 --- /dev/null +++ b/lldb/unittests/Platform/Android/PlatformAndroidRemoteGDBServerTest.cpp @@ -0,0 +1,50 @@ +//===-- PlatformAndroidRemoteGDBServerTest.cpp +//-----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h" +#include "gtest/gtest.h" +#include + +using namespace lldb; +using namespace lldb_private; + +namespace lldb_private { +namespace platform_android { + +class PlatformAndroidRemoteGDBServerTest : public ::testing::Test {}; + +TEST(PlatformAndroidRemoteGDBServerTest, GetDeviceIDFromURL) { + const static std::vector> data{ + {{"url", "unix-abstract-connect:///sock"}, {"serial", ""}}, + {{"url", "unix-abstract-connect://localhost/sock"}, {"serial", ""}}, + {{"url", "unix-abstract-connect://emulator-5554/sock"}, + {"serial", "emulator-5554"}}, + {{"url", "unix-abstract-connect://localhost:5556/sock"}, + {"serial", "localhost:5556"}}, + {{"url", "unix-abstract-connect://192.168.0.1:42/sock"}, + {"serial", "192.168.0.1:42"}}, + {{"url", "unix-abstract-connect://[::1]:5557/sock"}, + {"serial", "[::1]:5557"}}, + {{"url", "unix-abstract-connect://" + "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:5556/sock"}, + {"serial", "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:5556"}}, + }; + + for (const auto &map : data) { + const auto &url = map.at("url"); + llvm::Optional parsed_url = URI::Parse(url); + EXPECT_TRUE(parsed_url); + EXPECT_EQ( + PlatformAndroidRemoteGDBServer::GetDeviceIDFromURL(url, parsed_url), + map.at("serial")); + } +} + +} // end namespace platform_android +} // end namespace lldb_private