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