wallace created this revision.
Herald added subscribers: lldb-commits, srhines.
Herald added a project: LLDB.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D68048

Files:
  lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
  lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
  lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp

Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -610,9 +610,9 @@
   if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {
     StringExtractorGDBRemote response;
     m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
-    if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
-                                     response,
-                                     false) == PacketResult::Success) {
+    if (SendPacketAndWaitForResponse(
+            "jGetLoadedDynamicLibrariesInfos:", response, false) ==
+        PacketResult::Success) {
       if (response.IsOKResponse()) {
         m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
       }
@@ -1124,8 +1124,8 @@
   Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));
 
   if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
-    // host info computation can require DNS traffic and shelling out to external processes.
-    // Increase the timeout to account for that.
+    // host info computation can require DNS traffic and shelling out to
+    // external processes. Increase the timeout to account for that.
     ScopedTimeout timeout(*this, seconds(10));
     m_qHostInfo_is_valid = eLazyBoolNo;
     StringExtractorGDBRemote response;
@@ -1199,10 +1199,9 @@
             if (!value.getAsInteger(0, pointer_byte_size))
               ++num_keys_decoded;
           } else if (name.equals("os_version") ||
-                     name.equals(
-                         "version")) // Older debugserver binaries used the
-                                     // "version" key instead of
-                                     // "os_version"...
+                     name.equals("version")) // Older debugserver binaries used
+                                             // the "version" key instead of
+                                             // "os_version"...
           {
             if (!m_os_version.tryParse(value))
               ++num_keys_decoded;
@@ -2067,7 +2066,7 @@
                  !vendor_name.empty()) {
         llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
         if (!environment.empty())
-            triple.setEnvironmentName(environment);
+          triple.setEnvironmentName(environment);
 
         assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
         assert(triple.getObjectFormat() != llvm::Triple::Wasm);
@@ -2099,10 +2098,12 @@
         }
         m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
         m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
-        m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
+        m_process_arch.GetTriple().setEnvironmentName(
+            llvm::StringRef(environment));
         m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
         m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
-        m_host_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
+        m_host_arch.GetTriple().setEnvironmentName(
+            llvm::StringRef(environment));
       }
       return true;
     }
@@ -2581,7 +2582,7 @@
      * The reply from '?' packet could be as simple as 'S05'. There is no packet
      * which can
      * give us pid and/or tid. Assume pid=tid=1 in such cases.
-    */
+     */
     if (response.IsUnsupportedResponse() && IsConnected()) {
       m_curr_tid = 1;
       return true;
@@ -2617,7 +2618,7 @@
      * The reply from '?' packet could be as simple as 'S05'. There is no packet
      * which can
      * give us pid and/or tid. Assume pid=tid=1 in such cases.
-    */
+     */
     if (response.IsUnsupportedResponse() && IsConnected()) {
       m_curr_tid_run = 1;
       return true;
@@ -2754,7 +2755,7 @@
      * be as simple as 'S05'. There is no packet which can give us pid and/or
      * tid.
      * Assume pid=tid=1 in such cases.
-    */
+     */
     if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
         thread_ids.size() == 0 && IsConnected()) {
       thread_ids.push_back(1);
Index: lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
===================================================================
--- lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -12,8 +12,8 @@
 
 #include <string>
 
-#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
 #include "Plugins/Process/Utility/GDBRemoteSignals.h"
+#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
 #include "lldb/Target/Platform.h"
 
 namespace lldb_private {
Index: lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
===================================================================
--- lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
+++ lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
@@ -38,6 +38,9 @@
                                  lldb_private::Target *target,
                                  lldb_private::Status &error) override;
 
+  uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info,
+                         ProcessInstanceInfoList &process_infos) override;
+
 protected:
   std::string m_device_id;
   std::map<lldb::pid_t, uint16_t> m_port_forwards;
Index: lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
===================================================================
--- lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
+++ lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
@@ -9,6 +9,7 @@
 #include "lldb/Host/ConnectionFileDescriptor.h"
 #include "lldb/Host/common/TCPSocket.h"
 #include "lldb/Utility/Log.h"
+#include "lldb/Utility/ProcessInfo.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/UriParser.h"
 
@@ -225,3 +226,117 @@
   return PlatformRemoteGDBServer::ConnectProcess(new_connect_url, plugin_name,
                                                  debugger, target, error);
 }
+
+#define INVALID_INDEX -1
+struct PsColumnsIndices {
+  int user;
+  int pid;
+  int ppid;
+  int name;
+  PsColumnsIndices() { user = pid = ppid = name = INVALID_INDEX; }
+  bool isValid() { return pid != INVALID_INDEX && name != INVALID_INDEX; }
+};
+
+bool parsePsHeader(const std::string &line, PsColumnsIndices &indices) {
+  std::stringstream line_stream(line);
+  std::string column;
+  for (int columnIndex = 0; line_stream >> column; columnIndex++) {
+    if (column.empty()) {
+      continue;
+    }
+    if (column == "USER") {
+      indices.user = columnIndex;
+    } else if (column == "PID") {
+      indices.pid = columnIndex;
+    } else if (column == "PPID") {
+      indices.ppid = columnIndex;
+    } else if (column == "NAME") {
+      indices.name = columnIndex;
+    }
+  }
+  return indices.isValid();
+}
+
+void parsePsProcessLine(const std::string &line,
+                        const PsColumnsIndices &column_indices,
+                        ProcessInstanceInfo &process_info) {
+  std::string user, name;
+  lldb::pid_t pid, ppid;
+  std::stringstream line_stream(line);
+  std::string column;
+  // It is assumed that the name will be the last column because it can
+  // contain spaces or tab separators
+  for (int columnIndex = 0;
+       columnIndex < column_indices.name && line_stream >> column;
+       columnIndex++) {
+    if (column.empty()) {
+      continue;
+    }
+    if (column_indices.user == columnIndex) {
+      user = column;
+    } else if (column_indices.pid == columnIndex) {
+      std::stringstream column_stream(column);
+      column_stream >> pid;
+    } else if (column_indices.ppid == columnIndex) {
+      std::stringstream column_stream(column);
+      column_stream >> ppid;
+    }
+  }
+  std::string name_prefix;
+  line_stream >> name_prefix;
+  getline(line_stream, name, '\n');
+  name = name + name_prefix;
+
+  process_info.SetProcessID(pid);
+  process_info.SetParentProcessID(ppid);
+  process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
+  // TODO: set architecture: process_info.GetArchitecture().SetTriple(...);
+  // TODO: set user id, we only have the name: process_info.SetUserID(...)
+}
+
+bool findProcessFromCommand(const std::string command,
+                            ProcessInstanceInfoList &process_infos,
+                            AdbClient &adb) {
+  process_infos.Clear();
+  std::string output;
+  auto status = adb.Shell(command.c_str(), std::chrono::seconds(5), &output);
+  if (status.Fail()) {
+    return false;
+  }
+  std::stringstream output_stream(output);
+  std::string line;
+  getline(output_stream, line, '\n');
+  PsColumnsIndices column_indices;
+  if (!parsePsHeader(line, column_indices)) {
+    return false;
+  }
+
+  while (getline(output_stream, line, '\n')) {
+    ProcessInstanceInfo process_info;
+    parsePsProcessLine(line, column_indices, process_info);
+    process_infos.Append(process_info);
+  }
+  return true;
+}
+
+bool findProcessesWithAdb(ProcessInstanceInfoList &process_infos,
+                          const std::string device_id) {
+  AdbClient adb;
+  auto error = AdbClient::CreateByDeviceID(device_id, adb);
+  if (error.Fail()) {
+    return false;
+  }
+
+  return findProcessFromCommand("ps -A", process_infos, adb) ||
+         findProcessFromCommand("ps", process_infos, adb);
+}
+
+uint32_t PlatformAndroidRemoteGDBServer::FindProcesses(
+    const ProcessInstanceInfoMatch &match_info,
+    ProcessInstanceInfoList &process_infos) {
+  if (findProcessesWithAdb(process_infos, m_device_id)) {
+    return process_infos.GetSize();
+  } else {
+    return PlatformRemoteGDBServer::FindProcesses(match_info, process_infos);
+  }
+}
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to