1*99451b44SJordan Rupprecht"""
2*99451b44SJordan RupprechtTest display and Python APIs on file and class static variables.
3*99451b44SJordan Rupprecht"""
4*99451b44SJordan Rupprecht
5*99451b44SJordan Rupprecht
6*99451b44SJordan Rupprecht
7*99451b44SJordan Rupprechtimport lldb
8*99451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
9*99451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
10*99451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
11*99451b44SJordan Rupprecht
12*99451b44SJordan Rupprecht
13*99451b44SJordan Rupprechtclass StaticVariableTestCase(TestBase):
14*99451b44SJordan Rupprecht
15*99451b44SJordan Rupprecht    mydir = TestBase.compute_mydir(__file__)
16*99451b44SJordan Rupprecht
17*99451b44SJordan Rupprecht    def setUp(self):
18*99451b44SJordan Rupprecht        # Call super's setUp().
19*99451b44SJordan Rupprecht        TestBase.setUp(self)
20*99451b44SJordan Rupprecht        # Find the line number to break at.
21*99451b44SJordan Rupprecht        self.line = line_number('main.cpp', '// Set break point at this line.')
22*99451b44SJordan Rupprecht
23*99451b44SJordan Rupprecht    def test_with_run_command(self):
24*99451b44SJordan Rupprecht        """Test that file and class static variables display correctly."""
25*99451b44SJordan Rupprecht        self.build()
26*99451b44SJordan Rupprecht        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
27*99451b44SJordan Rupprecht
28*99451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
29*99451b44SJordan Rupprecht            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
30*99451b44SJordan Rupprecht
31*99451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
32*99451b44SJordan Rupprecht
33*99451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint.
34*99451b44SJordan Rupprecht        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
35*99451b44SJordan Rupprecht                    substrs=['stopped',
36*99451b44SJordan Rupprecht                             'stop reason = breakpoint'])
37*99451b44SJordan Rupprecht
38*99451b44SJordan Rupprecht        # Global variables are no longer displayed with the "frame variable"
39*99451b44SJordan Rupprecht        # command.
40*99451b44SJordan Rupprecht        self.expect(
41*99451b44SJordan Rupprecht            'target variable A::g_points',
42*99451b44SJordan Rupprecht            VARIABLES_DISPLAYED_CORRECTLY,
43*99451b44SJordan Rupprecht            patterns=['\(PointType \[[1-9]*\]\) A::g_points = {'])
44*99451b44SJordan Rupprecht        self.expect('target variable g_points', VARIABLES_DISPLAYED_CORRECTLY,
45*99451b44SJordan Rupprecht                    substrs=['(PointType [2]) g_points'])
46*99451b44SJordan Rupprecht
47*99451b44SJordan Rupprecht        # On Mac OS X, gcc 4.2 emits the wrong debug info for A::g_points.
48*99451b44SJordan Rupprecht        # A::g_points is an array of two elements.
49*99451b44SJordan Rupprecht        if self.platformIsDarwin() or self.getPlatform() == "linux":
50*99451b44SJordan Rupprecht            self.expect(
51*99451b44SJordan Rupprecht                "target variable A::g_points[1].x",
52*99451b44SJordan Rupprecht                VARIABLES_DISPLAYED_CORRECTLY,
53*99451b44SJordan Rupprecht                startstr="(int) A::g_points[1].x = 11")
54*99451b44SJordan Rupprecht
55*99451b44SJordan Rupprecht    @expectedFailureAll(
56*99451b44SJordan Rupprecht        compiler=["gcc"],
57*99451b44SJordan Rupprecht        bugnumber="Compiler emits incomplete debug info")
58*99451b44SJordan Rupprecht    @expectedFailureAll(
59*99451b44SJordan Rupprecht        compiler=["clang"],
60*99451b44SJordan Rupprecht        compiler_version=["<", "3.9"],
61*99451b44SJordan Rupprecht        bugnumber='llvm.org/pr20550')
62*99451b44SJordan Rupprecht    def test_with_run_command_complete(self):
63*99451b44SJordan Rupprecht        """
64*99451b44SJordan Rupprecht        Test that file and class static variables display correctly with
65*99451b44SJordan Rupprecht        complete debug information.
66*99451b44SJordan Rupprecht        """
67*99451b44SJordan Rupprecht        self.build()
68*99451b44SJordan Rupprecht        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
69*99451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
70*99451b44SJordan Rupprecht
71*99451b44SJordan Rupprecht        # Global variables are no longer displayed with the "frame variable"
72*99451b44SJordan Rupprecht        # command.
73*99451b44SJordan Rupprecht        self.expect(
74*99451b44SJordan Rupprecht            'target variable A::g_points',
75*99451b44SJordan Rupprecht            VARIABLES_DISPLAYED_CORRECTLY,
76*99451b44SJordan Rupprecht            patterns=[
77*99451b44SJordan Rupprecht                '\(PointType \[[1-9]*\]\) A::g_points = {', '(x = 1, y = 2)',
78*99451b44SJordan Rupprecht                '(x = 11, y = 22)'
79*99451b44SJordan Rupprecht            ])
80*99451b44SJordan Rupprecht
81*99451b44SJordan Rupprecht        # Ensure that we take the context into account and only print
82*99451b44SJordan Rupprecht        # A::g_points.
83*99451b44SJordan Rupprecht        self.expect(
84*99451b44SJordan Rupprecht            'target variable A::g_points',
85*99451b44SJordan Rupprecht            VARIABLES_DISPLAYED_CORRECTLY,
86*99451b44SJordan Rupprecht            matching=False,
87*99451b44SJordan Rupprecht            patterns=['(x = 3, y = 4)', '(x = 33, y = 44)'])
88*99451b44SJordan Rupprecht
89*99451b44SJordan Rupprecht        # Finally, ensure that we print both points when not specifying a
90*99451b44SJordan Rupprecht        # context.
91*99451b44SJordan Rupprecht        self.expect(
92*99451b44SJordan Rupprecht            'target variable g_points',
93*99451b44SJordan Rupprecht            VARIABLES_DISPLAYED_CORRECTLY,
94*99451b44SJordan Rupprecht            substrs=[
95*99451b44SJordan Rupprecht                '(PointType [2]) g_points', '(x = 1, y = 2)',
96*99451b44SJordan Rupprecht                '(x = 11, y = 22)', '(x = 3, y = 4)', '(x = 33, y = 44)'
97*99451b44SJordan Rupprecht            ])
98*99451b44SJordan Rupprecht
99*99451b44SJordan Rupprecht    @expectedFailureAll(
100*99451b44SJordan Rupprecht        compiler=["gcc"],
101*99451b44SJordan Rupprecht        bugnumber="Compiler emits incomplete debug info")
102*99451b44SJordan Rupprecht    @expectedFailureAll(
103*99451b44SJordan Rupprecht        compiler=["clang"],
104*99451b44SJordan Rupprecht        compiler_version=["<", "3.9"],
105*99451b44SJordan Rupprecht        bugnumber='llvm.org/pr20550')
106*99451b44SJordan Rupprecht    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")
107*99451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
108*99451b44SJordan Rupprecht    def test_with_python_api(self):
109*99451b44SJordan Rupprecht        """Test Python APIs on file and class static variables."""
110*99451b44SJordan Rupprecht        self.build()
111*99451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
112*99451b44SJordan Rupprecht
113*99451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
114*99451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
115*99451b44SJordan Rupprecht
116*99451b44SJordan Rupprecht        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
117*99451b44SJordan Rupprecht        self.assertTrue(breakpoint, VALID_BREAKPOINT)
118*99451b44SJordan Rupprecht
119*99451b44SJordan Rupprecht        # Now launch the process, and do not stop at entry point.
120*99451b44SJordan Rupprecht        process = target.LaunchSimple(
121*99451b44SJordan Rupprecht            None, None, self.get_process_working_directory())
122*99451b44SJordan Rupprecht        self.assertTrue(process, PROCESS_IS_VALID)
123*99451b44SJordan Rupprecht
124*99451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint.
125*99451b44SJordan Rupprecht        thread = lldbutil.get_stopped_thread(
126*99451b44SJordan Rupprecht            process, lldb.eStopReasonBreakpoint)
127*99451b44SJordan Rupprecht        self.assertIsNotNone(thread)
128*99451b44SJordan Rupprecht
129*99451b44SJordan Rupprecht        # Get the SBValue of 'A::g_points' and 'g_points'.
130*99451b44SJordan Rupprecht        frame = thread.GetFrameAtIndex(0)
131*99451b44SJordan Rupprecht
132*99451b44SJordan Rupprecht        # arguments =>     False
133*99451b44SJordan Rupprecht        # locals =>        False
134*99451b44SJordan Rupprecht        # statics =>       True
135*99451b44SJordan Rupprecht        # in_scope_only => False
136*99451b44SJordan Rupprecht        valList = frame.GetVariables(False, False, True, False)
137*99451b44SJordan Rupprecht
138*99451b44SJordan Rupprecht        for val in valList:
139*99451b44SJordan Rupprecht            self.DebugSBValue(val)
140*99451b44SJordan Rupprecht            name = val.GetName()
141*99451b44SJordan Rupprecht            self.assertTrue(name in ['g_points', 'A::g_points'])
142*99451b44SJordan Rupprecht            if name == 'g_points':
143*99451b44SJordan Rupprecht                self.assertTrue(
144*99451b44SJordan Rupprecht                    val.GetValueType() == lldb.eValueTypeVariableStatic)
145*99451b44SJordan Rupprecht                self.assertEqual(val.GetNumChildren(), 2)
146*99451b44SJordan Rupprecht            elif name == 'A::g_points':
147*99451b44SJordan Rupprecht                self.assertTrue(
148*99451b44SJordan Rupprecht                    val.GetValueType() == lldb.eValueTypeVariableGlobal)
149*99451b44SJordan Rupprecht                self.assertEqual(val.GetNumChildren(), 2)
150*99451b44SJordan Rupprecht                child1 = val.GetChildAtIndex(1)
151*99451b44SJordan Rupprecht                self.DebugSBValue(child1)
152*99451b44SJordan Rupprecht                child1_x = child1.GetChildAtIndex(0)
153*99451b44SJordan Rupprecht                self.DebugSBValue(child1_x)
154*99451b44SJordan Rupprecht                self.assertTrue(child1_x.GetTypeName() == 'int' and
155*99451b44SJordan Rupprecht                                child1_x.GetValue() == '11')
156*99451b44SJordan Rupprecht
157*99451b44SJordan Rupprecht        # SBFrame.FindValue() should also work.
158*99451b44SJordan Rupprecht        val = frame.FindValue("A::g_points", lldb.eValueTypeVariableGlobal)
159*99451b44SJordan Rupprecht        self.DebugSBValue(val)
160*99451b44SJordan Rupprecht        self.assertTrue(val.GetName() == 'A::g_points')
161*99451b44SJordan Rupprecht
162*99451b44SJordan Rupprecht        # Also exercise the "parameter" and "local" scopes while we are at it.
163*99451b44SJordan Rupprecht        val = frame.FindValue("argc", lldb.eValueTypeVariableArgument)
164*99451b44SJordan Rupprecht        self.DebugSBValue(val)
165*99451b44SJordan Rupprecht        self.assertTrue(val.GetName() == 'argc')
166*99451b44SJordan Rupprecht
167*99451b44SJordan Rupprecht        val = frame.FindValue("argv", lldb.eValueTypeVariableArgument)
168*99451b44SJordan Rupprecht        self.DebugSBValue(val)
169*99451b44SJordan Rupprecht        self.assertTrue(val.GetName() == 'argv')
170*99451b44SJordan Rupprecht
171*99451b44SJordan Rupprecht        val = frame.FindValue("hello_world", lldb.eValueTypeVariableLocal)
172*99451b44SJordan Rupprecht        self.DebugSBValue(val)
173*99451b44SJordan Rupprecht        self.assertTrue(val.GetName() == 'hello_world')
174