1"""Test breakpoint by file/line number; and list variables with array types."""
2
3import os, time
4import unittest2
5import lldb
6from lldbtest import *
7import lldbutil
8
9class ArrayTypesTestCase(TestBase):
10
11    mydir = os.path.join("lang", "c", "array_types")
12
13    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
14    @dsym_test
15    def test_with_dsym_and_run_command(self):
16        """Test 'frame variable var_name' on some variables with array types."""
17        self.buildDsym()
18        self.array_types()
19
20    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
21    @python_api_test
22    @dsym_test
23    def test_with_dsym_and_python_api(self):
24        """Use Python APIs to inspect variables with array types."""
25        self.buildDsym()
26        self.array_types_python()
27
28    @dwarf_test
29    def test_with_dwarf_and_run_command(self):
30        """Test 'frame variable var_name' on some variables with array types."""
31        self.buildDwarf()
32        self.array_types()
33
34    @python_api_test
35    @dwarf_test
36    def test_with_dwarf_and_python_api(self):
37        """Use Python APIs to inspect variables with array types."""
38        self.buildDwarf()
39        self.array_types_python()
40
41    def setUp(self):
42        # Call super's setUp().
43        TestBase.setUp(self)
44        # Find the line number to break inside main().
45        self.line = line_number('main.c', '// Set break point at this line.')
46
47    def array_types(self):
48        """Test 'frame variable var_name' on some variables with array types."""
49        exe = os.path.join(os.getcwd(), "a.out")
50        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
51
52        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=False)
53
54        self.runCmd("run", RUN_SUCCEEDED)
55
56        # The test suite sometimes shows that the process has exited without stopping.
57        #
58        # CC=clang ./dotest.py -v -t array_types
59        # ...
60        # Process 76604 exited with status = 0 (0x00000000)
61        self.runCmd("process status")
62
63        # The stop reason of the thread should be breakpoint.
64        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
65            substrs = ['stopped',
66                       'stop reason = breakpoint'])
67
68        # The breakpoint should have a hit count of 1.
69        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
70            substrs = ['resolved, hit count = 1'])
71
72        # Issue 'variable list' command on several array-type variables.
73
74        self.expect("frame variable --show-types strings", VARIABLES_DISPLAYED_CORRECTLY,
75            startstr = '(char *[4])',
76            substrs = ['(char *) [0]',
77                       '(char *) [1]',
78                       '(char *) [2]',
79                       '(char *) [3]',
80                       'Hello',
81                       'Hola',
82                       'Bonjour',
83                       'Guten Tag'])
84
85        self.expect("frame variable --show-types --raw -- char_16", VARIABLES_DISPLAYED_CORRECTLY,
86            substrs = ['(char) [0]',
87                       '(char) [15]'])
88
89        self.expect("frame variable --show-types ushort_matrix", VARIABLES_DISPLAYED_CORRECTLY,
90            startstr = '(unsigned short [2][3])')
91
92        self.expect("frame variable --show-types long_6", VARIABLES_DISPLAYED_CORRECTLY,
93            startstr = '(long [6])')
94
95    def array_types_python(self):
96        """Use Python APIs to inspect variables with array types."""
97        exe = os.path.join(os.getcwd(), "a.out")
98
99        target = self.dbg.CreateTarget(exe)
100        self.assertTrue(target, VALID_TARGET)
101
102        breakpoint = target.BreakpointCreateByLocation("main.c", self.line)
103        self.assertTrue(breakpoint, VALID_BREAKPOINT)
104
105        # Sanity check the print representation of breakpoint.
106        bp = str(breakpoint)
107        self.expect(bp, msg="Breakpoint looks good", exe=False,
108            substrs = ["file = 'main.c'",
109                       "line = %d" % self.line,
110                       "locations = 1"])
111        self.expect(bp, msg="Breakpoint is not resolved as yet", exe=False, matching=False,
112            substrs = ["resolved = 1"])
113
114        # Now launch the process, and do not stop at entry point.
115        process = target.LaunchSimple(None, None, os.getcwd())
116        self.assertTrue(process, PROCESS_IS_VALID)
117
118        # Sanity check the print representation of process.
119        proc = str(process)
120        self.expect(proc, msg="Process looks good", exe=False,
121            substrs = ["state = stopped",
122                       "executable = a.out"])
123
124        # The stop reason of the thread should be breakpoint.
125        thread = process.GetThreadAtIndex(0)
126        if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
127            from lldbutil import stop_reason_to_str
128            self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
129                      stop_reason_to_str(thread.GetStopReason()))
130
131        # Sanity check the print representation of thread.
132        thr = str(thread)
133        self.expect(thr, "Thread looks good with stop reason = breakpoint", exe=False,
134            substrs = ["tid = 0x%4.4x" % thread.GetThreadID()])
135
136        # The breakpoint should have a hit count of 1.
137        self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE)
138
139        # The breakpoint should be resolved by now.
140        bp = str(breakpoint)
141        self.expect(bp, "Breakpoint looks good and is resolved", exe=False,
142            substrs = ["file = 'main.c'",
143                       "line = %d" % self.line,
144                       "locations = 1"])
145
146        # Sanity check the print representation of frame.
147        frame = thread.GetFrameAtIndex(0)
148        frm = str(frame)
149        self.expect(frm,
150                    "Frame looks good with correct index %d" % frame.GetFrameID(),
151                    exe=False,
152            substrs = ["#%d" % frame.GetFrameID()])
153
154        # Lookup the "strings" string array variable and sanity check its print
155        # representation.
156        variable = frame.FindVariable("strings")
157        var = str(variable)
158        self.expect(var, "Variable for 'strings' looks good with correct name", exe=False,
159            substrs = ["%s" % variable.GetName()])
160        self.DebugSBValue(variable)
161        self.assertTrue(variable.GetNumChildren() == 4,
162                        "Variable 'strings' should have 4 children")
163
164        child3 = variable.GetChildAtIndex(3)
165        self.DebugSBValue(child3)
166        self.assertTrue(child3.GetSummary() == '"Guten Tag"',
167                        'strings[3] == "Guten Tag"')
168
169        # Lookup the "char_16" char array variable.
170        variable = frame.FindVariable("char_16")
171        self.DebugSBValue(variable)
172        self.assertTrue(variable.GetNumChildren() == 16,
173                        "Variable 'char_16' should have 16 children")
174
175        # Lookup the "ushort_matrix" ushort[] array variable.
176        # Notice the pattern of int(child0_2.GetValue(), 0).  We pass a
177        # base of 0 so that the proper radix is determined based on the contents
178        # of the string.  Same applies to long().
179        variable = frame.FindVariable("ushort_matrix")
180        self.DebugSBValue(variable)
181        self.assertTrue(variable.GetNumChildren() == 2,
182                        "Variable 'ushort_matrix' should have 2 children")
183        child0 = variable.GetChildAtIndex(0)
184        self.DebugSBValue(child0)
185        self.assertTrue(child0.GetNumChildren() == 3,
186                        "Variable 'ushort_matrix[0]' should have 3 children")
187        child0_2 = child0.GetChildAtIndex(2)
188        self.DebugSBValue(child0_2)
189        self.assertTrue(int(child0_2.GetValue(), 0) == 3,
190                        "ushort_matrix[0][2] == 3")
191
192        # Lookup the "long_6" char array variable.
193        variable = frame.FindVariable("long_6")
194        self.DebugSBValue(variable)
195        self.assertTrue(variable.GetNumChildren() == 6,
196                        "Variable 'long_6' should have 6 children")
197        child5 = variable.GetChildAtIndex(5)
198        self.DebugSBValue(child5)
199        self.assertTrue(long(child5.GetValue(), 0) == 6,
200                        "long_6[5] == 6")
201
202        # Last, check that "long_6" has a value type of eValueTypeVariableLocal
203        # and "argc" has eValueTypeVariableArgument.
204        from lldbutil import value_type_to_str
205        self.assertTrue(variable.GetValueType() == lldb.eValueTypeVariableLocal,
206                        "Variable 'long_6' should have '%s' value type." %
207                        value_type_to_str(lldb.eValueTypeVariableLocal))
208        argc = frame.FindVariable("argc")
209        self.DebugSBValue(argc)
210        self.assertTrue(argc.GetValueType() == lldb.eValueTypeVariableArgument,
211                        "Variable 'argc' should have '%s' value type." %
212                        value_type_to_str(lldb.eValueTypeVariableArgument))
213
214
215if __name__ == '__main__':
216    import atexit
217    lldb.SBDebugger.Initialize()
218    atexit.register(lambda: lldb.SBDebugger.Terminate())
219    unittest2.main()
220