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;
 }


_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to