1"""Test Python APIs for target (launch and attach), breakpoint, and process.""" 2 3 4 5import os 6 7import lldb 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10import lldbsuite.test.lldbutil as lldbutil 11 12class HelloWorldTestCase(TestBase): 13 NO_DEBUG_INFO_TESTCASE = True 14 mydir = TestBase.compute_mydir(__file__) 15 16 def setUp(self): 17 # Call super's setUp(). 18 TestBase.setUp(self) 19 # Find a couple of the line numbers within main.c. 20 self.line1 = line_number('main.c', '// Set break point at this line.') 21 self.line2 = line_number('main.c', '// Waiting to be attached...') 22 23 def tearDown(self): 24 # Destroy process before TestBase.tearDown() 25 self.dbg.GetSelectedTarget().GetProcess().Destroy() 26 # Call super's tearDown(). 27 TestBase.tearDown(self) 28 29 @add_test_categories(['pyapi']) 30 @skipIfiOSSimulator 31 def test_with_process_launch_api(self): 32 """Create target, breakpoint, launch a process, and then kill it.""" 33 # Get the full path to our executable to be attached/debugged. 34 exe = '%s_%d'%(self.getBuildArtifact(self.testMethodName), os.getpid()) 35 d = {'EXE': exe} 36 self.build(dictionary=d) 37 self.setTearDownCleanup(dictionary=d) 38 target = self.dbg.CreateTarget(exe) 39 40 breakpoint = target.BreakpointCreateByLocation("main.c", self.line1) 41 42 # The default state after breakpoint creation should be enabled. 43 self.assertTrue(breakpoint.IsEnabled(), 44 "Breakpoint should be enabled after creation") 45 46 breakpoint.SetEnabled(False) 47 self.assertTrue(not breakpoint.IsEnabled(), 48 "Breakpoint.SetEnabled(False) works") 49 50 breakpoint.SetEnabled(True) 51 self.assertTrue(breakpoint.IsEnabled(), 52 "Breakpoint.SetEnabled(True) works") 53 54 # rdar://problem/8364687 55 # SBTarget.Launch() issue (or is there some race condition)? 56 57 process = target.LaunchSimple( 58 None, None, self.get_process_working_directory()) 59 # The following isn't needed anymore, rdar://8364687 is fixed. 60 # 61 # Apply some dances after LaunchProcess() in order to break at "main". 62 # It only works sometimes. 63 #self.breakAfterLaunch(process, "main") 64 65 process = target.GetProcess() 66 self.assertTrue(process, PROCESS_IS_VALID) 67 68 thread = lldbutil.get_stopped_thread( 69 process, lldb.eStopReasonBreakpoint) 70 self.assertIsNotNone(thread) 71 72 # The breakpoint should have a hit count of 1. 73 self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE) 74 75 @add_test_categories(['pyapi']) 76 @skipIfiOSSimulator 77 @skipIfReproducer # File synchronization is not supported during replay. 78 def test_with_attach_to_process_with_id_api(self): 79 """Create target, spawn a process, and attach to it with process id.""" 80 exe = '%s_%d'%(self.testMethodName, os.getpid()) 81 d = {'EXE': exe} 82 self.build(dictionary=d) 83 self.setTearDownCleanup(dictionary=d) 84 target = self.dbg.CreateTarget(self.getBuildArtifact(exe)) 85 86 # Spawn a new process 87 token = exe+'.token' 88 if not lldb.remote_platform: 89 token = self.getBuildArtifact(token) 90 if os.path.exists(token): 91 os.remove(token) 92 popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token]) 93 lldbutil.wait_for_file_on_target(self, token) 94 95 listener = lldb.SBListener("my.attach.listener") 96 error = lldb.SBError() 97 process = target.AttachToProcessWithID(listener, popen.pid, error) 98 99 self.assertTrue(error.Success() and process, PROCESS_IS_VALID) 100 101 # Let's check the stack traces of the attached process. 102 stacktraces = lldbutil.print_stacktraces(process, string_buffer=True) 103 self.expect(stacktraces, exe=False, 104 substrs=['main.c:%d' % self.line2, 105 '(int)argc=2']) 106 107 @add_test_categories(['pyapi']) 108 @skipIfiOSSimulator 109 @skipIfAsan # FIXME: Hangs indefinitely. 110 @skipIfReproducer # FIXME: Unexpected packet during (active) replay 111 def test_with_attach_to_process_with_name_api(self): 112 """Create target, spawn a process, and attach to it with process name.""" 113 exe = '%s_%d'%(self.testMethodName, os.getpid()) 114 d = {'EXE': exe} 115 self.build(dictionary=d) 116 self.setTearDownCleanup(dictionary=d) 117 target = self.dbg.CreateTarget(self.getBuildArtifact(exe)) 118 119 # Spawn a new process. 120 token = exe+'.token' 121 if not lldb.remote_platform: 122 token = self.getBuildArtifact(token) 123 if os.path.exists(token): 124 os.remove(token) 125 popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token]) 126 lldbutil.wait_for_file_on_target(self, token) 127 128 listener = lldb.SBListener("my.attach.listener") 129 error = lldb.SBError() 130 # Pass 'False' since we don't want to wait for new instance of 131 # "hello_world" to be launched. 132 name = os.path.basename(exe) 133 134 # While we're at it, make sure that passing a None as the process name 135 # does not hang LLDB. 136 target.AttachToProcessWithName(listener, None, False, error) 137 # Also boundary condition test ConnectRemote(), too. 138 target.ConnectRemote(listener, None, None, error) 139 140 process = target.AttachToProcessWithName(listener, name, False, error) 141 self.assertSuccess(error) 142 self.assertTrue(process, PROCESS_IS_VALID) 143 144 # Verify that after attach, our selected target indeed matches name. 145 self.expect( 146 self.dbg.GetSelectedTarget().GetExecutable().GetFilename(), 147 exe=False, 148 startstr=name) 149 150 # Let's check the stack traces of the attached process. 151 stacktraces = lldbutil.print_stacktraces(process, string_buffer=True) 152 self.expect(stacktraces, exe=False, 153 substrs=['main.c:%d' % self.line2, 154 '(int)argc=2']) 155