TestBitfields.py revision 8f2e392e8937aaf66f91201dc5f4190d61902c67
1"""Show bitfields and check that they display correctly."""
2
3import os, time
4import unittest2
5import lldb
6from lldbtest import *
7
8class BitfieldsTestCase(TestBase):
9
10    mydir = os.path.join("lang", "c", "bitfields")
11
12    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
13    def test_with_dsym_and_run_command(self):
14        """Test 'frame variable ...' on a variable with bitfields."""
15        self.buildDsym()
16        self.bitfields_variable()
17
18    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
19    @python_api_test
20    def test_with_dsym_and_python_api(self):
21        """Use Python APIs to inspect a bitfields variable."""
22        self.buildDsym()
23        self.bitfields_variable_python()
24
25    def test_with_dwarf_and_run_command(self):
26        """Test 'frame variable ...' on a variable with bitfields."""
27        self.buildDwarf()
28        self.bitfields_variable()
29
30    @python_api_test
31    def test_with_dwarf_and_python_api(self):
32        """Use Python APIs to inspect a bitfields variable."""
33        self.buildDwarf()
34        self.bitfields_variable_python()
35
36    def setUp(self):
37        # Call super's setUp().
38        TestBase.setUp(self)
39        # Find the line number to break inside main().
40        self.line = line_number('main.c', '// Set break point at this line.')
41
42    def bitfields_variable(self):
43        """Test 'frame variable ...' on a variable with bitfields."""
44        exe = os.path.join(os.getcwd(), "a.out")
45        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
46
47        # Break inside the main.
48        self.expect("breakpoint set -f main.c -l %d" % self.line,
49                    BREAKPOINT_CREATED,
50            startstr = "Breakpoint created: 1: file ='main.c', line = %d, locations = 1" %
51                        self.line)
52
53        self.runCmd("run", RUN_SUCCEEDED)
54
55        # The stop reason of the thread should be breakpoint.
56        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
57            substrs = ['stopped',
58                       'stop reason = breakpoint'])
59
60        # The breakpoint should have a hit count of 1.
61        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
62            substrs = [' resolved, hit count = 1'])
63
64        # This should display correctly.
65        self.expect("frame variable -T bits", VARIABLES_DISPLAYED_CORRECTLY,
66            substrs = ['(uint32_t:1) b1 = 1',
67                       '(uint32_t:2) b2 = 3',
68                       '(uint32_t:3) b3 = 7',
69                       '(uint32_t) b4 = 15',
70                       '(uint32_t:5) b5 = 31',
71                       '(uint32_t:6) b6 = 63',
72                       '(uint32_t:7) b7 = 127',
73                       '(uint32_t:4) four = 15'])
74
75        # And so should this.
76        # rdar://problem/8348251
77        self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY,
78            substrs = ['(uint32_t:1) b1 = 1',
79                       '(uint32_t:2) b2 = 3',
80                       '(uint32_t:3) b3 = 7',
81                       '(uint32_t) b4 = 15',
82                       '(uint32_t:5) b5 = 31',
83                       '(uint32_t:6) b6 = 63',
84                       '(uint32_t:7) b7 = 127',
85                       '(uint32_t:4) four = 15'])
86
87    def bitfields_variable_python(self):
88        """Use Python APIs to inspect a bitfields variable."""
89        exe = os.path.join(os.getcwd(), "a.out")
90
91        target = self.dbg.CreateTarget(exe)
92        self.assertTrue(target, VALID_TARGET)
93
94        breakpoint = target.BreakpointCreateByLocation("main.c", self.line)
95        self.assertTrue(breakpoint, VALID_BREAKPOINT)
96
97        process = target.LaunchSimple(None, None, os.getcwd())
98        self.assertTrue(process, PROCESS_IS_VALID)
99
100        # The stop reason of the thread should be breakpoint.
101        thread = target.GetProcess().GetThreadAtIndex(0)
102        if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
103            from lldbutil import stop_reason_to_str
104            self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
105                      stop_reason_to_str(thread.GetStopReason()))
106
107        # The breakpoint should have a hit count of 1.
108        self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE)
109
110        # Lookup the "bits" variable which contains 8 bitfields.
111        frame = thread.GetFrameAtIndex(0)
112        bits = frame.FindVariable("bits")
113        self.DebugSBValue(bits)
114        self.assertTrue(bits.GetTypeName() == "Bits" and
115                        bits.GetNumChildren() == 8 and
116                        bits.GetByteSize() == 32,
117                        "(Bits)bits with byte size of 32 and 8 children")
118
119        # Notice the pattern of int(b1.GetValue(), 0).  We pass a base of 0
120        # so that the proper radix is determined based on the contents of the
121        # string.
122        b1 = bits.GetChildAtIndex(0)
123        self.DebugSBValue(b1)
124        self.assertTrue(b1.GetName() == "b1" and
125                        b1.GetTypeName() == "uint32_t:1" and
126                        b1.IsInScope() and
127                        int(b1.GetValue(), 0) == 1,
128                        'bits.b1 has type uint32_t:1, is in scope, and == 1')
129
130        b7 = bits.GetChildAtIndex(6)
131        self.DebugSBValue(b7)
132        self.assertTrue(b7.GetName() == "b7" and
133                        b7.GetTypeName() == "uint32_t:7" and
134                        b7.IsInScope() and
135                        int(b7.GetValue(), 0) == 127,
136                        'bits.b7 has type uint32_t:7, is in scope, and == 127')
137
138        four = bits.GetChildAtIndex(7)
139        self.DebugSBValue(four)
140        self.assertTrue(four.GetName() == "four" and
141                        four.GetTypeName() == "uint32_t:4" and
142                        four.IsInScope() and
143                        int(four.GetValue(), 0) == 15,
144                        'bits.four has type uint32_t:4, is in scope, and == 15')
145
146        # Now kill the process, and we are done.
147        rc = target.GetProcess().Kill()
148        self.assertTrue(rc.Success())
149
150
151if __name__ == '__main__':
152    import atexit
153    lldb.SBDebugger.Initialize()
154    atexit.register(lambda: lldb.SBDebugger.Terminate())
155    unittest2.main()
156