TestStaticVariables.py revision a749646c914e6731cb789bcd0f25e5740c47e722
1"""
2Test display and Python APIs on file and class static variables.
3"""
4
5import os, time
6import unittest2
7import lldb
8from lldbtest import *
9import lldbutil
10
11class StaticVariableTestCase(TestBase):
12
13    mydir = os.path.join("lang", "cpp", "class_static")
14    failing_compilers = ['clang', 'gcc']
15
16    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
17    @dsym_test
18    def test_with_dsym_and_run_command(self):
19        """Test that file and class static variables display correctly."""
20        self.buildDsym()
21        self.static_variable_commands()
22
23    @expectedFailureLinux('llvm.org/pr15261', failing_compilers) # lldb on Linux does not display the size of (class or file)static arrays
24    @dwarf_test
25    def test_with_dwarf_and_run_command(self):
26        """Test that file and class static variables display correctly."""
27        self.buildDwarf()
28        self.static_variable_commands()
29
30    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
31    @expectedFailureClang(9980907)
32    @expectedFailureGcc(9980907)
33    @python_api_test
34    @dsym_test
35    def test_with_dsym_and_python_api(self):
36        """Test Python APIs on file and class static variables."""
37        self.buildDsym()
38        self.static_variable_python()
39
40    @expectedFailureClang(9980907)
41    @python_api_test
42    @dwarf_test
43    def test_with_dwarf_and_python_api(self):
44        """Test Python APIs on file and class static variables."""
45        self.buildDwarf()
46        self.static_variable_python()
47
48    def setUp(self):
49        # Call super's setUp().
50        TestBase.setUp(self)
51        # Find the line number to break at.
52        self.line = line_number('main.cpp', '// Set break point at this line.')
53
54    def static_variable_commands(self):
55        """Test that that file and class static variables display correctly."""
56        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
57
58        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
59
60        self.runCmd("run", RUN_SUCCEEDED)
61
62        # The stop reason of the thread should be breakpoint.
63        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
64            substrs = ['stopped',
65                       'stop reason = breakpoint'])
66
67        # global variables are no longer displayed with the "frame variable" command.
68        self.expect('target variable A::g_points', VARIABLES_DISPLAYED_CORRECTLY,
69            substrs = ['(PointType [2]) A::g_points'])
70        self.expect('target variable g_points', VARIABLES_DISPLAYED_CORRECTLY,
71            substrs = ['(PointType [2]) g_points'])
72
73        # On Mac OS X, gcc 4.2 emits the wrong debug info for A::g_points.
74        # A::g_points is an array of two elements.
75        if sys.platform.startswith("darwin") and self.getCompiler() in ['clang', 'llvm-gcc']:
76            self.expect("target variable A::g_points[1].x", VARIABLES_DISPLAYED_CORRECTLY,
77                startstr = "(int) A::g_points[1].x = 11")
78
79    def static_variable_python(self):
80        """Test Python APIs on file and class static variables."""
81        exe = os.path.join(os.getcwd(), "a.out")
82
83        target = self.dbg.CreateTarget(exe)
84        self.assertTrue(target, VALID_TARGET)
85
86        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line)
87        self.assertTrue(breakpoint, VALID_BREAKPOINT)
88
89        # Now launch the process, and do not stop at entry point.
90        process = target.LaunchSimple(None, None, os.getcwd())
91        self.assertTrue(process, PROCESS_IS_VALID)
92
93        # The stop reason of the thread should be breakpoint.
94        thread = process.GetThreadAtIndex(0)
95        if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
96            from lldbutil import stop_reason_to_str
97            self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
98                      stop_reason_to_str(thread.GetStopReason()))
99
100        # Get the SBValue of 'A::g_points' and 'g_points'.
101        frame = thread.GetFrameAtIndex(0)
102
103        # arguments =>     False
104        # locals =>        False
105        # statics =>       True
106        # in_scope_only => False
107        valList = frame.GetVariables(False, False, True, False)
108
109        for val in valList:
110            self.DebugSBValue(val)
111            name = val.GetName()
112            self.assertTrue(name in ['g_points', 'A::g_points'])
113            if name == 'g_points':
114                self.assertTrue(val.GetValueType() == lldb.eValueTypeVariableStatic)
115                self.assertTrue(val.GetNumChildren() == 2)
116            elif name == 'A::g_points' and self.getCompiler() in ['clang', 'llvm-gcc']:
117                # On Mac OS X, gcc 4.2 emits the wrong debug info for A::g_points.
118                self.assertTrue(val.GetValueType() == lldb.eValueTypeVariableGlobal)
119                self.assertTrue(val.GetNumChildren() == 2)
120                child1 = val.GetChildAtIndex(1)
121                self.DebugSBValue(child1)
122                child1_x = child1.GetChildAtIndex(0)
123                self.DebugSBValue(child1_x)
124                self.assertTrue(child1_x.GetTypeName() == 'int' and
125                                child1_x.GetValue() == '11')
126
127        # SBFrame.FindValue() should also work.
128        val = frame.FindValue("A::g_points", lldb.eValueTypeVariableGlobal)
129        self.DebugSBValue(val)
130        self.assertTrue(val.GetName() == 'A::g_points')
131
132        # Also exercise the "parameter" and "local" scopes while we are at it.
133        val = frame.FindValue("argc", lldb.eValueTypeVariableArgument)
134        self.DebugSBValue(val)
135        self.assertTrue(val.GetName() == 'argc')
136
137        val = frame.FindValue("argv", lldb.eValueTypeVariableArgument)
138        self.DebugSBValue(val)
139        self.assertTrue(val.GetName() == 'argv')
140
141        val = frame.FindValue("hello_world", lldb.eValueTypeVariableLocal)
142        self.DebugSBValue(val)
143        self.assertTrue(val.GetName() == 'hello_world')
144
145
146if __name__ == '__main__':
147    import atexit
148    lldb.SBDebugger.Initialize()
149    atexit.register(lambda: lldb.SBDebugger.Terminate())
150    unittest2.main()
151