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