diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestPlatformClient.py b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestPlatformClient.py --- a/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestPlatformClient.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestPlatformClient.py @@ -5,9 +5,11 @@ from lldbsuite.test.decorators import * from gdbclientutils import * + def hexlify(string): return binascii.hexlify(string.encode()).decode() + class TestPlatformClient(GDBRemoteTestBase): def test_process_list_with_all_users(self): @@ -16,31 +18,42 @@ class MyResponder(MockGDBServerResponder): def __init__(self): MockGDBServerResponder.__init__(self) - self.currentQsProc = 0 + self.currentProc = 0 self.all_users = False + def _processInfo0(self): + name = hexlify("/a/test_process") + args = "-".join(map(hexlify, + ["/system/bin/sh", "-c", "/data/local/tmp/lldb-server"])) + return "pid:10;ppid:1;uid:2;gid:3;euid:4;egid:5;name:" + name + ";args:" + args + ";" + + def _processInfo1(self): + name = hexlify("/b/another_test_process") + # This intentionally has a badly encoded argument + args = "X".join(map(hexlify, + ["/system/bin/ls", "--help"])) + return "pid:11;ppid:2;uid:3;gid:4;euid:5;egid:6;name:" + name + ";args:" + args + ";" + + def _processInfo2(self): + # a process with an empty name but an arg0, which can happen on android + args = hexlify("com.test.app") + return "pid:12;ppid:3;uid:4;gid:5;euid:6;egid:7;name:;args:" + args + ";" + def qfProcessInfo(self, packet): - if "all_users:1" in packet: - self.all_users = True - name = hexlify("/a/test_process") - args = "-".join(map(hexlify, - ["/system/bin/sh", "-c", "/data/local/tmp/lldb-server"])) - return "pid:10;ppid:1;uid:2;gid:3;euid:4;egid:5;name:" + name + ";args:" + args + ";" - else: - self.all_users = False - return "E04" + self.all_users = "all_users:1" in packet + self.currentProc = 1 + return self._processInfo0() def qsProcessInfo(self): if self.all_users: - if self.currentQsProc == 0: - self.currentQsProc = 1 - name = hexlify("/b/another_test_process") - # This intentionally has a badly encoded argument - args = "X".join(map(hexlify, - ["/system/bin/ls", "--help"])) - return "pid:11;ppid:2;uid:3;gid:4;euid:5;egid:6;name:" + name + ";args:" + args + ";" - elif self.currentQsProc == 1: - self.currentQsProc = 0 + if self.currentProc == 1: + self.currentProc = 2 + return self._processInfo1() + elif self.currentProc == 2: + self.currentProc = 3 + return self._processInfo2() + else: + self.currentProc = 0 return "E04" else: return "E04" @@ -53,19 +66,19 @@ self.server.port) self.assertTrue(self.dbg.GetSelectedPlatform().IsConnected()) self.expect("platform process list -x", - substrs=["2 matching processes were found", "test_process", "another_test_process"]) + substrs=["3 matching processes were found", "test_process", "another_test_process", "com.test.app"]) self.expect("platform process list -xv", substrs=[ "PID PARENT USER GROUP EFF USER EFF GROUP", - "10 1 2 3 4 5", - "/system/bin/sh -c /data/local/tmp/lldb-server", - "11 2 3 4 5 6"]) + "10 1 2 3 4 5 /system/bin/sh -c /data/local/tmp/lldb-server", + "11 2 3 4 5 6", + "12 3 4 5 6 7 com.test.app"]) self.assertRaises( Exception, - lambda : self.expect("platform process list -xv", substrs=["/system/bin/ls"]) + lambda: self.expect( + "platform process list -xv", substrs=["/system/bin/ls"]) ) self.expect("platform process list", - error=True, - substrs=["error: no processes were found on the \"remote-linux\" platform"]) + substrs=["1 matching process was found"]) finally: self.dbg.GetSelectedPlatform().DisconnectRemote() diff --git a/lldb/source/Utility/ProcessInfo.cpp b/lldb/source/Utility/ProcessInfo.cpp --- a/lldb/source/Utility/ProcessInfo.cpp +++ b/lldb/source/Utility/ProcessInfo.cpp @@ -38,11 +38,18 @@ m_pid = LLDB_INVALID_PROCESS_ID; } +// In systems like android, there are cases in which a process name can +// correspond to a package name (e.g. com.test.app), which is not an executable +// path. This package name is stored in Arg0, so we can use it as fallback. const char *ProcessInfo::GetName() const { + if (m_executable.GetFilename().IsEmpty() && !GetArg0().empty()) + return GetArg0().data(); return m_executable.GetFilename().GetCString(); } llvm::StringRef ProcessInfo::GetNameAsStringRef() const { + if (m_executable.GetFilename().IsEmpty() && !GetArg0().empty()) + return GetArg0(); return m_executable.GetFilename().GetStringRef(); }