xref: /llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestNoLocalFile.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1import lldb
2from lldbsuite.test.lldbtest import *
3from lldbsuite.test.decorators import *
4from lldbsuite.test.gdbclientutils import *
5from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
6
7
8class TestNoLocalFile(GDBRemoteTestBase):
9    """Test the case where there is NO local copy of the file
10    being debugged.  We shouldn't immediately error out, but
11    rather lldb should ask debugserver if it knows about the file."""
12
13    @skipIfXmlSupportMissing
14    def test_with_python(self):
15        self.do_test(False)
16
17    @skipIfXmlSupportMissing
18    def test_with_target_ceate(self):
19        self.do_test(True)
20
21    def do_test(self, use_target_create):
22        self.absent_file = "/nosuch_dir/nosuch_subdir/nosuch_executable"
23        self.a_packet_file = None
24
25        class MyResponder(MockGDBServerResponder):
26            def __init__(self, testcase):
27                MockGDBServerResponder.__init__(self)
28                self.after_launch = False
29                self.testcase = testcase
30                self.current_thread = 0
31
32            def A(self, packet):
33                # This is the main test, we want to see that lldb DID send the
34                # A packet to get debugserver to load the file.
35                # Skip the length and second length:
36                print("Got A packet: {0}".format(packet))
37                a_arr = packet.split(",")
38                self.testcase.a_packet_file = bytearray.fromhex(a_arr[2]).decode()
39                return "OK"
40
41            def qXferRead(self, obj, annex, offset, length):
42                if annex == "target.xml":
43                    return (
44                        """<?xml version="1.0"?>
45                        <target version="1.0">
46                          <architecture>i386:x86-64</architecture>
47                          <feature name="org.gnu.gdb.i386.core">
48                            <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/>
49                          </feature>
50                        </target>""",
51                        False,
52                    )
53                else:
54                    return None, False
55
56            def qC(self):
57                if not self.after_launch:
58                    return "QC0"
59                return "0"
60
61            def qfThreadInfo(self):
62                if not self.after_launch:
63                    return "OK"
64                return "m0"
65
66            def qsThreadInfo(self):
67                if not self.after_launch:
68                    return "OK"
69                return "l"
70
71            def qLaunchSuccess(self):
72                return "OK"
73
74            def qProcessInfo(self):
75                return "$pid:10b70;parent-pid:10b20;real-uid:1f6;real-gid:14;effective-uid:1f6;effective-gid:14;cputype:1000007;cpusubtype:8;ptrsize:8;ostype:macosx;vendor:apple;endian:little;"
76
77        error = lldb.SBError()
78        self.server.responder = MyResponder(self)
79        target = lldb.SBTarget()
80        if use_target_create:
81            create_cmd = "target create --arch x86_64-apple-macosx --platform remote-macosx --remote-file {0}".format(
82                self.absent_file
83            )
84            self.runCmd(create_cmd)
85            target = self.dbg.GetSelectedTarget()
86            self.assertTrue(target.IsValid(), "Made a valid target")
87        else:
88            target = self.dbg.CreateTarget(
89                None, "x86_64-apple-macosx", "remote-macosx", False, error
90            )
91            self.assertSuccess(error, "Made a valid target")
92
93        launch_info = target.GetLaunchInfo()
94        if not use_target_create:
95            launch_info.SetExecutableFile(lldb.SBFileSpec(self.absent_file), True)
96        flags = launch_info.GetLaunchFlags()
97        flags |= lldb.eLaunchFlagStopAtEntry
98        launch_info.SetLaunchFlags(flags)
99
100        process = self.connect(target)
101        self.assertTrue(process.IsValid(), "Process is valid")
102
103        # We need to fetch the connected event:
104        lldbutil.expect_state_changes(
105            self, self.dbg.GetListener(), process, [lldb.eStateConnected]
106        )
107
108        self.server.responder.after_launch = True
109
110        process = target.Launch(launch_info, error)
111
112        self.assertSuccess(error, "Successfully launched.")
113        self.assertState(
114            process.GetState(), lldb.eStateStopped, "Should be stopped at entry"
115        )
116        self.assertIsNotNone(self.a_packet_file, "A packet was sent")
117        self.assertEqual(
118            self.absent_file, self.a_packet_file, "The A packet file was correct"
119        )
120