199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest that we read the function starts section.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprecht
699451b44SJordan Rupprecht
799451b44SJordan Rupprechtimport lldb
899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1099451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1199451b44SJordan Rupprecht
1299451b44SJordan Rupprechtexe_name = "StripMe"  # Must match Makefile
1399451b44SJordan Rupprecht
1499451b44SJordan Rupprechtclass FunctionStartsTestCase(TestBase):
1599451b44SJordan Rupprecht
1699451b44SJordan Rupprecht    NO_DEBUG_INFO_TESTCASE = True
1799451b44SJordan Rupprecht
1899451b44SJordan Rupprecht    @skipIfRemote
1999451b44SJordan Rupprecht    @skipUnlessDarwin
2099451b44SJordan Rupprecht    def test_function_starts_binary(self):
2199451b44SJordan Rupprecht        """Test that we make synthetic symbols when we have the binary."""
22825a08f8SJonas 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
2799451b44SJordan Rupprecht    def test_function_starts_no_binary(self):
2899451b44SJordan Rupprecht        """Test that we make synthetic symbols when we don't have the binary"""
29825a08f8SJonas Devlieghere        self.build(dictionary={'CODESIGN': ''}) # Binary is getting stripped later.
3099451b44SJordan Rupprecht        self.do_function_starts(True)
3199451b44SJordan Rupprecht
3299451b44SJordan Rupprecht    def do_function_starts(self, in_memory):
3399451b44SJordan Rupprecht        """Run the binary, stop at our unstripped function,
3499451b44SJordan Rupprecht           make sure the caller has synthetic symbols"""
3599451b44SJordan Rupprecht
36*8ee35c55SJason Molenda        exe = os.path.realpath(self.getBuildArtifact(exe_name))
3799451b44SJordan Rupprecht        # Now strip the binary, but leave externals so we can break on dont_strip_me.
388e3de91cSPavel Labath        self.runBuildCommand(["strip", "-u", "-x", "-S", exe])
3999451b44SJordan Rupprecht
4099451b44SJordan Rupprecht        # Use a file as a synchronization point between test and inferior.
4199451b44SJordan Rupprecht        pid_file_path = lldbutil.append_to_process_working_directory(self,
4299451b44SJordan Rupprecht            "token_pid_%d" % (int(os.getpid())))
4399451b44SJordan Rupprecht        self.addTearDownHook(
4499451b44SJordan Rupprecht            lambda: self.run_platform_command(
4599451b44SJordan Rupprecht                "rm %s" %
4699451b44SJordan Rupprecht                (pid_file_path)))
4799451b44SJordan Rupprecht
4899451b44SJordan Rupprecht        popen = self.spawnSubprocess(exe, [pid_file_path])
4999451b44SJordan Rupprecht
5099451b44SJordan Rupprecht        # Wait until process has fully started up.
5199451b44SJordan Rupprecht        pid = lldbutil.wait_for_file_on_target(self, pid_file_path)
5299451b44SJordan Rupprecht
5399451b44SJordan Rupprecht        if in_memory:
5499451b44SJordan Rupprecht          remove_file(exe)
5599451b44SJordan Rupprecht
5699451b44SJordan Rupprecht        target = self.dbg.CreateTarget(None)
5799451b44SJordan Rupprecht        self.assertTrue(target.IsValid(), "Got a vaid empty target.")
5899451b44SJordan Rupprecht        error = lldb.SBError()
5999451b44SJordan Rupprecht        attach_info = lldb.SBAttachInfo()
6099451b44SJordan Rupprecht        attach_info.SetProcessID(popen.pid)
6199451b44SJordan Rupprecht        attach_info.SetIgnoreExisting(False)
6299451b44SJordan Rupprecht        process = target.Attach(attach_info, error)
63779bbbf2SDave Lee        self.assertSuccess(error, "Didn't attach successfully to %d"%(popen.pid))
6499451b44SJordan Rupprecht
6599451b44SJordan Rupprecht        bkpt = target.BreakpointCreateByName("dont_strip_me", exe)
6699451b44SJordan Rupprecht        self.assertTrue(bkpt.GetNumLocations() > 0, "Didn't set the dont_strip_me bkpt.")
6799451b44SJordan Rupprecht
6899451b44SJordan Rupprecht        threads = lldbutil.continue_to_breakpoint(process, bkpt)
6999451b44SJordan Rupprecht        self.assertEqual(len(threads), 1, "Didn't hit my breakpoint.")
7099451b44SJordan Rupprecht
7199451b44SJordan Rupprecht        # Our caller frame should have been stripped.  Make sure we made a synthetic symbol
7299451b44SJordan Rupprecht        # for it:
7399451b44SJordan Rupprecht        thread = threads[0]
7499451b44SJordan Rupprecht        self.assertTrue(thread.num_frames > 1, "Couldn't backtrace.")
7599451b44SJordan Rupprecht        name = thread.frame[1].GetFunctionName()
7699451b44SJordan Rupprecht        self.assertTrue(name.startswith("___lldb_unnamed_symbol"))
7799451b44SJordan Rupprecht
7899451b44SJordan Rupprecht
7999451b44SJordan Rupprecht
80