• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""
2Test lldb data formatter subsystem.
3"""
4
5import os, time
6import unittest2
7import lldb
8from lldbtest import *
9import lldbutil
10
11class SkipSummaryDataFormatterTestCase(TestBase):
12
13    mydir = os.path.join("functionalities", "data-formatter", "data-formatter-skip-summary")
14
15    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
16    @dsym_test
17    def test_with_dsym_and_run_command(self):
18        """Test data formatter commands."""
19        self.buildDsym()
20        self.data_formatter_commands()
21
22    @dwarf_test
23    def test_with_dwarf_and_run_command(self):
24        """Test data formatter commands."""
25        self.buildDwarf()
26        self.data_formatter_commands()
27
28    def setUp(self):
29        # Call super's setUp().
30        TestBase.setUp(self)
31        # Find the line number to break at.
32        self.line = line_number('main.cpp', '// Set break point at this line.')
33
34    def data_formatter_commands(self):
35        """Test that that file and class static variables display correctly."""
36        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
37
38        #import lldbutil
39        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
40
41
42        self.runCmd("run", RUN_SUCCEEDED)
43
44        # The stop reason of the thread should be breakpoint.
45        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
46            substrs = ['stopped',
47                       'stop reason = breakpoint'])
48
49        # This is the function to remove the custom formats in order to have a
50        # clean slate for the next test case.
51        def cleanup():
52            self.runCmd('type format clear', check=False)
53            self.runCmd('type summary clear', check=False)
54
55        # Execute the cleanup function during test case tear down.
56        self.addTearDownHook(cleanup)
57
58        # Setup the summaries for this scenario
59        #self.runCmd("type summary add --summary-string \"${var._M_dataplus._M_p}\" std::string")
60        self.runCmd("type summary add --summary-string \"Level 1\" \"DeepData_1\"")
61        self.runCmd("type summary add --summary-string \"Level 2\" \"DeepData_2\" -e")
62        self.runCmd("type summary add --summary-string \"Level 3\" \"DeepData_3\"")
63        self.runCmd("type summary add --summary-string \"Level 4\" \"DeepData_4\"")
64        self.runCmd("type summary add --summary-string \"Level 5\" \"DeepData_5\"")
65
66        # Default case, just print out summaries
67        self.expect('frame variable',
68            substrs = ['(DeepData_1) data1 = Level 1',
69                       '(DeepData_2) data2 = Level 2 {',
70                       'm_child1 = Level 3',
71                       'm_child2 = Level 3',
72                       'm_child3 = Level 3',
73                       'm_child4 = Level 3',
74                       '}'])
75
76        # Skip the default (should be 1) levels of summaries
77        self.expect('frame variable --no-summary-depth',
78            substrs = ['(DeepData_1) data1 = {',
79                       'm_child1 = 0x',
80                       '}',
81                       '(DeepData_2) data2 = {',
82                       'm_child1 = Level 3',
83                       'm_child2 = Level 3',
84                       'm_child3 = Level 3',
85                       'm_child4 = Level 3',
86                       '}'])
87
88        # Now skip 2 levels of summaries
89        self.expect('frame variable --no-summary-depth=2',
90            substrs = ['(DeepData_1) data1 = {',
91                       'm_child1 = 0x',
92                       '}',
93                       '(DeepData_2) data2 = {',
94                       'm_child1 = {',
95                       'm_child1 = 0x',
96                       'Level 4',
97                       'm_child2 = {',
98                       'm_child3 = {',
99                       '}'])
100
101        # Check that no "Level 3" comes out
102        self.expect('frame variable data1.m_child1 --no-summary-depth=2', matching=False,
103            substrs = ['Level 3'])
104
105        # Now expand a pointer with 2 level of skipped summaries
106        self.expect('frame variable data1.m_child1 --no-summary-depth=2',
107                    substrs = ['(DeepData_2 *) data1.m_child1 = 0x'])
108
109        # Deref and expand said pointer
110        self.expect('frame variable *data1.m_child1 --no-summary-depth=2',
111                    substrs = ['(DeepData_2) *data1.m_child1 = {',
112                               'm_child2 = {',
113                               'm_child1 = 0x',
114                               'Level 4',
115                               '}'])
116
117        # Expand an expression, skipping 2 layers of summaries
118        self.expect('frame variable data1.m_child1->m_child2 --no-summary-depth=2',
119                substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
120                           'm_child2 = {',
121                           'm_child1 = Level 5',
122                           'm_child2 = Level 5',
123                           'm_child3 = Level 5',
124                           '}'])
125
126        # Expand same expression, skipping only 1 layer of summaries
127        self.expect('frame variable data1.m_child1->m_child2 --no-summary-depth=1',
128                    substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
129                               'm_child1 = 0x',
130                               'Level 4',
131                               'm_child2 = Level 4',
132                               '}'])
133
134        # Bad debugging info on SnowLeopard gcc (Apple Inc. build 5666).
135        # Skip the following tests if the condition is met.
136        if self.getCompiler().endswith('gcc') and not self.getCompiler().endswith('llvm-gcc'):
137           import re
138           gcc_version_output = system([lldbutil.which(self.getCompiler()), "-v"])[1]
139           #print "my output:", gcc_version_output
140           for line in gcc_version_output.split(os.linesep):
141               m = re.search('\(Apple Inc\. build ([0-9]+)\)', line)
142               #print "line:", line
143               if m:
144                   gcc_build = int(m.group(1))
145                   #print "gcc build:", gcc_build
146                   if gcc_build >= 5666:
147                       # rdar://problem/9804600"
148                       self.skipTest("rdar://problem/9804600 wrong namespace for std::string in debug info")
149
150        # Expand same expression, skipping 3 layers of summaries
151        self.expect('frame variable data1.m_child1->m_child2 --show-types --no-summary-depth=3',
152                    substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
153                               'm_some_text = "Just a test"',
154                               'm_child2 = {',
155                               'm_some_text = "Just a test"'])
156
157        # Expand within a standard string (might depend on the implementation of the C++ stdlib you use)
158        self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 --no-summary-depth=2',
159            substrs = ['(DeepData_5) data1.m_child1->m_child2.m_child1.m_child2 = {',
160                       'm_some_text = {',
161                       '_M_dataplus = {',
162                       '_M_p = 0x',
163                       '"Just a test"'])
164
165        # Repeat the above, but only skip 1 level of summaries
166        self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 --no-summary-depth=1',
167                    substrs = ['(DeepData_5) data1.m_child1->m_child2.m_child1.m_child2 = {',
168                               'm_some_text = "Just a test"',
169                               '}'])
170
171        # Change summary and expand, first without --no-summary-depth then with --no-summary-depth
172        self.runCmd("type summary add --summary-string \"${var.m_some_text}\" DeepData_5")
173
174        self.expect('fr var data2.m_child4.m_child2.m_child2',
175            substrs = ['(DeepData_5) data2.m_child4.m_child2.m_child2 = "Just a test"'])
176
177        self.expect('fr var data2.m_child4.m_child2.m_child2 --no-summary-depth',
178                    substrs = ['(DeepData_5) data2.m_child4.m_child2.m_child2 = {',
179                               'm_some_text = "Just a test"',
180                               '}'])
181
182
183if __name__ == '__main__':
184    import atexit
185    lldb.SBDebugger.Initialize()
186    atexit.register(lambda: lldb.SBDebugger.Terminate())
187    unittest2.main()
188