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 mydir = TestBase.compute_mydir(__file__) 17 18 NO_DEBUG_INFO_TESTCASE = True 19 20 @skipIfRemote 21 @skipUnlessDarwin 22 def test_function_starts_binary(self): 23 """Test that we make synthetic symbols when we have the binary.""" 24 self.build(dictionary={'CODESIGN': ''}) # Binary is getting stripped later. 25 self.do_function_starts(False) 26 27 @skipIfRemote 28 @skipUnlessDarwin 29 def test_function_starts_no_binary(self): 30 """Test that we make synthetic symbols when we don't have the binary""" 31 self.build(dictionary={'CODESIGN': ''}) # Binary is getting stripped later. 32 self.do_function_starts(True) 33 34 def do_function_starts(self, in_memory): 35 """Run the binary, stop at our unstripped function, 36 make sure the caller has synthetic symbols""" 37 38 exe = self.getBuildArtifact(exe_name) 39 # Now strip the binary, but leave externals so we can break on dont_strip_me. 40 try: 41 fail_str = system([["strip", "-u", "-x", "-S", exe]]) 42 except CalledProcessError as cmd_error: 43 self.fail("Strip failed: %d"%(cmd_error.returncode)) 44 45 # Use a file as a synchronization point between test and inferior. 46 pid_file_path = lldbutil.append_to_process_working_directory(self, 47 "token_pid_%d" % (int(os.getpid()))) 48 self.addTearDownHook( 49 lambda: self.run_platform_command( 50 "rm %s" % 51 (pid_file_path))) 52 53 popen = self.spawnSubprocess(exe, [pid_file_path]) 54 55 # Wait until process has fully started up. 56 pid = lldbutil.wait_for_file_on_target(self, pid_file_path) 57 58 if in_memory: 59 remove_file(exe) 60 61 target = self.dbg.CreateTarget(None) 62 self.assertTrue(target.IsValid(), "Got a vaid empty target.") 63 error = lldb.SBError() 64 attach_info = lldb.SBAttachInfo() 65 attach_info.SetProcessID(popen.pid) 66 attach_info.SetIgnoreExisting(False) 67 process = target.Attach(attach_info, error) 68 self.assertTrue(error.Success(), "Didn't attach successfully to %d: %s"%(popen.pid, error.GetCString())) 69 70 bkpt = target.BreakpointCreateByName("dont_strip_me", exe) 71 self.assertTrue(bkpt.GetNumLocations() > 0, "Didn't set the dont_strip_me bkpt.") 72 73 threads = lldbutil.continue_to_breakpoint(process, bkpt) 74 self.assertEqual(len(threads), 1, "Didn't hit my breakpoint.") 75 76 # Our caller frame should have been stripped. Make sure we made a synthetic symbol 77 # for it: 78 thread = threads[0] 79 self.assertTrue(thread.num_frames > 1, "Couldn't backtrace.") 80 name = thread.frame[1].GetFunctionName() 81 self.assertTrue(name.startswith("___lldb_unnamed_symbol")) 82 83 84 85