| import lldb |
| import binascii |
| import os |
| import time |
| from lldbsuite.test.lldbtest import * |
| from lldbsuite.test.decorators import * |
| from lldbsuite.test.gdbclientutils import * |
| from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase |
| |
| def hexlify(string): |
| return binascii.hexlify(string.encode()).decode() |
| |
| class TestPlatformClient(GDBRemoteTestBase): |
| |
| mydir = TestBase.compute_mydir(__file__) |
| |
| def test_process_list_with_all_users(self): |
| """Test connecting to a remote linux platform""" |
| |
| class MyResponder(MockGDBServerResponder): |
| def __init__(self): |
| MockGDBServerResponder.__init__(self) |
| self.currentQsProc = 0 |
| self.all_users = False |
| |
| 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" |
| |
| 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 |
| return "E04" |
| else: |
| return "E04" |
| |
| self.server.responder = MyResponder() |
| |
| try: |
| self.runCmd("platform select remote-linux") |
| self.runCmd("platform connect " + self.server.get_connect_url()) |
| self.assertTrue(self.dbg.GetSelectedPlatform().IsConnected()) |
| self.expect("platform process list -x", |
| substrs=["2 matching processes were found", "test_process", "another_test_process"]) |
| self.expect("platform process list -xv", |
| substrs=[ |
| "PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE ARGUMENTS", |
| "10 1 2 3 4 5 /system/bin/sh -c /data/local/tmp/lldb-server", |
| "11 2 3 4 5 6"]) |
| self.expect("platform process list -xv", substrs=["/system/bin/ls"], matching=False) |
| self.expect("platform process list", |
| error=True, |
| substrs=["error: no processes were found on the \"remote-linux\" platform"]) |
| finally: |
| self.dbg.GetSelectedPlatform().DisconnectRemote() |
| |
| class TimeoutResponder(MockGDBServerResponder): |
| """A mock server, which takes a very long time to compute the working |
| directory.""" |
| def __init__(self): |
| MockGDBServerResponder.__init__(self) |
| |
| def qGetWorkingDir(self): |
| time.sleep(10) |
| return hexlify("/foo/bar") |
| |
| def test_no_timeout(self): |
| """Test that we honor the timeout setting. With a large enough timeout, |
| we should get the CWD successfully.""" |
| |
| self.server.responder = TestPlatformClient.TimeoutResponder() |
| self.runCmd("settings set plugin.process.gdb-remote.packet-timeout 30") |
| plat = lldb.SBPlatform("remote-linux") |
| try: |
| self.assertSuccess(plat.ConnectRemote(lldb.SBPlatformConnectOptions( |
| self.server.get_connect_url()))) |
| self.assertEqual(plat.GetWorkingDirectory(), "/foo/bar") |
| finally: |
| plat.DisconnectRemote() |
| |
| def test_timeout(self): |
| """Test that we honor the timeout setting. With a small timeout, CWD |
| retrieval should fail.""" |
| |
| self.server.responder = TestPlatformClient.TimeoutResponder() |
| self.runCmd("settings set plugin.process.gdb-remote.packet-timeout 3") |
| plat = lldb.SBPlatform("remote-linux") |
| try: |
| self.assertSuccess(plat.ConnectRemote(lldb.SBPlatformConnectOptions( |
| self.server.get_connect_url()))) |
| self.assertIsNone(plat.GetWorkingDirectory()) |
| finally: |
| plat.DisconnectRemote() |