1""" 2Test that we read the function starts section. 3""" 4 5 6 7import lldb 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10from lldbsuite.test import lldbutil 11 12exe_name = "StripMe" # Must match Makefile 13 14class FunctionStartsTestCase(TestBase): 15 16 NO_DEBUG_INFO_TESTCASE = True 17 18 @skipIfRemote 19 @skipUnlessDarwin 20 def test_function_starts_binary(self): 21 """Test that we make synthetic symbols when we have the binary.""" 22 self.build(dictionary={'CODESIGN': ''}) # Binary is getting stripped later. 23 self.do_function_starts(False) 24 25 @skipIfRemote 26 @skipUnlessDarwin 27 def test_function_starts_no_binary(self): 28 """Test that we make synthetic symbols when we don't have the binary""" 29 self.build(dictionary={'CODESIGN': ''}) # Binary is getting stripped later. 30 self.do_function_starts(True) 31 32 def do_function_starts(self, in_memory): 33 """Run the binary, stop at our unstripped function, 34 make sure the caller has synthetic symbols""" 35 36 exe = os.path.realpath(self.getBuildArtifact(exe_name)) 37 # Now strip the binary, but leave externals so we can break on dont_strip_me. 38 self.runBuildCommand(["strip", "-u", "-x", "-S", exe]) 39 40 # Use a file as a synchronization point between test and inferior. 41 pid_file_path = lldbutil.append_to_process_working_directory(self, 42 "token_pid_%d" % (int(os.getpid()))) 43 self.addTearDownHook( 44 lambda: self.run_platform_command( 45 "rm %s" % 46 (pid_file_path))) 47 48 popen = self.spawnSubprocess(exe, [pid_file_path]) 49 50 # Wait until process has fully started up. 51 pid = lldbutil.wait_for_file_on_target(self, pid_file_path) 52 53 if in_memory: 54 remove_file(exe) 55 56 target = self.dbg.CreateTarget(None) 57 self.assertTrue(target.IsValid(), "Got a vaid empty target.") 58 error = lldb.SBError() 59 attach_info = lldb.SBAttachInfo() 60 attach_info.SetProcessID(popen.pid) 61 attach_info.SetIgnoreExisting(False) 62 process = target.Attach(attach_info, error) 63 self.assertSuccess(error, "Didn't attach successfully to %d"%(popen.pid)) 64 65 bkpt = target.BreakpointCreateByName("dont_strip_me", exe) 66 self.assertTrue(bkpt.GetNumLocations() > 0, "Didn't set the dont_strip_me bkpt.") 67 68 threads = lldbutil.continue_to_breakpoint(process, bkpt) 69 self.assertEqual(len(threads), 1, "Didn't hit my breakpoint.") 70 71 # Our caller frame should have been stripped. Make sure we made a synthetic symbol 72 # for it: 73 thread = threads[0] 74 self.assertTrue(thread.num_frames > 1, "Couldn't backtrace.") 75 name = thread.frame[1].GetFunctionName() 76 self.assertTrue(name.startswith("___lldb_unnamed_symbol")) 77 78 79 80