208 lines · python
1"""2Test lldb data formatter subsystem.3"""4 5 6import lldb7from lldbsuite.test.lldbtest import *8import lldbsuite.test.lldbutil as lldbutil9 10 11class SynthDataFormatterTestCase(TestBase):12 def setUp(self):13 # Call super's setUp().14 TestBase.setUp(self)15 # Find the line number to break at.16 self.line = line_number("main.cpp", "// Set break point at this line.")17 18 def test_with_run_command(self):19 """Test that that file and class static variables display correctly."""20 self.build()21 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)22 23 lldbutil.run_break_set_by_file_and_line(24 self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True25 )26 27 self.runCmd("run", RUN_SUCCEEDED)28 29 # The stop reason of the thread should be breakpoint.30 self.expect(31 "thread list",32 STOPPED_DUE_TO_BREAKPOINT,33 substrs=["stopped", "stop reason = breakpoint"],34 )35 36 # This is the function to remove the custom formats in order to have a37 # clean slate for the next test case.38 def cleanup():39 self.runCmd("type format clear", check=False)40 self.runCmd("type summary clear", check=False)41 self.runCmd("type filter clear", check=False)42 43 # Execute the cleanup function during test case tear down.44 self.addTearDownHook(cleanup)45 46 # Pick some values and check that the basics work47 self.runCmd("type filter add BagOfInts --child x --child z")48 self.expect("frame variable int_bag", substrs=["x = 6", "z = 8"])49 50 # Check we can still access the missing child by summary51 self.runCmd('type summary add BagOfInts --summary-string "y=${var.y}"')52 self.expect("frame variable int_bag", substrs=["y=7"])53 54 # Even if we have synth children, the summary prevails55 self.expect(56 "frame variable int_bag", matching=False, substrs=["x = 6", "z = 8"]57 )58 59 # if we skip synth and summary show y60 self.expect(61 "frame variable int_bag --synthetic-type false --no-summary-depth=1",62 substrs=["x = 6", "y = 7", "z = 8"],63 )64 65 # if we ask for raw output same happens66 self.expect(67 "frame variable int_bag --raw-output", substrs=["x = 6", "y = 7", "z = 8"]68 )69 70 # Summary+Synth must work together71 self.runCmd('type summary add BagOfInts --summary-string "x=${var.x}" -e')72 self.expect("frame variable int_bag", substrs=["x=6", "x = 6", "z = 8"])73 74 # Same output, but using Python75 self.runCmd(76 "type summary add BagOfInts --python-script \"return 'x=%s' % valobj.GetChildMemberWithName('x').GetValue()\" -e"77 )78 self.expect("frame variable int_bag", substrs=["x=6", "x = 6", "z = 8"])79 80 # If I skip summaries, still give me the artificial children81 self.expect(82 "frame variable int_bag --no-summary-depth=1", substrs=["x = 6", "z = 8"]83 )84 85 # Delete synth and check that the view reflects it immediately86 self.runCmd("type filter delete BagOfInts")87 self.expect("frame variable int_bag", substrs=["x = 6", "y = 7", "z = 8"])88 89 # Add the synth again and check that it's honored deeper in the90 # hierarchy91 self.runCmd("type filter add BagOfInts --child x --child z")92 self.expect(93 "frame variable bag_bag",94 substrs=[95 "x = x=69 {",96 "x = 69",97 "z = 71",98 "y = x=66 {",99 "x = 66",100 "z = 68",101 ],102 )103 self.expect(104 "frame variable bag_bag", matching=False, substrs=["y = 70", "y = 67"]105 )106 107 # Check that a synth can expand nested stuff108 self.runCmd("type filter add BagOfBags --child x.y --child y.z")109 self.expect("frame variable bag_bag", substrs=["x.y = 70", "y.z = 68"])110 111 # ...even if we get -> and . wrong112 self.runCmd('type filter add BagOfBags --child x.y --child "y->z"')113 self.expect("frame variable bag_bag", substrs=["x.y = 70", "y->z = 68"])114 115 # ...even bitfields116 self.runCmd('type filter add BagOfBags --child x.y --child "y->z[1-2]"')117 self.expect(118 "frame variable bag_bag --show-types",119 substrs=["x.y = 70", "(int:2) y->z[1-2] = 2"],120 )121 122 # ...even if we format the bitfields123 self.runCmd('type filter add BagOfBags --child x.y --child "y->y[0-0]"')124 self.runCmd('type format add "int:1" -f bool')125 self.expect(126 "frame variable bag_bag --show-types",127 substrs=["x.y = 70", "(int:1) y->y[0-0] = true"],128 )129 130 # ...even if we use one-liner summaries131 self.runCmd("type summary add -c BagOfBags")132 self.expect(133 "frame variable bag_bag",134 substrs=["(BagOfBags) bag_bag = (x.y = 70, y->y[0-0] = true)"],135 )136 137 self.runCmd("type summary delete BagOfBags")138 139 # now check we are dynamic (and arrays work)140 self.runCmd(141 "type filter add Plenty --child bitfield --child array[0] --child array[2]"142 )143 self.expect(144 "frame variable plenty_of_stuff",145 substrs=["bitfield = 1", "array[0] = 5", "array[2] = 3"],146 )147 148 self.runCmd("n")149 self.expect(150 "frame variable plenty_of_stuff",151 substrs=["bitfield = 17", "array[0] = 5", "array[2] = 3"],152 )153 154 # skip synthetic children155 self.expect(156 "frame variable plenty_of_stuff --synthetic-type no",157 substrs=["some_values = 0x", "array = 0x", "array_size = 5"],158 )159 160 # check flat printing with synthetic children161 self.expect(162 "frame variable plenty_of_stuff --flat",163 substrs=[164 "plenty_of_stuff.bitfield = 17",165 "*(plenty_of_stuff.array) = 5",166 "*(plenty_of_stuff.array) = 3",167 ],168 )169 170 # check that we do not lose location information for our children171 self.expect(172 "frame variable plenty_of_stuff --location",173 substrs=["0x", ": bitfield = 17"],174 )175 176 # check we work across pointer boundaries177 self.expect(178 "frame variable plenty_of_stuff.some_values --ptr-depth=1",179 substrs=["(BagOfInts *) plenty_of_stuff.some_values", "x = 5", "z = 7"],180 )181 182 # but not if we don't want to183 self.runCmd("type filter add BagOfInts --child x --child z -p")184 self.expect(185 "frame variable plenty_of_stuff.some_values --ptr-depth=1",186 substrs=[187 "(BagOfInts *) plenty_of_stuff.some_values",188 "x = 5",189 "y = 6",190 "z = 7",191 ],192 )193 194 # check we're dynamic even if nested195 self.runCmd("type filter add BagOfBags --child x.z")196 self.expect("frame variable bag_bag", substrs=["x.z = 71"])197 198 self.runCmd("n")199 self.expect("frame variable bag_bag", substrs=["x.z = 12"])200 201 self.runCmd('type summary add -e -s "I am always empty but have" EmptyStruct')202 self.expect("frame variable es", substrs=["I am always empty but have {}"])203 self.runCmd('type summary add -e -h -s "I am really empty" EmptyStruct')204 self.expect("frame variable es", substrs=["I am really empty"])205 self.expect(206 "frame variable es", substrs=["I am really empty {}"], matching=False207 )208