1 //===-- PlatformAndroidRemoteGDBServer.cpp ----------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // Other libraries and framework includes 11 #include "lldb/Core/Error.h" 12 #include "lldb/Core/Log.h" 13 14 // Project includes 15 #include "AdbClient.h" 16 #include "PlatformAndroidRemoteGDBServer.h" 17 #include "Utility/UriParser.h" 18 19 using namespace lldb; 20 using namespace lldb_private; 21 using namespace platform_android; 22 23 static const lldb::pid_t g_remote_platform_pid = 0; // Alias for the process id of lldb-platform 24 25 static Error 26 ForwardPortWithAdb (uint16_t port, std::string& device_id) 27 { 28 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); 29 30 // Fetch the device list from ADB and if only 1 device found then use that device 31 // TODO: Handle the case when more device is available 32 AdbClient adb; 33 auto error = AdbClient::CreateByDeviceID (nullptr, adb); 34 if (error.Fail ()) 35 return error; 36 37 device_id = adb.GetDeviceID (); 38 if (log) 39 log->Printf("Connected to Android device \"%s\"", device_id.c_str ()); 40 41 return adb.SetPortForwarding (port); 42 } 43 44 static Error 45 DeleteForwardPortWithAdb (uint16_t port, const std::string& device_id) 46 { 47 AdbClient adb (device_id); 48 return adb.DeletePortForwarding (port); 49 } 50 51 PlatformAndroidRemoteGDBServer::PlatformAndroidRemoteGDBServer () 52 { 53 } 54 55 PlatformAndroidRemoteGDBServer::~PlatformAndroidRemoteGDBServer () 56 { 57 for (const auto& it : m_port_forwards) 58 { 59 DeleteForwardPortWithAdb (it.second.first, it.second.second); 60 } 61 } 62 63 uint16_t 64 PlatformAndroidRemoteGDBServer::LaunchGDBserverAndGetPort (lldb::pid_t &pid) 65 { 66 uint16_t port = m_gdb_client.LaunchGDBserverAndGetPort (pid, "127.0.0.1"); 67 if (port == 0) 68 return port; 69 70 std::string device_id; 71 Error error = ForwardPortWithAdb (port, device_id); 72 if (error.Fail ()) 73 return 0; 74 75 m_port_forwards[pid] = std::make_pair (port, device_id); 76 77 return port; 78 } 79 80 bool 81 PlatformAndroidRemoteGDBServer::KillSpawnedProcess (lldb::pid_t pid) 82 { 83 DeleteForwardPort (pid); 84 return m_gdb_client.KillSpawnedProcess (pid); 85 } 86 87 Error 88 PlatformAndroidRemoteGDBServer::ConnectRemote (Args& args) 89 { 90 if (args.GetArgumentCount () != 1) 91 return Error ("\"platform connect\" takes a single argument: <connect-url>"); 92 93 int port; 94 std::string scheme, host, path; 95 const char *url = args.GetArgumentAtIndex (0); 96 if (!UriParser::Parse (url, scheme, host, port, path)) 97 return Error ("invalid uri"); 98 99 std::string device_id; 100 Error error = ForwardPortWithAdb (port, device_id); 101 if (error.Fail ()) 102 return error; 103 104 m_port_forwards[g_remote_platform_pid] = std::make_pair (port, device_id); 105 106 error = PlatformRemoteGDBServer::ConnectRemote (args); 107 if (error.Fail ()) 108 DeleteForwardPort (g_remote_platform_pid); 109 110 return error; 111 } 112 113 Error 114 PlatformAndroidRemoteGDBServer::DisconnectRemote () 115 { 116 DeleteForwardPort (g_remote_platform_pid); 117 return PlatformRemoteGDBServer::DisconnectRemote (); 118 } 119 120 void 121 PlatformAndroidRemoteGDBServer::DeleteForwardPort (lldb::pid_t pid) 122 { 123 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); 124 125 auto it = m_port_forwards.find (pid); 126 if (it == m_port_forwards.end ()) 127 return; 128 129 const auto& forward_val = it->second; 130 const auto error = DeleteForwardPortWithAdb (forward_val.first, forward_val.second); 131 if (error.Fail ()) { 132 if (log) 133 log->Printf ("Failed to delete port forwarding (pid=%" PRIu64 ", port=%d, device=%s): %s", 134 pid, forward_val.first, forward_val.second.c_str (), error.AsCString ()); 135 } 136 m_port_forwards.erase (it); 137 } 138