aboutsummaryrefslogtreecommitdiff
path: root/source/Host
diff options
context:
space:
mode:
authorWalter Erquinigo <a20012251@gmail.com>2019-10-15 00:00:05 +0000
committerWalter Erquinigo <a20012251@gmail.com>2019-10-15 00:00:05 +0000
commitfde9c2ab6405076c26958cd71c60e5e25d8d8047 (patch)
tree0775f73479715423642ad9ba247528d6335f04fa /source/Host
parent37e39dd92e6497a48aaafb320a9716b132343f3d (diff)
downloadlldb-fde9c2ab6405076c26958cd71c60e5e25d8d8047.tar.gz
[lldb-server/android] Show more processes by relaxing some checks
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. We should show them instead. - 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. Differential Revision: D68289 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@374853 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'source/Host')
-rw-r--r--source/Host/linux/Host.cpp79
1 files changed, 45 insertions, 34 deletions
diff --git a/source/Host/linux/Host.cpp b/source/Host/linux/Host.cpp
index f6a8766a7..fe60d1fd8 100644
--- a/source/Host/linux/Host.cpp
+++ b/source/Host/linux/Host.cpp
@@ -144,68 +144,79 @@ static ArchSpec GetELFProcessCPUType(llvm::StringRef exe_path) {
}
}
-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;
- 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);
+ return;
+ std::unique_ptr<llvm::MemoryBuffer> Environ = std::move(*BufferOrError);
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;
}