xref: /llvm-project/lldb/test/API/macosx/function-starts/TestFunctionStarts.py (revision 9c2468821ec51defd09c246fea4a47886fff8c01)
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