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