199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest that we read the function starts section. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprecht 699451b44SJordan Rupprechtimport lldb 799451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 899451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 999451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 1099451b44SJordan Rupprecht 1199451b44SJordan Rupprechtexe_name = "StripMe" # Must match Makefile 1299451b44SJordan Rupprecht 1399451b44SJordan Rupprecht 142238dcc3SJonas Devlieghereclass FunctionStartsTestCase(TestBase): 1599451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1699451b44SJordan Rupprecht 1799451b44SJordan Rupprecht @skipIfRemote 1899451b44SJordan Rupprecht @skipUnlessDarwin 192238dcc3SJonas Devlieghere @skipIf(compiler="clang", compiler_version=["<", "13.0"]) 2099451b44SJordan Rupprecht def test_function_starts_binary(self): 2199451b44SJordan Rupprecht """Test that we make synthetic symbols when we have the binary.""" 222238dcc3SJonas Devlieghere self.build(dictionary={"CODESIGN": ""}) # Binary is getting stripped later. 2399451b44SJordan Rupprecht self.do_function_starts(False) 2499451b44SJordan Rupprecht 2599451b44SJordan Rupprecht @skipIfRemote 2699451b44SJordan Rupprecht @skipUnlessDarwin 272238dcc3SJonas Devlieghere @skipIf(compiler="clang", compiler_version=["<", "13.0"]) 2899451b44SJordan Rupprecht def test_function_starts_no_binary(self): 2999451b44SJordan Rupprecht """Test that we make synthetic symbols when we don't have the binary""" 302238dcc3SJonas Devlieghere self.build(dictionary={"CODESIGN": ""}) # Binary is getting stripped later. 3199451b44SJordan Rupprecht self.do_function_starts(True) 3299451b44SJordan Rupprecht 3399451b44SJordan Rupprecht def do_function_starts(self, in_memory): 3499451b44SJordan Rupprecht """Run the binary, stop at our unstripped function, 3599451b44SJordan Rupprecht make sure the caller has synthetic symbols""" 3699451b44SJordan Rupprecht 378ee35c55SJason Molenda exe = os.path.realpath(self.getBuildArtifact(exe_name)) 3899451b44SJordan Rupprecht # Now strip the binary, but leave externals so we can break on dont_strip_me. 398e3de91cSPavel Labath self.runBuildCommand(["strip", "-u", "-x", "-S", exe]) 4099451b44SJordan Rupprecht 4199451b44SJordan Rupprecht # Use a file as a synchronization point between test and inferior. 422238dcc3SJonas Devlieghere pid_file_path = lldbutil.append_to_process_working_directory( 432238dcc3SJonas Devlieghere self, "token_pid_%d" % (int(os.getpid())) 442238dcc3SJonas Devlieghere ) 4599451b44SJordan Rupprecht self.addTearDownHook( 462238dcc3SJonas Devlieghere lambda: self.run_platform_command("rm %s" % (pid_file_path)) 472238dcc3SJonas Devlieghere ) 4899451b44SJordan Rupprecht 4999451b44SJordan Rupprecht popen = self.spawnSubprocess(exe, [pid_file_path]) 5099451b44SJordan Rupprecht 5199451b44SJordan Rupprecht # Wait until process has fully started up. 5299451b44SJordan Rupprecht pid = lldbutil.wait_for_file_on_target(self, pid_file_path) 5399451b44SJordan Rupprecht 5499451b44SJordan Rupprecht if in_memory: 5599451b44SJordan Rupprecht remove_file(exe) 5699451b44SJordan Rupprecht 5799451b44SJordan Rupprecht target = self.dbg.CreateTarget(None) 5899451b44SJordan Rupprecht self.assertTrue(target.IsValid(), "Got a vaid empty target.") 5999451b44SJordan Rupprecht error = lldb.SBError() 6099451b44SJordan Rupprecht attach_info = lldb.SBAttachInfo() 6199451b44SJordan Rupprecht attach_info.SetProcessID(popen.pid) 6299451b44SJordan Rupprecht attach_info.SetIgnoreExisting(False) 6399451b44SJordan Rupprecht process = target.Attach(attach_info, error) 64779bbbf2SDave Lee self.assertSuccess(error, "Didn't attach successfully to %d" % (popen.pid)) 6599451b44SJordan Rupprecht 6699451b44SJordan Rupprecht bkpt = target.BreakpointCreateByName("dont_strip_me", exe) 67*9c246882SJordan Rupprecht self.assertGreater( 68*9c246882SJordan Rupprecht bkpt.GetNumLocations(), 0, "Didn't set the dont_strip_me bkpt." 692238dcc3SJonas Devlieghere ) 7099451b44SJordan Rupprecht 7199451b44SJordan Rupprecht threads = lldbutil.continue_to_breakpoint(process, bkpt) 7299451b44SJordan Rupprecht self.assertEqual(len(threads), 1, "Didn't hit my breakpoint.") 7399451b44SJordan Rupprecht 7499451b44SJordan Rupprecht # Our caller frame should have been stripped. Make sure we made a synthetic symbol 7599451b44SJordan Rupprecht # for it: 7699451b44SJordan Rupprecht thread = threads[0] 77*9c246882SJordan Rupprecht self.assertGreater(thread.num_frames, 1, "Couldn't backtrace.") 7899451b44SJordan Rupprecht name = thread.frame[1].GetFunctionName() 7999451b44SJordan Rupprecht self.assertTrue(name.startswith("___lldb_unnamed_symbol")) 80