199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTestlldb Python SBFrame APIs IsInlined() and GetFunctionName().
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprechtfrom __future__ import print_function
699451b44SJordan Rupprecht
799451b44SJordan Rupprecht
899451b44SJordan Rupprechtimport lldb
999451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
1099451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1199451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprecht
1499451b44SJordan Rupprechtclass InlinedFrameAPITestCase(TestBase):
1599451b44SJordan Rupprecht
1699451b44SJordan Rupprecht    def setUp(self):
1799451b44SJordan Rupprecht        # Call super's setUp().
1899451b44SJordan Rupprecht        TestBase.setUp(self)
1999451b44SJordan Rupprecht        # Find the line number to of function 'c'.
2099451b44SJordan Rupprecht        self.source = 'inlines.c'
2199451b44SJordan Rupprecht        self.first_stop = line_number(
2299451b44SJordan Rupprecht            self.source, '// This should correspond to the first break stop.')
2399451b44SJordan Rupprecht        self.second_stop = line_number(
2499451b44SJordan Rupprecht            self.source, '// This should correspond to the second break stop.')
2599451b44SJordan Rupprecht
2699451b44SJordan Rupprecht    def test_stop_at_outer_inline(self):
2799451b44SJordan Rupprecht        """Exercise SBFrame.IsInlined() and SBFrame.GetFunctionName()."""
2899451b44SJordan Rupprecht        self.build()
2999451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
3099451b44SJordan Rupprecht
3199451b44SJordan Rupprecht        # Create a target by the debugger.
3299451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
3399451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
3499451b44SJordan Rupprecht
3599451b44SJordan Rupprecht        # Now create a breakpoint on main.c by the name of 'inner_inline'.
3699451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateByName('inner_inline', 'a.out')
37b321b429SJonas Devlieghere        self.trace("breakpoint:", breakpoint)
3899451b44SJordan Rupprecht        self.assertTrue(breakpoint and
3999451b44SJordan Rupprecht                        breakpoint.GetNumLocations() > 1,
4099451b44SJordan Rupprecht                        VALID_BREAKPOINT)
4199451b44SJordan Rupprecht
4299451b44SJordan Rupprecht        # Now launch the process, and do not stop at the entry point.
4399451b44SJordan Rupprecht        process = target.LaunchSimple(
4499451b44SJordan Rupprecht            None, None, self.get_process_working_directory())
4599451b44SJordan Rupprecht
4699451b44SJordan Rupprecht        process = target.GetProcess()
47*47c4c6a7SDave Lee        self.assertState(process.GetState(), lldb.eStateStopped,
4899451b44SJordan Rupprecht                         PROCESS_STOPPED)
4999451b44SJordan Rupprecht
5099451b44SJordan Rupprecht        import lldbsuite.test.lldbutil as lldbutil
5199451b44SJordan Rupprecht        stack_traces1 = lldbutil.print_stacktraces(process, string_buffer=True)
5299451b44SJordan Rupprecht        if self.TraceOn():
5399451b44SJordan Rupprecht            print(
5499451b44SJordan Rupprecht                "Full stack traces when first stopped on the breakpoint 'inner_inline':")
5599451b44SJordan Rupprecht            print(stack_traces1)
5699451b44SJordan Rupprecht
5799451b44SJordan Rupprecht        # The first breakpoint should correspond to an inlined call frame.
5899451b44SJordan Rupprecht        # If it's an inlined call frame, expect to find, in the stack trace,
5999451b44SJordan Rupprecht        # that there is a frame which corresponds to the following call site:
6099451b44SJordan Rupprecht        #
6199451b44SJordan Rupprecht        #     outer_inline (argc);
6299451b44SJordan Rupprecht        #
6399451b44SJordan Rupprecht        thread = lldbutil.get_stopped_thread(
6499451b44SJordan Rupprecht            process, lldb.eStopReasonBreakpoint)
6599451b44SJordan Rupprecht        self.assertIsNotNone(thread)
6699451b44SJordan Rupprecht
6799451b44SJordan Rupprecht        frame0 = thread.GetFrameAtIndex(0)
6899451b44SJordan Rupprecht        if frame0.IsInlined():
6999451b44SJordan Rupprecht            filename = frame0.GetLineEntry().GetFileSpec().GetFilename()
70619e2e09SDave Lee            self.assertEqual(filename, self.source)
7199451b44SJordan Rupprecht            self.expect(
7299451b44SJordan Rupprecht                stack_traces1, "First stop at %s:%d" %
7399451b44SJordan Rupprecht                (self.source, self.first_stop), exe=False, substrs=[
7499451b44SJordan Rupprecht                    '%s:%d' %
7599451b44SJordan Rupprecht                    (self.source, self.first_stop)])
7699451b44SJordan Rupprecht
7799451b44SJordan Rupprecht            # Expect to break again for the second time.
7899451b44SJordan Rupprecht            process.Continue()
79*47c4c6a7SDave Lee            self.assertState(process.GetState(), lldb.eStateStopped,
8099451b44SJordan Rupprecht                             PROCESS_STOPPED)
8199451b44SJordan Rupprecht            stack_traces2 = lldbutil.print_stacktraces(
8299451b44SJordan Rupprecht                process, string_buffer=True)
8399451b44SJordan Rupprecht            if self.TraceOn():
8499451b44SJordan Rupprecht                print(
8599451b44SJordan Rupprecht                    "Full stack traces when stopped on the breakpoint 'inner_inline' for the second time:")
8699451b44SJordan Rupprecht                print(stack_traces2)
8799451b44SJordan Rupprecht                self.expect(
8899451b44SJordan Rupprecht                    stack_traces2, "Second stop at %s:%d" %
8999451b44SJordan Rupprecht                    (self.source, self.second_stop), exe=False, substrs=[
9099451b44SJordan Rupprecht                        '%s:%d' %
9199451b44SJordan Rupprecht                        (self.source, self.second_stop)])
92