1"""
2Test SBSymbolContext APIs.
3"""
4
5from __future__ import print_function
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12
13class SymbolContextAPITestCase(TestBase):
14
15    mydir = TestBase.compute_mydir(__file__)
16
17    def setUp(self):
18        # Call super's setUp().
19        TestBase.setUp(self)
20        # Find the line number to of function 'c'.
21        self.line = line_number(
22            'main.c', '// Find the line number of function "c" here.')
23
24    @add_test_categories(['pyapi'])
25    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
26    @skipIfReproducer # FIXME: Unexpected packet during (passive) replay
27    def test(self):
28        """Exercise SBSymbolContext API extensively."""
29        self.build()
30        exe = self.getBuildArtifact("a.out")
31
32        # Create a target by the debugger.
33        target = self.dbg.CreateTarget(exe)
34        self.assertTrue(target, VALID_TARGET)
35
36        # Now create a breakpoint on main.c by name 'c'.
37        breakpoint = target.BreakpointCreateByName('c', exe)
38        self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1,
39                        VALID_BREAKPOINT)
40
41        # Now launch the process, and do not stop at entry point.
42        process = target.LaunchSimple(None, None,
43                                      self.get_process_working_directory())
44        self.assertTrue(process, PROCESS_IS_VALID)
45
46        # Frame #0 should be on self.line.
47        thread = lldbutil.get_stopped_thread(process,
48                                             lldb.eStopReasonBreakpoint)
49        self.assertTrue(thread.IsValid(),
50                        "There should be a thread stopped due to breakpoint")
51        frame0 = thread.GetFrameAtIndex(0)
52        self.assertTrue(frame0.GetLineEntry().GetLine() == self.line)
53
54        # Now get the SBSymbolContext from this frame.  We want everything. :-)
55        context = frame0.GetSymbolContext(lldb.eSymbolContextEverything)
56        self.assertTrue(context)
57
58        # Get the description of this module.
59        module = context.GetModule()
60        desc = lldbutil.get_description(module)
61        self.expect(desc, "The module should match", exe=False, substrs=[exe])
62
63        compileUnit = context.GetCompileUnit()
64        self.expect(str(compileUnit),
65                    "The compile unit should match",
66                    exe=False,
67                    substrs=[self.getSourcePath('main.c')])
68
69        function = context.GetFunction()
70        self.assertTrue(function)
71
72        block = context.GetBlock()
73        self.assertTrue(block)
74
75        lineEntry = context.GetLineEntry()
76        self.expect(lineEntry.GetFileSpec().GetDirectory(),
77                    "The line entry should have the correct directory",
78                    exe=False,
79                    substrs=[self.mydir])
80        self.expect(lineEntry.GetFileSpec().GetFilename(),
81                    "The line entry should have the correct filename",
82                    exe=False,
83                    substrs=['main.c'])
84        self.assertTrue(lineEntry.GetLine() == self.line,
85                        "The line entry's line number should match ")
86
87        symbol = context.GetSymbol()
88        self.assertTrue(
89            function.GetName() == symbol.GetName() and symbol.GetName() == 'c',
90            "The symbol name should be 'c'")
91
92        sc_list = lldb.SBSymbolContextList()
93        sc_list.Append(context)
94        self.assertEqual(len(sc_list), 1)
95        for sc in sc_list:
96            self.assertEqual(lineEntry, sc.GetLineEntry())
97