1"""Test Python APIs for target (launch and attach), breakpoint, and process.""" 2 3import os, sys, time 4import unittest2 5import lldb 6import time 7from lldbtest import * 8 9class HelloWorldTestCase(TestBase): 10 11 mydir = os.path.join("python_api", "hello_world") 12 13 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 14 @python_api_test 15 @dsym_test 16 def test_with_dsym_and_process_launch_api(self): 17 """Create target, breakpoint, launch a process, and then kill it. 18 19 Use dsym info and process launch API. 20 """ 21 self.buildDsym(dictionary=self.d) 22 self.setTearDownCleanup(dictionary=self.d) 23 self.hello_world_python() 24 25 @python_api_test 26 @dwarf_test 27 def test_with_dwarf_and_process_launch_api(self): 28 """Create target, breakpoint, launch a process, and then kill it. 29 30 Use dwarf debug map and process launch API. 31 """ 32 self.buildDwarf(dictionary=self.d) 33 self.setTearDownCleanup(dictionary=self.d) 34 self.hello_world_python() 35 36 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 37 @python_api_test 38 @dsym_test 39 def test_with_dsym_and_attach_to_process_with_id_api(self): 40 """Create target, spawn a process, and attach to it with process id. 41 42 Use dsym info and attach to process with id API. 43 """ 44 self.buildDsym(dictionary=self.d) 45 self.setTearDownCleanup(dictionary=self.d) 46 self.hello_world_attach_with_id_api() 47 48 @python_api_test 49 @dwarf_test 50 def test_with_dwarf_and_attach_to_process_with_id_api(self): 51 """Create target, spawn a process, and attach to it with process id. 52 53 Use dwarf map (no dsym) and attach to process with id API. 54 """ 55 self.buildDwarf(dictionary=self.d) 56 self.setTearDownCleanup(dictionary=self.d) 57 self.hello_world_attach_with_id_api() 58 59 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 60 @python_api_test 61 @dsym_test 62 def test_with_dsym_and_attach_to_process_with_name_api(self): 63 """Create target, spawn a process, and attach to it with process name. 64 65 Use dsym info and attach to process with name API. 66 """ 67 self.buildDsym(dictionary=self.d) 68 self.setTearDownCleanup(dictionary=self.d) 69 self.hello_world_attach_with_name_api() 70 71 @expectedFailureFreeBSD('llvm.org/pr16699') # attach by name not on FreeBSD yet 72 @python_api_test 73 @dwarf_test 74 def test_with_dwarf_and_attach_to_process_with_name_api(self): 75 """Create target, spawn a process, and attach to it with process name. 76 77 Use dwarf map (no dsym) and attach to process with name API. 78 """ 79 self.buildDwarf(dictionary=self.d) 80 self.setTearDownCleanup(dictionary=self.d) 81 self.hello_world_attach_with_name_api() 82 83 def setUp(self): 84 # Call super's setUp(). 85 TestBase.setUp(self) 86 # Get the full path to our executable to be attached/debugged. 87 self.exe = os.path.join(os.getcwd(), self.testMethodName) 88 self.d = {'EXE': self.testMethodName} 89 # Find a couple of the line numbers within main.c. 90 self.line1 = line_number('main.c', '// Set break point at this line.') 91 self.line2 = line_number('main.c', '// Waiting to be attached...') 92 93 def hello_world_python(self): 94 """Create target, breakpoint, launch a process, and then kill it.""" 95 96 target = self.dbg.CreateTarget(self.exe) 97 98 breakpoint = target.BreakpointCreateByLocation("main.c", self.line1) 99 100 # The default state after breakpoint creation should be enabled. 101 self.assertTrue(breakpoint.IsEnabled(), 102 "Breakpoint should be enabled after creation") 103 104 breakpoint.SetEnabled(False) 105 self.assertTrue(not breakpoint.IsEnabled(), 106 "Breakpoint.SetEnabled(False) works") 107 108 breakpoint.SetEnabled(True) 109 self.assertTrue(breakpoint.IsEnabled(), 110 "Breakpoint.SetEnabled(True) works") 111 112 # rdar://problem/8364687 113 # SBTarget.Launch() issue (or is there some race condition)? 114 115 process = target.LaunchSimple(None, None, os.getcwd()) 116 # The following isn't needed anymore, rdar://8364687 is fixed. 117 # 118 # Apply some dances after LaunchProcess() in order to break at "main". 119 # It only works sometimes. 120 #self.breakAfterLaunch(process, "main") 121 122 process = target.GetProcess() 123 self.assertTrue(process, PROCESS_IS_VALID) 124 125 thread = process.GetThreadAtIndex(0) 126 if thread.GetStopReason() != lldb.eStopReasonBreakpoint: 127 from lldbutil import stop_reason_to_str 128 self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS % 129 stop_reason_to_str(thread.GetStopReason())) 130 131 # The breakpoint should have a hit count of 1. 132 self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE) 133 134 def hello_world_attach_with_id_api(self): 135 """Create target, spawn a process, and attach to it by id.""" 136 137 target = self.dbg.CreateTarget(self.exe) 138 139 # Spawn a new process 140 popen = self.spawnSubprocess(self.exe, ["abc", "xyz"]) 141 self.addTearDownHook(self.cleanupSubprocesses) 142 143 # Give the subprocess time to start and wait for user input 144 time.sleep(0.25) 145 146 listener = lldb.SBListener("my.attach.listener") 147 error = lldb.SBError() 148 process = target.AttachToProcessWithID(listener, popen.pid, error) 149 150 self.assertTrue(error.Success() and process, PROCESS_IS_VALID) 151 152 # Let's check the stack traces of the attached process. 153 import lldbutil 154 stacktraces = lldbutil.print_stacktraces(process, string_buffer=True) 155 self.expect(stacktraces, exe=False, 156 substrs = ['main.c:%d' % self.line2, 157 '(int)argc=3']) 158 159 def hello_world_attach_with_name_api(self): 160 """Create target, spawn a process, and attach to it by name.""" 161 162 target = self.dbg.CreateTarget(self.exe) 163 164 # Spawn a new process 165 popen = self.spawnSubprocess(self.exe, ["abc", "xyz"]) 166 self.addTearDownHook(self.cleanupSubprocesses) 167 168 # Give the subprocess time to start and wait for user input 169 time.sleep(0.25) 170 171 listener = lldb.SBListener("my.attach.listener") 172 error = lldb.SBError() 173 # Pass 'False' since we don't want to wait for new instance of "hello_world" to be launched. 174 name = os.path.basename(self.exe) 175 176 # While we're at it, make sure that passing a None as the process name 177 # does not hang LLDB. 178 target.AttachToProcessWithName(listener, None, False, error) 179 # Also boundary condition test ConnectRemote(), too. 180 target.ConnectRemote(listener, None, None, error) 181 182 process = target.AttachToProcessWithName(listener, name, False, error) 183 184 self.assertTrue(error.Success() and process, PROCESS_IS_VALID) 185 186 # Verify that after attach, our selected target indeed matches name. 187 self.expect(self.dbg.GetSelectedTarget().GetExecutable().GetFilename(), exe=False, 188 startstr = name) 189 190 # Let's check the stack traces of the attached process. 191 import lldbutil 192 stacktraces = lldbutil.print_stacktraces(process, string_buffer=True) 193 self.expect(stacktraces, exe=False, 194 substrs = ['main.c:%d' % self.line2, 195 '(int)argc=3']) 196 197 198if __name__ == '__main__': 199 import atexit 200 lldb.SBDebugger.Initialize() 201 atexit.register(lambda: lldb.SBDebugger.Terminate()) 202 unittest2.main() 203