Index: lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp =================================================================== --- lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp @@ -166,6 +166,14 @@ // unix://SOCKNAME return NamedSocketAccept(s + strlen("unix-accept://"), error_ptr); } + else if (strstr(s, "adb://") == s) + { + int port = -1; + sscanf(s, "adb://%*[^:]:%d", &port); + char host_and_port[sizeof("localhost:65535")]; + snprintf(host_and_port, sizeof(host_and_port), "localhost:%d", port); + return ConnectTCP(host_and_port, error_ptr); + } else if (strstr(s, "connect://") == s) { return ConnectTCP(s + strlen("connect://"), error_ptr); Index: lldb/trunk/source/Plugins/Platform/Android/AdbClient.h =================================================================== --- lldb/trunk/source/Plugins/Platform/Android/AdbClient.h +++ lldb/trunk/source/Plugins/Platform/Android/AdbClient.h @@ -32,7 +32,7 @@ using DeviceIDList = std::list; static Error - CreateByDeviceID (const char* device_id, AdbClient &adb); + CreateByDeviceID(const std::string &device_id, AdbClient &adb); AdbClient () = default; explicit AdbClient (const std::string &device_id); Index: lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp +++ lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp @@ -31,27 +31,28 @@ } // namespace Error -AdbClient::CreateByDeviceID (const char* device_id, AdbClient &adb) +AdbClient::CreateByDeviceID(const std::string &device_id, AdbClient &adb) { DeviceIDList connect_devices; - auto error = adb.GetDevices (connect_devices); - if (error.Fail ()) + auto error = adb.GetDevices(connect_devices); + if (error.Fail()) return error; - if (device_id) + if (device_id.empty()) { - auto find_it = std::find(connect_devices.begin (), connect_devices.end (), device_id); - if (find_it == connect_devices.end ()) - return Error ("Device \"%s\" not found", device_id); + if (connect_devices.size() != 1) + return Error("Expected a single connected device, got instead %" PRIu64, + static_cast(connect_devices.size())); - adb.SetDeviceID (*find_it); + adb.SetDeviceID(connect_devices.front()); } else { - if (connect_devices.size () != 1) - return Error ("Expected a single connected device, got instead %" PRIu64, static_cast(connect_devices.size ())); + auto find_it = std::find(connect_devices.begin(), connect_devices.end(), device_id); + if (find_it == connect_devices.end()) + return Error("Device \"%s\" not found", device_id.c_str()); - adb.SetDeviceID (connect_devices.front ()); + adb.SetDeviceID(*find_it); } return error; } Index: lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp +++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -13,6 +13,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/HostInfo.h" +#include "Utility/UriParser.h" // Project includes #include "AdbClient.h" @@ -171,9 +172,9 @@ } Error -PlatformAndroid::ConnectRemote (Args& args) +PlatformAndroid::ConnectRemote(Args& args) { - m_device_id.clear (); + m_device_id.clear(); if (IsHost()) { @@ -183,17 +184,25 @@ if (!m_remote_platform_sp) m_remote_platform_sp = PlatformSP(new PlatformAndroidRemoteGDBServer()); - auto error = PlatformLinux::ConnectRemote (args); - if (error.Success ()) + int port; + std::string scheme, host, path; + const char *url = args.GetArgumentAtIndex(0); + if (!url) + return Error("URL is null."); + if (!UriParser::Parse(url, scheme, host, port, path)) + return Error("Invalid URL: %s", url); + if (scheme == "adb") + m_device_id = host; + + auto error = PlatformLinux::ConnectRemote(args); + if (error.Success()) { - // Fetch the device list from ADB and if only 1 device found then use that device - // TODO: Handle the case when more device is available AdbClient adb; - error = AdbClient::CreateByDeviceID (nullptr, adb); - if (error.Fail ()) + error = AdbClient::CreateByDeviceID(m_device_id, adb); + if (error.Fail()) return error; - m_device_id = adb.GetDeviceID (); + m_device_id = adb.GetDeviceID(); } return error; } Index: lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h =================================================================== --- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h +++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h @@ -37,7 +37,8 @@ DisconnectRemote () override; protected: - std::map> m_port_forwards; + std::string m_device_id; + std::map m_port_forwards; uint16_t LaunchGDBserverAndGetPort (lldb::pid_t &pid) override; Index: lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp +++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp @@ -27,18 +27,16 @@ { Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); - // Fetch the device list from ADB and if only 1 device found then use that device - // TODO: Handle the case when more device is available AdbClient adb; - auto error = AdbClient::CreateByDeviceID (nullptr, adb); + auto error = AdbClient::CreateByDeviceID(device_id, adb); if (error.Fail ()) return error; - device_id = adb.GetDeviceID (); + device_id = adb.GetDeviceID(); if (log) log->Printf("Connected to Android device \"%s\"", device_id.c_str ()); - return adb.SetPortForwarding (port); + return adb.SetPortForwarding(port); } static Error @@ -55,9 +53,7 @@ PlatformAndroidRemoteGDBServer::~PlatformAndroidRemoteGDBServer () { for (const auto& it : m_port_forwards) - { - DeleteForwardPortWithAdb (it.second.first, it.second.second); - } + DeleteForwardPortWithAdb(it.second, m_device_id); } uint16_t @@ -67,12 +63,11 @@ if (port == 0) return port; - std::string device_id; - Error error = ForwardPortWithAdb (port, device_id); + Error error = ForwardPortWithAdb(port, m_device_id); if (error.Fail ()) return 0; - m_port_forwards[pid] = std::make_pair (port, device_id); + m_port_forwards[pid] = port; return port; } @@ -87,23 +82,28 @@ Error PlatformAndroidRemoteGDBServer::ConnectRemote (Args& args) { - if (args.GetArgumentCount () != 1) - return Error ("\"platform connect\" takes a single argument: "); - + m_device_id.clear(); + + if (args.GetArgumentCount() != 1) + return Error("\"platform connect\" takes a single argument: "); + int port; std::string scheme, host, path; const char *url = args.GetArgumentAtIndex (0); + if (!url) + return Error("URL is null."); if (!UriParser::Parse (url, scheme, host, port, path)) - return Error ("invalid uri"); + return Error("Invalid URL: %s", url); + if (scheme == "adb") + m_device_id = host; - std::string device_id; - Error error = ForwardPortWithAdb (port, device_id); - if (error.Fail ()) + Error error = ForwardPortWithAdb(port, m_device_id); + if (error.Fail()) return error; - m_port_forwards[g_remote_platform_pid] = std::make_pair (port, device_id); + m_port_forwards[g_remote_platform_pid] = port; - error = PlatformRemoteGDBServer::ConnectRemote (args); + error = PlatformRemoteGDBServer::ConnectRemote(args); if (error.Fail ()) DeleteForwardPort (g_remote_platform_pid); @@ -120,18 +120,18 @@ void PlatformAndroidRemoteGDBServer::DeleteForwardPort (lldb::pid_t pid) { - Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - auto it = m_port_forwards.find (pid); - if (it == m_port_forwards.end ()) + auto it = m_port_forwards.find(pid); + if (it == m_port_forwards.end()) return; - const auto& forward_val = it->second; - const auto error = DeleteForwardPortWithAdb (forward_val.first, forward_val.second); - if (error.Fail ()) { + const auto port = it->second; + const auto error = DeleteForwardPortWithAdb(port, m_device_id); + if (error.Fail()) { if (log) - log->Printf ("Failed to delete port forwarding (pid=%" PRIu64 ", port=%d, device=%s): %s", - pid, forward_val.first, forward_val.second.c_str (), error.AsCString ()); + log->Printf("Failed to delete port forwarding (pid=%" PRIu64 ", port=%d, device=%s): %s", + pid, port, m_device_id.c_str(), error.AsCString()); } - m_port_forwards.erase (it); + m_port_forwards.erase(it); } Index: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h =================================================================== --- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -216,6 +216,7 @@ protected: process_gdb_remote::GDBRemoteCommunicationClient m_gdb_client; std::string m_platform_description; // After we connect we can get a more complete description of what we are connected to + std::string m_platform_scheme; std::string m_platform_hostname; // Launch the lldb-gdbserver on the remote host and return the port it is listening on or 0 on Index: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -40,13 +40,18 @@ static bool g_initialized = false; -static std::string MakeGdbServerUrl (const std::string &platform_hostname, uint16_t port) +static std::string MakeGdbServerUrl( + const std::string &platform_scheme, + const std::string &platform_hostname, + uint16_t port) { + const char *override_scheme = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_SCHEME"); const char *override_hostname = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME"); const char *port_offset_c_str = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_PORT_OFFSET"); int port_offset = port_offset_c_str ? ::atoi(port_offset_c_str) : 0; StreamString result; - result.Printf("connect://%s:%u", + result.Printf("%s://%s:%u", + override_scheme ? override_scheme : platform_scheme.c_str(), override_hostname ? override_hostname : platform_hostname.c_str(), port + port_offset); return result.GetString(); @@ -375,17 +380,15 @@ { if (args.GetArgumentCount() == 1) { - const char *url = args.GetArgumentAtIndex(0); - m_gdb_client.SetConnection (new ConnectionFileDescriptor()); + m_gdb_client.SetConnection(new ConnectionFileDescriptor()); // we're going to reuse the hostname when we connect to the debugserver - std::string scheme; int port; std::string path; - if ( !UriParser::Parse(url, scheme, m_platform_hostname, port, path) ) - { - error.SetErrorString("invalid uri"); - return error; - } + const char *url = args.GetArgumentAtIndex(0); + if (!url) + return Error("URL is null."); + if (!UriParser::Parse(url, m_platform_scheme, m_platform_hostname, port, path)) + return Error("Invalid URL: %s", url); const ConnectionStatus status = m_gdb_client.Connect(url, &error); if (status == eConnectionStatusSuccess) @@ -624,7 +627,8 @@ if (process_sp) { - std::string connect_url = MakeGdbServerUrl(m_platform_hostname, port); + std::string connect_url = + MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port); error = process_sp->ConnectRemote (nullptr, connect_url.c_str()); // Retry the connect remote one time... if (error.Fail()) @@ -719,7 +723,8 @@ if (process_sp) { - std::string connect_url = MakeGdbServerUrl(m_platform_hostname, port); + std::string connect_url = + MakeGdbServerUrl(m_platform_scheme, m_platform_hostname, port); error = process_sp->ConnectRemote(nullptr, connect_url.c_str()); if (error.Success()) {