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