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 auto it = m_port_forwards.find (pid); 84 if (it != m_port_forwards.end ()) 85 { 86 DeleteForwardPortWithAdb (it->second.first, it->second.second); 87 m_port_forwards.erase (it); 88 } 89 90 return m_gdb_client.KillSpawnedProcess (pid); 91 } 92 93 Error 94 PlatformAndroidRemoteGDBServer::ConnectRemote (Args& args) 95 { 96 if (args.GetArgumentCount () != 1) 97 return Error ("\"platform connect\" takes a single argument: <connect-url>"); 98 99 int port; 100 std::string scheme, host, path; 101 const char *url = args.GetArgumentAtIndex (0); 102 if (!UriParser::Parse (url, scheme, host, port, path)) 103 return Error ("invalid uri"); 104 105 std::string device_id; 106 Error error = ForwardPortWithAdb (port, device_id); 107 if (error.Fail ()) 108 return error; 109 110 m_port_forwards[g_remote_platform_pid] = std::make_pair (port, device_id); 111 112 return PlatformRemoteGDBServer::ConnectRemote (args); 113 } 114 115 Error 116 PlatformAndroidRemoteGDBServer::DisconnectRemote () 117 { 118 auto it = m_port_forwards.find (g_remote_platform_pid); 119 if (it != m_port_forwards.end ()) 120 { 121 DeleteForwardPortWithAdb (it->second.first, it->second.second); 122 m_port_forwards.erase (it); 123 } 124 125 return PlatformRemoteGDBServer::DisconnectRemote (); 126 } 127