1*92eaad2dSJim Inghamimport lldb
2*92eaad2dSJim Inghamfrom lldbsuite.test.lldbtest import *
3*92eaad2dSJim Inghamfrom lldbsuite.test.decorators import *
4*92eaad2dSJim Inghamfrom lldbsuite.test.gdbclientutils import *
5*92eaad2dSJim Inghamfrom lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
6*92eaad2dSJim Ingham
7*92eaad2dSJim Inghamclass TestNoLocalFile(GDBRemoteTestBase):
8*92eaad2dSJim Ingham    """ Test the case where there is NO local copy of the file
9*92eaad2dSJim Ingham        being debugged.  We shouldn't immediately error out, but
10*92eaad2dSJim Ingham        rather lldb should ask debugserver if it knows about the file. """
11*92eaad2dSJim Ingham
12*92eaad2dSJim Ingham    mydir = TestBase.compute_mydir(__file__)
13*92eaad2dSJim Ingham
14*92eaad2dSJim Ingham    @skipIfXmlSupportMissing
15*92eaad2dSJim Ingham    def test(self):
16*92eaad2dSJim Ingham        self.absent_file = '/nosuch_dir/nosuch_subdir/nosuch_executable'
17*92eaad2dSJim Ingham        self.a_packet_file = None
18*92eaad2dSJim Ingham        class MyResponder(MockGDBServerResponder):
19*92eaad2dSJim Ingham            def __init__(self, testcase):
20*92eaad2dSJim Ingham                MockGDBServerResponder.__init__(self)
21*92eaad2dSJim Ingham                self.after_launch = False
22*92eaad2dSJim Ingham                self.testcase = testcase
23*92eaad2dSJim Ingham                self.current_thread = 0
24*92eaad2dSJim Ingham
25*92eaad2dSJim Ingham            def A(self, packet):
26*92eaad2dSJim Ingham                # This is the main test, we want to see that lldb DID send the
27*92eaad2dSJim Ingham                # A packet to get debugserver to load the file.
28*92eaad2dSJim Ingham                # Skip the length and second length:
29*92eaad2dSJim Ingham                print("Got A packet: {0}".format(packet))
30*92eaad2dSJim Ingham                a_arr = packet.split(",")
31*92eaad2dSJim Ingham                self.testcase.a_packet_file = bytearray.fromhex(a_arr[2]).decode()
32*92eaad2dSJim Ingham                return "OK"
33*92eaad2dSJim Ingham
34*92eaad2dSJim Ingham            def qXferRead(self, obj, annex, offset, length):
35*92eaad2dSJim Ingham                if annex == "target.xml":
36*92eaad2dSJim Ingham                    return """<?xml version="1.0"?>
37*92eaad2dSJim Ingham                        <target version="1.0">
38*92eaad2dSJim Ingham                          <architecture>i386:x86-64</architecture>
39*92eaad2dSJim Ingham                          <feature name="org.gnu.gdb.i386.core">
40*92eaad2dSJim Ingham                            <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/>
41*92eaad2dSJim Ingham                          </feature>
42*92eaad2dSJim Ingham                        </target>""", False
43*92eaad2dSJim Ingham                else:
44*92eaad2dSJim Ingham                    return None, False
45*92eaad2dSJim Ingham
46*92eaad2dSJim Ingham            def qC(self):
47*92eaad2dSJim Ingham                if not self.after_launch:
48*92eaad2dSJim Ingham                    return "QC0"
49*92eaad2dSJim Ingham                return "0"
50*92eaad2dSJim Ingham
51*92eaad2dSJim Ingham            def qfThreadInfo(self):
52*92eaad2dSJim Ingham                if not self.after_launch:
53*92eaad2dSJim Ingham                    return "OK"
54*92eaad2dSJim Ingham                return "m0"
55*92eaad2dSJim Ingham
56*92eaad2dSJim Ingham            def qsThreadInfo(self):
57*92eaad2dSJim Ingham                if not self.after_launch:
58*92eaad2dSJim Ingham                    return "OK"
59*92eaad2dSJim Ingham                return "l"
60*92eaad2dSJim Ingham
61*92eaad2dSJim Ingham            def qLaunchSuccess(self):
62*92eaad2dSJim Ingham                return "OK"
63*92eaad2dSJim Ingham
64*92eaad2dSJim Ingham            def qProcessInfo(self):
65*92eaad2dSJim Ingham                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;"
66*92eaad2dSJim Ingham
67*92eaad2dSJim Ingham
68*92eaad2dSJim Ingham        error = lldb.SBError()
69*92eaad2dSJim Ingham        self.server.responder = MyResponder(self)
70*92eaad2dSJim Ingham        target = self.dbg.CreateTarget(None, "x86_64-apple-macosx", "remote-macosx", False, error)
71*92eaad2dSJim Ingham        self.assertSuccess(error, "Made a valid target")
72*92eaad2dSJim Ingham        launch_info = target.GetLaunchInfo()
73*92eaad2dSJim Ingham        launch_info.SetExecutableFile(lldb.SBFileSpec(self.absent_file), True)
74*92eaad2dSJim Ingham        flags = launch_info.GetLaunchFlags()
75*92eaad2dSJim Ingham        flags |= lldb.eLaunchFlagStopAtEntry
76*92eaad2dSJim Ingham        launch_info.SetLaunchFlags(flags)
77*92eaad2dSJim Ingham
78*92eaad2dSJim Ingham        process = self.connect(target)
79*92eaad2dSJim Ingham        self.assertTrue(process.IsValid(), "Process is valid")
80*92eaad2dSJim Ingham
81*92eaad2dSJim Ingham        # We need to fetch the connected event:
82*92eaad2dSJim Ingham        lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, [lldb.eStateConnected])
83*92eaad2dSJim Ingham
84*92eaad2dSJim Ingham        self.server.responder.after_launch = True
85*92eaad2dSJim Ingham
86*92eaad2dSJim Ingham        process = target.Launch(launch_info, error)
87*92eaad2dSJim Ingham
88*92eaad2dSJim Ingham        self.assertSuccess(error, "Successfully launched.")
89*92eaad2dSJim Ingham        self.assertEqual(process.GetState(), lldb.eStateStopped, "Should be stopped at entry")
90*92eaad2dSJim Ingham        self.assertIsNotNone(self.a_packet_file, "A packet was sent")
91*92eaad2dSJim Ingham        self.assertEqual(self.absent_file, self.a_packet_file, "The A packet file was correct")
92