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 @expectedFailureNetBSD 78 @skipIfReproducer # File synchronization is not supported during replay. 79 def test_with_attach_to_process_with_id_api(self): 80 """Create target, spawn a process, and attach to it with process id.""" 81 exe = '%s_%d'%(self.testMethodName, os.getpid()) 82 d = {'EXE': exe} 83 self.build(dictionary=d) 84 self.setTearDownCleanup(dictionary=d) 85 target = self.dbg.CreateTarget(self.getBuildArtifact(exe)) 86 87 # Spawn a new process 88 token = exe+'.token' 89 if not lldb.remote_platform: 90 token = self.getBuildArtifact(token) 91 if os.path.exists(token): 92 os.remove(token) 93 popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token]) 94 self.addTearDownHook(self.cleanupSubprocesses) 95 lldbutil.wait_for_file_on_target(self, token) 96 97 listener = lldb.SBListener("my.attach.listener") 98 error = lldb.SBError() 99 process = target.AttachToProcessWithID(listener, popen.pid, error) 100 101 self.assertTrue(error.Success() and process, PROCESS_IS_VALID) 102 103 # Let's check the stack traces of the attached process. 104 stacktraces = lldbutil.print_stacktraces(process, string_buffer=True) 105 self.expect(stacktraces, exe=False, 106 substrs=['main.c:%d' % self.line2, 107 '(int)argc=2']) 108 109 @add_test_categories(['pyapi']) 110 @skipIfiOSSimulator 111 @skipIfAsan # FIXME: Hangs indefinitely. 112 @expectedFailureNetBSD 113 @skipIfReproducer # FIXME: Unexpected packet during (active) replay 114 def test_with_attach_to_process_with_name_api(self): 115 """Create target, spawn a process, and attach to it with process name.""" 116 exe = '%s_%d'%(self.testMethodName, os.getpid()) 117 d = {'EXE': exe} 118 self.build(dictionary=d) 119 self.setTearDownCleanup(dictionary=d) 120 target = self.dbg.CreateTarget(self.getBuildArtifact(exe)) 121 122 # Spawn a new process. 123 token = exe+'.token' 124 if not lldb.remote_platform: 125 token = self.getBuildArtifact(token) 126 if os.path.exists(token): 127 os.remove(token) 128 popen = self.spawnSubprocess(self.getBuildArtifact(exe), [token]) 129 self.addTearDownHook(self.cleanupSubprocesses) 130 lldbutil.wait_for_file_on_target(self, token) 131 132 listener = lldb.SBListener("my.attach.listener") 133 error = lldb.SBError() 134 # Pass 'False' since we don't want to wait for new instance of 135 # "hello_world" to be launched. 136 name = os.path.basename(exe) 137 138 # While we're at it, make sure that passing a None as the process name 139 # does not hang LLDB. 140 target.AttachToProcessWithName(listener, None, False, error) 141 # Also boundary condition test ConnectRemote(), too. 142 target.ConnectRemote(listener, None, None, error) 143 144 process = target.AttachToProcessWithName(listener, name, False, error) 145 self.assertSuccess(error) 146 self.assertTrue(process, PROCESS_IS_VALID) 147 148 # Verify that after attach, our selected target indeed matches name. 149 self.expect( 150 self.dbg.GetSelectedTarget().GetExecutable().GetFilename(), 151 exe=False, 152 startstr=name) 153 154 # Let's check the stack traces of the attached process. 155 stacktraces = lldbutil.print_stacktraces(process, string_buffer=True) 156 self.expect(stacktraces, exe=False, 157 substrs=['main.c:%d' % self.line2, 158 '(int)argc=2']) 159