1""" 2Test lldb data formatter subsystem. 3""" 4 5 6import lldb 7from lldbsuite.test.lldbtest import * 8import lldbsuite.test.lldbutil as lldbutil 9import re 10 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=True 26 ) 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 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("settings set target.max-children-count 256", 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 correctly 67 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 a 89 # "type summary" that uses bitfields with no format 90 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('type summary add --summary-string "${var[0-1]}" -x "int\[[0-9]\]"') 108 109 self.expect("frame variable int_array", substrs=["1,2"]) 110 111 self.runCmd('type summary add --summary-string "${var[0-1]}" "int[]"') 112 113 self.expect("frame variable int_array", substrs=["1,2"]) 114 115 # Test the patterns are matched in reverse-chronological order. 116 self.runCmd('type summary add --summary-string "${var[2-3]}" "int[]"') 117 118 self.expect("frame variable int_array", substrs=["3,4"]) 119 120 self.runCmd("type summary clear") 121 122 self.runCmd('type summary add -c -x "i_am_cool\[[0-9]\]"') 123 self.runCmd("type summary add -c i_am_cool") 124 125 self.expect( 126 "frame variable cool_array", 127 substrs=[ 128 "[0]", 129 "integer", 130 "floating", 131 "character", 132 "[1]", 133 "integer", 134 "floating", 135 "character", 136 "[2]", 137 "integer", 138 "floating", 139 "character", 140 "[3]", 141 "integer", 142 "floating", 143 "character", 144 "[4]", 145 "integer", 146 "floating", 147 "character", 148 ], 149 ) 150 151 self.runCmd( 152 'type summary add --summary-string "int = ${*var.int_pointer}, float = ${*var.float_pointer}" IWrapPointers' 153 ) 154 155 self.expect("frame variable wrapper", substrs=["int = 4", "float = 1.1"]) 156 157 self.runCmd( 158 'type summary add --summary-string "low bits = ${*var.int_pointer[2]}" IWrapPointers -p' 159 ) 160 161 self.expect("frame variable wrapper", substrs=["low bits = 1"]) 162 163 self.expect("frame variable *wrap_pointer", substrs=["low bits = 1"]) 164 165 self.runCmd("type summary clear") 166 167 self.expect( 168 'frame variable int_array --summary-string "${var[0][0-2]%hex}"', 169 substrs=["0x", "7"], 170 ) 171 172 self.runCmd("type summary clear") 173 174 self.runCmd( 175 'type summary add --summary-string "${*var[].x[0-3]%hex} is a bitfield on a set of integers" -x "SimpleWithPointers\[[0-9]\]"' 176 ) 177 178 self.expect( 179 '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]}"', 180 substrs=[ 181 "1 are low bits of integer 9.", 182 "If I pretend it is an array I get [9,", 183 ], 184 ) 185 186 # if the summary has an error, we still display the value 187 self.expect( 188 'frame variable couple --summary-string "${*var.sp.foo[0-2]"', 189 substrs=["(Couple) couple = {", "x = 0x", "y = 0x", "z = 0x", "s = 0x"], 190 ) 191 192 self.runCmd( 193 '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' 194 ) 195 196 self.expect( 197 "frame variable sparray", substrs=["[0x0000000f,0x0000000c,0x00000009]"] 198 ) 199 200 # check that we can format a variable in a summary even if a format is 201 # defined for its datatype 202 self.runCmd("type format add -f hex int") 203 self.runCmd('type summary add --summary-string "x=${var.x%d}" Simple') 204 205 self.expect("frame variable a_simple_object", substrs=["x=3"]) 206 207 self.expect("frame variable a_simple_object", matching=False, substrs=["0x0"]) 208 209 # now check that the default is applied if we do not hand out a format 210 self.runCmd('type summary add --summary-string "x=${var.x}" Simple') 211 212 self.expect("frame variable a_simple_object", matching=False, substrs=["x=3"]) 213 214 self.expect( 215 "frame variable a_simple_object", matching=True, substrs=["x=0x00000003"] 216 ) 217 218 self.expect_var_path("constInt", value="0x0000002a") 219 220 self.expect_var_path("volatileInt", value="0x0000002b") 221 222 self.expect_var_path("constVolatileInt", value="0x0000002c") 223 224 # check that we can correctly cap the number of children shown 225 self.runCmd("settings set target.max-children-count 5") 226 227 self.expect( 228 "frame variable a_long_guy", 229 matching=True, 230 substrs=["a_1", "b_1", "c_1", "d_1", "e_1", "..."], 231 ) 232 233 # check that no further stuff is printed (not ALL values are checked!) 234 self.expect( 235 "frame variable a_long_guy", 236 matching=False, 237 substrs=[ 238 "f_1", 239 "g_1", 240 "h_1", 241 "i_1", 242 "j_1", 243 "q_1", 244 "a_2", 245 "f_2", 246 "t_2", 247 "w_2", 248 ], 249 ) 250 251 self.runCmd("settings set target.max-children-count 1") 252 self.expect("frame variable a_long_guy", matching=True, substrs=["a_1", "..."]) 253 self.expect( 254 "frame variable a_long_guy", 255 matching=False, 256 substrs=["b_1", "c_1", "d_1", "e_1"], 257 ) 258 self.expect( 259 "frame variable a_long_guy", 260 matching=False, 261 substrs=[ 262 "f_1", 263 "g_1", 264 "h_1", 265 "i_1", 266 "j_1", 267 "q_1", 268 "a_2", 269 "f_2", 270 "t_2", 271 "w_2", 272 ], 273 ) 274 275 self.runCmd("settings set target.max-children-count 30") 276 self.expect( 277 "frame variable a_long_guy", 278 matching=True, 279 substrs=[ 280 "a_1", 281 "b_1", 282 "c_1", 283 "d_1", 284 "e_1", 285 "z_1", 286 "a_2", 287 "b_2", 288 "c_2", 289 "d_2", 290 "...", 291 ], 292 ) 293 self.expect( 294 "frame variable a_long_guy", 295 matching=False, 296 substrs=["e_2", "n_2", "r_2", "i_2", "k_2", "o_2"], 297 ) 298 299 self.runCmd("settings set target.max-string-summary-length 5") 300 some_string = self.frame().FindVariable("some_string") 301 some_string_summary = some_string.GetSummary() 302 if re.match(r"^std::__\w+::", some_string.GetTypeName()): 303 self.assertEqual(some_string_summary, '"01234"...') 304 else: 305 # libstdc++ string formatter suffers from the same problem as some_cstring below 306 pass 307 308 some_carr = self.frame().FindVariable("some_carr") 309 some_carr_summary = some_carr.GetSummary() 310 self.assertEqual(some_carr_summary, '"01234"...') 311 312 # FIXME: c-strings should honor the target.max-string-summary-length 313 # setting. Currently a C-string will be truncated at 64 (an internal 314 # implementation detail) instead of the value specified in the setting. 315 some_cstring = self.frame().FindVariable("some_cstring") 316 some_cstring_summary = some_cstring.GetSummary() 317 self.assertEqual(len(some_cstring_summary), 66) # 64 + 2 (for quotation marks) 318 self.assertFalse(some_cstring_summary.endswith("...")) 319 320 # override the cap 321 self.expect( 322 "frame variable a_long_guy --show-all-children", 323 matching=True, 324 substrs=[ 325 "a_1", 326 "b_1", 327 "c_1", 328 "d_1", 329 "e_1", 330 "z_1", 331 "a_2", 332 "b_2", 333 "c_2", 334 "d_2", 335 ], 336 ) 337 self.expect( 338 "frame variable a_long_guy --show-all-children", 339 matching=True, 340 substrs=[ 341 "e_2", 342 "i_2", 343 "k_2", 344 "n_2", 345 "o_2", 346 "r_2", 347 ], 348 ) 349 self.expect( 350 "frame variable a_long_guy --show-all-children", 351 matching=False, 352 substrs=["..."], 353 ) 354