TestFormattersSBAPI.py revision d67dc54a5ca70c26cf33fde8d1ae6b8c172985ce
1"""Test Python APIs for working with formatters"""
2
3import os, sys, time
4import unittest2
5import lldb
6from lldbtest import *
7
8class SBFormattersAPITestCase(TestBase):
9
10    mydir = os.path.join("python_api", "formatters")
11
12    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
13    @python_api_test
14    @dsym_test
15    def test_with_dsym_formatters_api(self):
16        """Test Python APIs for working with formatters"""
17        self.buildDsym()
18        self.setTearDownCleanup()
19        self.formatters()
20
21    @python_api_test
22    @dwarf_test
23    def test_with_dwarf_formatters_api(self):
24        """Test Python APIs for working with formatters"""
25        self.buildDwarf()
26        self.setTearDownCleanup()
27        self.formatters()
28
29    @python_api_test
30    def test_force_synth_off(self):
31        """Test that one can have the public API return non-synthetic SBValues if desired"""
32        self.buildDwarf(dictionary={'EXE':'no_synth'})
33        self.setTearDownCleanup()
34        self.force_synth_off()
35
36    def setUp(self):
37        # Call super's setUp().
38        TestBase.setUp(self)
39        self.line = line_number('main.cpp', '// Set break point at this line.')
40
41    def formatters(self):
42        """Test Python APIs for working with formatters"""
43        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
44
45        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
46                    BREAKPOINT_CREATED,
47            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
48                        self.line)
49
50        self.runCmd("run", RUN_SUCCEEDED)
51
52        # The stop reason of the thread should be breakpoint.
53        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
54            substrs = ['stopped',
55                       'stop reason = breakpoint'])
56
57        # This is the function to remove the custom formats in order to have a
58        # clean slate for the next test case.
59        def cleanup():
60            self.runCmd('type format clear', check=False)
61            self.runCmd('type summary clear', check=False)
62            self.runCmd('type filter clear', check=False)
63            self.runCmd('type synthetic clear', check=False)
64            self.runCmd('type category delete foobar', check=False)
65            self.runCmd('type category delete JASSynth', check=False)
66            self.runCmd('type category delete newbar', check=False)
67
68        # Execute the cleanup function during test case tear down.
69        self.addTearDownHook(cleanup)
70
71
72        format = lldb.SBTypeFormat(lldb.eFormatHex)
73        category = self.dbg.GetDefaultCategory()
74        category.AddTypeFormat(lldb.SBTypeNameSpecifier("int"),format)
75
76        self.expect("frame variable foo.A",
77             substrs = ['0x00000001'])
78        self.expect("frame variable foo.E", matching=False,
79             substrs = ['b8cca70a'])
80
81        category.AddTypeFormat(lldb.SBTypeNameSpecifier("long"),format)
82        self.expect("frame variable foo.A",
83             substrs = ['0x00000001'])
84        self.expect("frame variable foo.E",
85             substrs = ['b8cca70a'])
86
87        format.format = lldb.eFormatOctal
88        category.AddTypeFormat(lldb.SBTypeNameSpecifier("int"),format)
89        self.expect("frame variable foo.A",
90             substrs = ['01'])
91        self.expect("frame variable foo.E",
92             substrs = ['b8cca70a'])
93
94        category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("int"))
95        category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("long"))
96        self.expect("frame variable foo.A", matching=False,
97             substrs = ['01'])
98        self.expect("frame variable foo.E", matching=False,
99             substrs = ['b8cca70a'])
100
101        summary = lldb.SBTypeSummary.CreateWithSummaryString("the hello world you'll never see")
102        summary.SetSummaryString('hello world')
103        new_category = self.dbg.GetCategory("foobar")
104        self.assertFalse(new_category.IsValid(), "getting a non-existing category worked")
105        new_category = self.dbg.CreateCategory("foobar")
106        new_category.enabled = True
107        new_category.AddTypeSummary(lldb.SBTypeNameSpecifier("^.*t$",True),summary)
108        self.expect("frame variable foo.A",
109             substrs = ['hello world'])
110        self.expect("frame variable foo.E", matching=False,
111             substrs = ['hello world'])
112        self.expect("frame variable foo.B",
113             substrs = ['hello world'])
114        self.expect("frame variable foo.F",
115             substrs = ['hello world'])
116        new_category.enabled = False
117        self.expect("frame variable foo.A", matching=False,
118             substrs = ['hello world'])
119        self.expect("frame variable foo.E", matching=False,
120             substrs = ['hello world'])
121        self.expect("frame variable foo.B", matching=False,
122             substrs = ['hello world'])
123        self.expect("frame variable foo.F", matching=False,
124             substrs = ['hello world'])
125        self.dbg.DeleteCategory(new_category.GetName())
126        self.expect("frame variable foo.A", matching=False,
127             substrs = ['hello world'])
128        self.expect("frame variable foo.E", matching=False,
129             substrs = ['hello world'])
130        self.expect("frame variable foo.B", matching=False,
131             substrs = ['hello world'])
132        self.expect("frame variable foo.F", matching=False,
133             substrs = ['hello world'])
134
135        filter = lldb.SBTypeFilter(0)
136        filter.AppendExpressionPath("A")
137        filter.AppendExpressionPath("D")
138        self.assertTrue(filter.GetNumberOfExpressionPaths() == 2, "filter with two items does not have two items")
139
140        category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"),filter)
141        self.expect("frame variable foo",
142             substrs = ['A = 1', 'D = 6.28'])
143        self.expect("frame variable foo", matching=False,
144             substrs = ['B = ', 'C = ', 'E = ', 'F = '])
145
146        category.DeleteTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct",True))
147        self.expect("frame variable foo",
148             substrs = ['A = 1', 'D = 6.28'])
149        self.expect("frame variable foo", matching=False,
150             substrs = ['B = ', 'C = ', 'E = ', 'F = '])
151
152        category.DeleteTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct",False))
153        self.expect("frame variable foo",
154             substrs = ['A = 1', 'D = 6.28'])
155        self.expect("frame variable foo", matching=True,
156             substrs = ['B = ', 'C = ', 'E = ', 'F = '])
157
158        self.runCmd("command script import --allow-reload ./jas_synth.py")
159
160        self.expect("frame variable foo", matching=False,
161             substrs = ['X = 1'])
162
163        self.dbg.GetCategory("JASSynth").SetEnabled(True)
164        self.expect("frame variable foo", matching=True,
165             substrs = ['X = 1'])
166
167        foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('foo')
168        self.assertTrue(foo_var.IsValid(), 'could not find foo')
169
170        self.assertTrue(foo_var.GetNumChildren() == 2, 'synthetic value has wrong number of child items (synth)')
171        self.assertTrue(foo_var.GetChildMemberWithName('X').GetValueAsUnsigned() == 1, 'foo_synth.X has wrong value (synth)')
172        self.assertFalse(foo_var.GetChildMemberWithName('B').IsValid(), 'foo_synth.B is valid but should not (synth)')
173
174        self.dbg.GetCategory("JASSynth").SetEnabled(False)
175        foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('foo')
176        self.assertTrue(foo_var.IsValid(), 'could not find foo')
177
178        self.assertFalse(foo_var.GetNumChildren() == 2, 'still seeing synthetic value')
179
180        filter = lldb.SBTypeFilter(0)
181        filter.AppendExpressionPath("A")
182        filter.AppendExpressionPath("D")
183        category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"),filter)
184        self.expect("frame variable foo",
185             substrs = ['A = 1', 'D = 6.28'])
186
187        foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('foo')
188        self.assertTrue(foo_var.IsValid(), 'could not find foo')
189
190        self.assertTrue(foo_var.GetNumChildren() == 2, 'synthetic value has wrong number of child items (filter)')
191        self.assertTrue(foo_var.GetChildMemberWithName('X').GetValueAsUnsigned() == 0, 'foo_synth.X has wrong value (filter)')
192        self.assertTrue(foo_var.GetChildMemberWithName('A').GetValueAsUnsigned() == 1, 'foo_synth.A has wrong value (filter)')
193
194        self.assertTrue(filter.ReplaceExpressionPathAtIndex(0,"C"), "failed to replace an expression path in filter")
195        self.expect("frame variable foo",
196             substrs = ['A = 1', 'D = 6.28'])
197        category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"),filter)
198        self.expect("frame variable foo",
199             substrs = ["C = 'e'", 'D = 6.28'])
200        category.AddTypeFilter(lldb.SBTypeNameSpecifier("FooType"),filter)
201        filter.ReplaceExpressionPathAtIndex(1,"F")
202        self.expect("frame variable foo",
203             substrs = ["C = 'e'", 'D = 6.28'])
204        category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"),filter)
205        self.expect("frame variable foo",
206             substrs = ["C = 'e'", 'F = 0'])
207        self.expect("frame variable bar",
208             substrs = ["C = 'e'", 'D = 6.28'])
209
210        foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('foo')
211        self.assertTrue(foo_var.IsValid(), 'could not find foo')
212        self.assertTrue(foo_var.GetChildMemberWithName('C').GetValueAsUnsigned() == ord('e'), 'foo_synth.C has wrong value (filter)')
213
214        chosen = self.dbg.GetFilterForType(lldb.SBTypeNameSpecifier("JustAStruct"))
215        self.assertTrue(chosen.count == 2, "wrong filter found for JustAStruct")
216        self.assertTrue(chosen.GetExpressionPathAtIndex(0) == 'C', "wrong item at index 0 for JustAStruct")
217        self.assertTrue(chosen.GetExpressionPathAtIndex(1) == 'F', "wrong item at index 1 for JustAStruct")
218
219        self.assertFalse(category.DeleteTypeFilter(lldb.SBTypeNameSpecifier("NoSuchType")),"deleting a non-existing filter worked")
220        self.assertFalse(category.DeleteTypeSummary(lldb.SBTypeNameSpecifier("NoSuchType")),"deleting a non-existing summary worked")
221        self.assertFalse(category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("NoSuchType")),"deleting a non-existing format worked")
222        self.assertFalse(category.DeleteTypeSynthetic(lldb.SBTypeNameSpecifier("NoSuchType")),"deleting a non-existing synthetic worked")
223
224        self.assertFalse(category.DeleteTypeFilter(lldb.SBTypeNameSpecifier("")),"deleting a filter for '' worked")
225        self.assertFalse(category.DeleteTypeSummary(lldb.SBTypeNameSpecifier("")),"deleting a summary for '' worked")
226        self.assertFalse(category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("")),"deleting a format for '' worked")
227        self.assertFalse(category.DeleteTypeSynthetic(lldb.SBTypeNameSpecifier("")),"deleting a synthetic for '' worked")
228
229        try:
230             self.assertFalse(category.AddTypeSummary(lldb.SBTypeNameSpecifier("NoneSuchType"), None), "adding a summary valued None worked")
231        except:
232             pass
233        else:
234             self.assertFalse(True, "adding a summary valued None worked")
235
236        try:
237             self.assertFalse(category.AddTypeFilter(lldb.SBTypeNameSpecifier("NoneSuchType"), None), "adding a filter valued None worked")
238        except:
239             pass
240        else:
241             self.assertFalse(True, "adding a filter valued None worked")
242
243        try:
244             self.assertFalse(category.AddTypeSynthetic(lldb.SBTypeNameSpecifier("NoneSuchType"), None), "adding a synthetic valued None worked")
245        except:
246             pass
247        else:
248             self.assertFalse(True, "adding a synthetic valued None worked")
249
250        try:
251             self.assertFalse(category.AddTypeFormat(lldb.SBTypeNameSpecifier("NoneSuchType"), None), "adding a format valued None worked")
252        except:
253             pass
254        else:
255             self.assertFalse(True, "adding a format valued None worked")
256
257
258        self.assertFalse(category.AddTypeSummary(lldb.SBTypeNameSpecifier("EmptySuchType"), lldb.SBTypeSummary()), "adding a summary without value worked")
259        self.assertFalse(category.AddTypeFilter(lldb.SBTypeNameSpecifier("EmptySuchType"), lldb.SBTypeFilter()), "adding a filter without value worked")
260        self.assertFalse(category.AddTypeSynthetic(lldb.SBTypeNameSpecifier("EmptySuchType"), lldb.SBTypeSynthetic()), "adding a synthetic without value worked")
261        self.assertFalse(category.AddTypeFormat(lldb.SBTypeNameSpecifier("EmptySuchType"), lldb.SBTypeFormat()), "adding a format without value worked")
262
263        self.assertFalse(category.AddTypeSummary(lldb.SBTypeNameSpecifier(""), lldb.SBTypeSummary.CreateWithSummaryString("")), "adding a summary for an invalid type worked")
264        self.assertFalse(category.AddTypeFilter(lldb.SBTypeNameSpecifier(""), lldb.SBTypeFilter(0)), "adding a filter for an invalid type worked")
265        self.assertFalse(category.AddTypeSynthetic(lldb.SBTypeNameSpecifier(""), lldb.SBTypeSynthetic.CreateWithClassName("")), "adding a synthetic for an invalid type worked")
266        self.assertFalse(category.AddTypeFormat(lldb.SBTypeNameSpecifier(""), lldb.SBTypeFormat(lldb.eFormatHex)), "adding a format for an invalid type worked")
267
268        new_category = self.dbg.CreateCategory("newbar")
269        new_category.AddTypeSummary(lldb.SBTypeNameSpecifier("JustAStruct"),
270             lldb.SBTypeSummary.CreateWithScriptCode("return 'hello scripted world';"))
271        self.expect("frame variable foo", matching=False,
272             substrs = ['hello scripted world'])
273        new_category.enabled = True
274        self.expect("frame variable foo", matching=True,
275             substrs = ['hello scripted world'])
276
277        self.expect("frame variable foo_ptr", matching=True,
278             substrs = ['hello scripted world'])
279        new_category.AddTypeSummary(lldb.SBTypeNameSpecifier("JustAStruct"),
280             lldb.SBTypeSummary.CreateWithScriptCode("return 'hello scripted world';",
281             lldb.eTypeOptionSkipPointers))
282        self.expect("frame variable foo", matching=True,
283             substrs = ['hello scripted world'])
284
285        frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
286        foo_ptr = frame.FindVariable("foo_ptr")
287        summary = foo_ptr.GetTypeSummary()
288
289        self.assertFalse(summary.IsValid(), "summary found for foo* when none was planned")
290
291        self.expect("frame variable foo_ptr", matching=False,
292             substrs = ['hello scripted world'])
293
294        new_category.AddTypeSummary(lldb.SBTypeNameSpecifier("JustAStruct"),
295             lldb.SBTypeSummary.CreateWithSummaryString("hello static world",
296             lldb.eTypeOptionNone))
297
298        summary = foo_ptr.GetTypeSummary()
299
300        self.assertTrue(summary.IsValid(), "no summary found for foo* when one was in place")
301        self.assertTrue(summary.GetData() == "hello static world", "wrong summary found for foo*")
302
303    def force_synth_off(self):
304        """Test that one can have the public API return non-synthetic SBValues if desired"""
305        self.runCmd("file no_synth", CURRENT_EXECUTABLE_SET)
306
307        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
308                    BREAKPOINT_CREATED,
309            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
310                        self.line)
311
312        self.runCmd("run", RUN_SUCCEEDED)
313
314        # The stop reason of the thread should be breakpoint.
315        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
316            substrs = ['stopped',
317                       'stop reason = breakpoint'])
318
319        # This is the function to remove the custom formats in order to have a
320        # clean slate for the next test case.
321        def cleanup():
322            self.runCmd('type format clear', check=False)
323            self.runCmd('type summary clear', check=False)
324            self.runCmd('type filter clear', check=False)
325            self.runCmd('type synthetic clear', check=False)
326            self.runCmd('type category delete foobar', check=False)
327            self.runCmd('type category delete JASSynth', check=False)
328            self.runCmd('type category delete newbar', check=False)
329            self.runCmd('settings set target.enable-synthetic-value true')
330
331        # Execute the cleanup function during test case tear down.
332        self.addTearDownHook(cleanup)
333
334        frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
335        int_vector = frame.FindVariable("int_vector")
336        if self.TraceOn():
337             print int_vector
338        self.assertTrue(int_vector.GetNumChildren() == 0, 'synthetic vector is empty')
339
340        self.runCmd('settings set target.enable-synthetic-value false')
341        frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
342        int_vector = frame.FindVariable("int_vector")
343        if self.TraceOn():
344             print int_vector
345        self.assertFalse(int_vector.GetNumChildren() == 0, '"physical" vector is not empty')
346
347        self.runCmd('settings set target.enable-synthetic-value true')
348        frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
349        int_vector = frame.FindVariable("int_vector")
350        if self.TraceOn():
351             print int_vector
352        self.assertTrue(int_vector.GetNumChildren() == 0, 'synthetic vector is still empty')
353
354
355if __name__ == '__main__':
356    import atexit
357    lldb.SBDebugger.Initialize()
358    atexit.register(lambda: lldb.SBDebugger.Terminate())
359    unittest2.main()
360