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