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