[Lldb-commits] [lldb] r373758 - [lldb-server/android] Show more processes and package name when necessary

Walter Erquinigo via lldb-commits lldb-commits at lists.llvm.org
Fri Oct 4 09:35:59 PDT 2019


Author: wallace
Date: Fri Oct  4 09:35:59 2019
New Revision: 373758

URL: http://llvm.org/viewvc/llvm-project?rev=373758&view=rev
Log:
[lldb-server/android] Show more processes and package name when necessary

Summary:
By default `platform process list` only shows the processes of the current user that lldb-server can parse.
There are several problems:
- apk programs don't have an executable file. They instead use a package name as identifier.
- each apk also runs under a different user. That's how android works
- because of the user permission, some files like /proc/<pid>/{environ,exe} can't be read.

This results in a very small process list.

This is a local run on my machine
```
(lldb) platform process list
2 matching processes were found on "remote-android"
PID    PARENT USER       TRIPLE                   NAME
====== ====== ========== ======================== ============================
23291  3177              aarch64-unknown-linux-android sh
23301  23291            aarch64-unknown-linux-android lldb-server
```
However, I have 700 processes running at this time.

By implementing a few fallbacks for android, I've expanded this list to 202, filtering out kernel processes, which would presumably appear in this list if the device was rooted.

```
(lldb) platform process list
202 matching processes were found on "remote-android"
PID    PARENT USER       TRIPLE                   NAME
====== ====== ========== ======================== ============================
...
12647  3208              aarch64-unknown-linux-android sh
12649  12647             aarch64-unknown-linux-android lldb-server
12653  982                                        com.samsung.faceservice
13185  982                                        com.samsung.vvm
15899  982                                        com.samsung.android.spay
16220  982                                        com.sec.spp.push
17126  982                                        com.sec.spp.push:RemoteDlcProcess
19772  983                                        com.android.chrome
20209  982                                        com.samsung.cmh:CMH
20380  982                                        com.google.android.inputmethod.latin
20879  982                                        com.samsung.android.oneconnect:Receiver
21212  983                                        com.tencent.mm
24459  1                 aarch64-unknown-linux-android wpa_supplicant
25974  982                                        com.samsung.android.contacts
26293  982                                        com.samsung.android.messaging
28714  982                                        com.samsung.android.dialer
31605  982                                        com.samsung.android.MtpApplication
32256  982                                        com.bezobidny
```

Something to notice is that the architecture is unkonwn for all apks. And that's fine, because run-as would be required to gather this information and that would make this entire functionality massively slow.

There are still several improvements to make here, like displaying actual user names, which I'll try to do in a following diff.

Note: Regarding overall apk debugging support from lldb. I'm planning on having lldb spawn lldb-server by itself with the correct user, so that everything works well. The initial lldb-server used for connecting to the remote platform can be reused for such purpose. Furthermore, eventually lldb could also launch that initial lldb-server on its own.

Reviewers: clayborg, aadsm, labath, xiaobai

Subscribers: srhines, krytarowski, kristof.beyls, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D68289

Modified:
    lldb/trunk/source/Host/linux/Host.cpp

Modified: lldb/trunk/source/Host/linux/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/linux/Host.cpp?rev=373758&r1=373757&r2=373758&view=diff
==============================================================================
--- lldb/trunk/source/Host/linux/Host.cpp (original)
+++ lldb/trunk/source/Host/linux/Host.cpp Fri Oct  4 09:35:59 2019
@@ -144,68 +144,79 @@ static ArchSpec GetELFProcessCPUType(llv
   }
 }
 
-static bool GetProcessAndStatInfo(::pid_t pid,
-                                  ProcessInstanceInfo &process_info,
-                                  ProcessState &State, ::pid_t &tracerpid) {
-  tracerpid = 0;
-  process_info.Clear();
+static void GetProcessArgs(::pid_t pid, ProcessInstanceInfo &process_info) {
+  auto BufferOrError = getProcFile(pid, "cmdline");
+  if (!BufferOrError)
+    return;
+  std::unique_ptr<llvm::MemoryBuffer> Cmdline = std::move(*BufferOrError);
 
+  llvm::StringRef Arg0, Rest;
+  std::tie(Arg0, Rest) = Cmdline->getBuffer().split('\0');
+  process_info.SetArg0(Arg0);
+  while (!Rest.empty()) {
+    llvm::StringRef Arg;
+    std::tie(Arg, Rest) = Rest.split('\0');
+    process_info.GetArguments().AppendArgument(Arg);
+  }
+}
+
+static void GetExePathAndArch(::pid_t pid, ProcessInstanceInfo &process_info) {
   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+  std::string ExePath(PATH_MAX, '\0');
 
   // We can't use getProcFile here because proc/[pid]/exe is a symbolic link.
   llvm::SmallString<64> ProcExe;
   (llvm::Twine("/proc/") + llvm::Twine(pid) + "/exe").toVector(ProcExe);
-  std::string ExePath(PATH_MAX, '\0');
 
   ssize_t len = readlink(ProcExe.c_str(), &ExePath[0], PATH_MAX);
-  if (len <= 0) {
+  if (len > 0) {
+    ExePath.resize(len);
+  } else {
     LLDB_LOG(log, "failed to read link exe link for {0}: {1}", pid,
              Status(errno, eErrorTypePOSIX));
-    return false;
+    ExePath.resize(0);
   }
-  ExePath.resize(len);
-
   // If the binary has been deleted, the link name has " (deleted)" appended.
   // Remove if there.
   llvm::StringRef PathRef = ExePath;
   PathRef.consume_back(" (deleted)");
 
-  process_info.SetArchitecture(GetELFProcessCPUType(PathRef));
+  if (!PathRef.empty()) {
+    process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native);
+    process_info.SetArchitecture(GetELFProcessCPUType(PathRef));
+  }
+}
 
+static void GetProcessEnviron(::pid_t pid, ProcessInstanceInfo &process_info) {
   // Get the process environment.
   auto BufferOrError = getProcFile(pid, "environ");
   if (!BufferOrError)
-    return false;
+    return;
+ 
   std::unique_ptr<llvm::MemoryBuffer> Environ = std::move(*BufferOrError);
-
-  // Get the command line used to start the process.
-  BufferOrError = getProcFile(pid, "cmdline");
-  if (!BufferOrError)
-    return false;
-  std::unique_ptr<llvm::MemoryBuffer> Cmdline = std::move(*BufferOrError);
-
-  // Get User and Group IDs and get tracer pid.
-  if (!GetStatusInfo(pid, process_info, State, tracerpid))
-    return false;
-
-  process_info.SetProcessID(pid);
-  process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native);
-
   llvm::StringRef Rest = Environ->getBuffer();
   while (!Rest.empty()) {
     llvm::StringRef Var;
     std::tie(Var, Rest) = Rest.split('\0');
     process_info.GetEnvironment().insert(Var);
   }
+}
 
-  llvm::StringRef Arg0;
-  std::tie(Arg0, Rest) = Cmdline->getBuffer().split('\0');
-  process_info.SetArg0(Arg0);
-  while (!Rest.empty()) {
-    llvm::StringRef Arg;
-    std::tie(Arg, Rest) = Rest.split('\0');
-    process_info.GetArguments().AppendArgument(Arg);
-  }
+static bool GetProcessAndStatInfo(::pid_t pid,
+                                  ProcessInstanceInfo &process_info,
+                                  ProcessState &State, ::pid_t &tracerpid) {
+  tracerpid = 0;
+  process_info.Clear();
+
+  process_info.SetProcessID(pid);
+
+  GetExePathAndArch(pid, process_info);
+  GetProcessArgs(pid, process_info);
+  GetProcessEnviron(pid, process_info);
+
+  // Get User and Group IDs and get tracer pid.
+  if (!GetStatusInfo(pid, process_info, State, tracerpid))
+    return false;
 
   return true;
 }




More information about the lldb-commits mailing list