356 lines · python
1"""2Test lldb data formatter subsystem.3"""4 5 6import lldb7from lldbsuite.test.lldbtest import *8import lldbsuite.test.lldbutil as lldbutil9import re10 11 12class AdvDataFormatterTestCase(TestBase):13 def setUp(self):14 # Call super's setUp().15 TestBase.setUp(self)16 # Find the line number to break at.17 self.line = line_number("main.cpp", "// Set break point at this line.")18 19 def test_with_run_command(self):20 """Test that that file and class static variables display correctly."""21 self.build()22 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)23 24 lldbutil.run_break_set_by_file_and_line(25 self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True26 )27 28 self.runCmd("run", RUN_SUCCEEDED)29 30 # The stop reason of the thread should be breakpoint.31 self.expect(32 "thread list",33 STOPPED_DUE_TO_BREAKPOINT,34 substrs=["stopped", "stop reason = breakpoint"],35 )36 37 # This is the function to remove the custom formats in order to have a38 # 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("settings set target.max-children-count 24", check=False)43 44 # Execute the cleanup function during test case tear down.45 self.addTearDownHook(cleanup)46 47 self.runCmd('type summary add --summary-string "pippo" "i_am_cool"')48 49 self.runCmd('type summary add --summary-string "pluto" -x "i_am_cool[a-z]*"')50 51 self.expect("frame variable cool_boy", substrs=["pippo"])52 53 self.expect("frame variable cooler_boy", substrs=["pluto"])54 55 self.runCmd("type summary delete i_am_cool")56 57 self.expect("frame variable cool_boy", substrs=["pluto"])58 59 self.runCmd("type summary clear")60 61 self.runCmd('type summary add --summary-string "${var[]}" -x "^int\\[[0-9]\\]')62 63 self.expect("frame variable int_array", substrs=["1,2,3,4,5"])64 self.expect("frame variable const_int_array", substrs=["11,12,13,14,15"])65 66 # this will fail if we don't do [] as regex correctly67 self.runCmd('type summary add --summary-string "${var[].integer}" "i_am_cool[]')68 69 self.expect("frame variable cool_array", substrs=["1,1,1,1,6"])70 71 self.runCmd("type summary clear")72 73 self.runCmd('type summary add --summary-string "${var[1-0]%x}" "int"')74 75 self.expect("frame variable iAmInt", substrs=["01"])76 77 self.runCmd('type summary add --summary-string "${var[0-1]%x}" "int"')78 79 self.expect("frame variable iAmInt", substrs=["01"])80 81 self.runCmd("type summary clear")82 83 self.runCmd('type summary add --summary-string "${var[0-1]%x}" int')84 self.runCmd('type summary add --summary-string "${var[0-31]%x}" float')85 86 self.expect("frame variable *pointer", substrs=["0x", "2"])87 88 # check fix for <rdar://problem/11338654> LLDB crashes when using a89 # "type summary" that uses bitfields with no format90 self.runCmd('type summary add --summary-string "${var[0-1]}" int')91 self.expect("frame variable iAmInt", substrs=["9 1"])92 93 self.expect("frame variable cool_array[3].floating", substrs=["0x"])94 95 self.runCmd(96 'type summary add --summary-string "low bits are ${*var[0-1]} tgt is ${*var}" "int *"'97 )98 99 self.expect("frame variable pointer", substrs=["low bits are", "tgt is 6"])100 101 self.expect(102 'frame variable int_array --summary-string "${*var[0-1]}"', substrs=["3"]103 )104 105 self.runCmd("type summary clear")106 107 self.runCmd(108 r'type summary add --summary-string "${var[0-1]}" -x "int\[[0-9]\]"'109 )110 111 self.expect("frame variable int_array", substrs=["1,2"])112 113 self.runCmd('type summary add --summary-string "${var[0-1]}" "int[]"')114 115 self.expect("frame variable int_array", substrs=["1,2"])116 117 # Test the patterns are matched in reverse-chronological order.118 self.runCmd('type summary add --summary-string "${var[2-3]}" "int[]"')119 120 self.expect("frame variable int_array", substrs=["3,4"])121 122 self.runCmd("type summary clear")123 124 self.runCmd(r'type summary add -c -x "i_am_cool\[[0-9]\]"')125 self.runCmd("type summary add -c i_am_cool")126 127 self.expect(128 "frame variable cool_array",129 substrs=[130 "[0]",131 "integer",132 "floating",133 "character",134 "[1]",135 "integer",136 "floating",137 "character",138 "[2]",139 "integer",140 "floating",141 "character",142 "[3]",143 "integer",144 "floating",145 "character",146 "[4]",147 "integer",148 "floating",149 "character",150 ],151 )152 153 self.runCmd(154 'type summary add --summary-string "int = ${*var.int_pointer}, float = ${*var.float_pointer}" IWrapPointers'155 )156 157 self.expect("frame variable wrapper", substrs=["int = 4", "float = 1.1"])158 159 self.runCmd(160 'type summary add --summary-string "low bits = ${*var.int_pointer[2]}" IWrapPointers -p'161 )162 163 self.expect("frame variable wrapper", substrs=["low bits = 1"])164 165 self.expect("frame variable *wrap_pointer", substrs=["low bits = 1"])166 167 self.runCmd("type summary clear")168 169 self.expect(170 'frame variable int_array --summary-string "${var[0][0-2]%hex}"',171 substrs=["0x", "7"],172 )173 174 self.runCmd("type summary clear")175 176 self.runCmd(177 r'type summary add --summary-string "${*var[].x[0-3]%hex} is a bitfield on a set of integers" -x "SimpleWithPointers\[[0-9]\]"'178 )179 180 self.expect(181 'frame variable couple --summary-string "${*var.sp.x[0-2]} are low bits of integer ${*var.sp.x}. If I pretend it is an array I get ${var.sp.x[0-5]}"',182 substrs=[183 "1 are low bits of integer 9.",184 "If I pretend it is an array I get [9,",185 ],186 )187 188 # if the summary has an error, we still display the value189 self.expect(190 'frame variable couple --summary-string "${*var.sp.foo[0-2]"',191 substrs=["(Couple) couple = {", "x = 0x", "y = 0x", "z = 0x", "s = 0x"],192 )193 194 self.runCmd(195 'type summary add --summary-string "${*var.sp.x[0-2]} are low bits of integer ${*var.sp.x}. If I pretend it is an array I get ${var.sp.x[0-5]}" Couple'196 )197 198 self.expect(199 "frame variable sparray", substrs=["[0x0000000f,0x0000000c,0x00000009]"]200 )201 202 # check that we can format a variable in a summary even if a format is203 # defined for its datatype204 self.runCmd("type format add -f hex int")205 self.runCmd('type summary add --summary-string "x=${var.x%d}" Simple')206 207 self.expect("frame variable a_simple_object", substrs=["x=3"])208 209 self.expect("frame variable a_simple_object", matching=False, substrs=["0x0"])210 211 # now check that the default is applied if we do not hand out a format212 self.runCmd('type summary add --summary-string "x=${var.x}" Simple')213 214 self.expect("frame variable a_simple_object", matching=False, substrs=["x=3"])215 216 self.expect(217 "frame variable a_simple_object", matching=True, substrs=["x=0x00000003"]218 )219 220 self.expect_var_path("constInt", value="0x0000002a")221 222 self.expect_var_path("volatileInt", value="0x0000002b")223 224 self.expect_var_path("constVolatileInt", value="0x0000002c")225 226 # check that we can correctly cap the number of children shown227 self.runCmd("settings set target.max-children-count 5")228 229 self.expect(230 "frame variable a_long_guy",231 matching=True,232 substrs=["a_1", "b_1", "c_1", "d_1", "e_1", "..."],233 )234 235 # check that no further stuff is printed (not ALL values are checked!)236 self.expect(237 "frame variable a_long_guy",238 matching=False,239 substrs=[240 "f_1",241 "g_1",242 "h_1",243 "i_1",244 "j_1",245 "q_1",246 "a_2",247 "f_2",248 "t_2",249 "w_2",250 ],251 )252 253 self.runCmd("settings set target.max-children-count 1")254 self.expect("frame variable a_long_guy", matching=True, substrs=["a_1", "..."])255 self.expect(256 "frame variable a_long_guy",257 matching=False,258 substrs=["b_1", "c_1", "d_1", "e_1"],259 )260 self.expect(261 "frame variable a_long_guy",262 matching=False,263 substrs=[264 "f_1",265 "g_1",266 "h_1",267 "i_1",268 "j_1",269 "q_1",270 "a_2",271 "f_2",272 "t_2",273 "w_2",274 ],275 )276 277 self.runCmd("settings set target.max-children-count 30")278 self.expect(279 "frame variable a_long_guy",280 matching=True,281 substrs=[282 "a_1",283 "b_1",284 "c_1",285 "d_1",286 "e_1",287 "z_1",288 "a_2",289 "b_2",290 "c_2",291 "d_2",292 "...",293 ],294 )295 self.expect(296 "frame variable a_long_guy",297 matching=False,298 substrs=["e_2", "n_2", "r_2", "i_2", "k_2", "o_2"],299 )300 301 self.runCmd("settings set target.max-string-summary-length 5")302 some_string = self.frame().FindVariable("some_string")303 some_string_summary = some_string.GetSummary()304 if re.match(r"^std::__\w+::", some_string.GetTypeName()):305 self.assertEqual(some_string_summary, '"01234"...')306 else:307 # libstdc++ string formatter suffers from the same problem as some_cstring below308 pass309 310 some_carr = self.frame().FindVariable("some_carr")311 some_carr_summary = some_carr.GetSummary()312 self.assertEqual(some_carr_summary, '"01234"...')313 314 # FIXME: c-strings should honor the target.max-string-summary-length315 # setting. Currently a C-string will be truncated at 64 (an internal316 # implementation detail) instead of the value specified in the setting.317 some_cstring = self.frame().FindVariable("some_cstring")318 some_cstring_summary = some_cstring.GetSummary()319 self.assertEqual(len(some_cstring_summary), 66) # 64 + 2 (for quotation marks)320 self.assertFalse(some_cstring_summary.endswith("..."))321 322 # override the cap323 self.expect(324 "frame variable a_long_guy --show-all-children",325 matching=True,326 substrs=[327 "a_1",328 "b_1",329 "c_1",330 "d_1",331 "e_1",332 "z_1",333 "a_2",334 "b_2",335 "c_2",336 "d_2",337 ],338 )339 self.expect(340 "frame variable a_long_guy --show-all-children",341 matching=True,342 substrs=[343 "e_2",344 "i_2",345 "k_2",346 "n_2",347 "o_2",348 "r_2",349 ],350 )351 self.expect(352 "frame variable a_long_guy --show-all-children",353 matching=False,354 substrs=["..."],355 )356