1 # Copyright (C) 2008-2025 Free Software Foundation, Inc. 2 3 # This program is free software; you can redistribute it and/or modify 4 # it under the terms of the GNU General Public License as published by 5 # the Free Software Foundation; either version 3 of the License, or 6 # (at your option) any later version. 7 # 8 # This program is distributed in the hope that it will be useful, 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 # GNU General Public License for more details. 12 # 13 # You should have received a copy of the GNU General Public License 14 # along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 # This file is part of the GDB testsuite. It tests Python-based 17 # pretty-printing for MI. 18 19 load_lib mi-support.exp 20 set MIFLAGS "-i=mi2" 21 22 standard_testfile py-prettyprint.c 23 set pyfile py-prettyprint.py 24 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DMI}] != "" } { 25 untested "failed to compile" 26 return -1 27 } 28 29 if {[mi_clean_restart $::testfile]} { 30 return 31 } 32 33 if {[lsearch -exact [mi_get_features] python] < 0} { 34 unsupported "python support is disabled" 35 return -1 36 } 37 38 mi_runto_main 39 40 set remote_python_file [gdb_remote_download host ${srcdir}/${subdir}/${pyfile}] 41 42 set cmd "source ${remote_python_file}" 43 set re [string_list_to_regexp & {"} $cmd \\ n {"} \r\n ^ done] 44 mi_gdb_test $cmd $re "load python file" 45 46 mi_continue_to_line [gdb_get_line_number {MI breakpoint here} ${srcfile}] \ 47 "step to breakpoint" 48 49 with_test_prefix "varobj container" { 50 mi_create_floating_varobj container c \ 51 "create container varobj, no pretty-printing" 52 53 mi_list_varobj_children container { 54 { container.name name 1 string } 55 { container.len len 0 int } 56 { container.elements elements 1 "int ." } 57 } "examine container children=0, no pretty-printing" 58 59 mi_delete_varobj container "delete varobj" 60 } 61 62 with_test_prefix "varobj nscont" { 63 mi_create_floating_varobj nscont nstype \ 64 "create nscont varobj, no pretty-printing" 65 66 mi_list_varobj_children nscont { 67 { nscont.len len 0 int } 68 { nscont.elements elements 1 "int ." } 69 } "examine nscont children=0, no pretty-printing" 70 71 mi_delete_varobj nscont "delete varobj" 72 } 73 74 mi_gdb_test "-enable-pretty-printing" "\\^done" 75 76 mi_create_varobj_checked string string_1 \ 77 "struct string_repr" \ 78 "create string_1 varobj" 79 80 mi_create_varobj_checked lstring estring \ 81 "struct lazystring" \ 82 "create estring varobj" 83 84 mi_gdb_test "-data-evaluate-expression \"string_1 = string_2\"" ".*" \ 85 "assign string_1 from string_2" 86 87 mi_gdb_test "-var-update string" \ 88 "\\^done,changelist=\\\[{name=\"string\",in_scope=\"true\",type_changed=\"false\",dynamic=\"1\",has_more=\"0\"}\\\]" \ 89 "update string varobj after assignment" 90 91 with_test_prefix "varobj container" { 92 # The "elements" field of "c" is still empty, so the attribute 93 # "has_more" is expected to be zero. 94 mi_create_dynamic_varobj container c "container .* with 0 elements" 0 \ 95 "create container varobj" 96 97 mi_list_varobj_children container { 98 } "examine container children=0" 99 100 mi_next "next over update 1" 101 102 mi_varobj_update_dynamic container "varobj update 1" { 103 type_changed false new_num_children 1 dynamic 1 has_more 0 104 } { 105 } { 106 { name {container.\[0\]} exp {\[0\]} numchild 0 type int } 107 } 108 109 mi_next "next over update 2" 110 111 mi_varobj_update_dynamic container "varobj update 2" { 112 type_changed false new_num_children 2 dynamic 1 has_more 0 113 } { 114 } { 115 { name {container.\[1\]} exp {\[1\]} numchild 0 type int } 116 } 117 118 mi_gdb_test "-var-set-visualizer container None" \ 119 "\\^done" \ 120 "clear visualizer" 121 122 mi_gdb_test "-var-update container" \ 123 "\\^done,changelist=\\\[\\\]" \ 124 "varobj update after clearing" 125 126 mi_gdb_test "-var-set-visualizer container gdb.default_visualizer" \ 127 "\\^done" \ 128 "choose default visualizer" 129 130 mi_varobj_update_dynamic container "varobj update after choosing default" { 131 type_changed false new_num_children 2 dynamic 1 has_more 0 132 } { 133 } { 134 { name {container.\[0\]} exp {\[0\]} numchild 0 type int } 135 { name {container.\[1\]} exp {\[1\]} numchild 0 type int } 136 } 137 138 mi_gdb_test "-var-set-visualizer container ContainerPrinter" \ 139 "\\^done" \ 140 "choose visualizer using expression" 141 142 mi_varobj_update_dynamic container \ 143 "varobj update after choosing via expression" { 144 type_changed false new_num_children 2 dynamic 1 has_more 0 145 } { 146 } { 147 { name {container.\[0\]} exp {\[0\]} numchild 0 type int } 148 { name {container.\[1\]} exp {\[1\]} numchild 0 type int } 149 } 150 151 mi_list_varobj_children_range container 1 2 2 { 152 { {container.\[1\]} {\[1\]} 0 int } 153 } "list varobj children after selecting child range" 154 155 mi_list_varobj_children_range container -1 -1 2 { 156 { {container.\[0\]} {\[0\]} 0 int } 157 { {container.\[1\]} {\[1\]} 0 int } 158 } "list varobj children after resetting child range" 159 160 mi_next "next over update 3" 161 162 mi_gdb_test "-var-set-update-range container 0 1" \ 163 "\\^done" \ 164 "set update range" 165 166 # This should truncate the list. 167 mi_list_varobj_children container { 168 { {container.\[0\]} {\[0\]} 0 int } 169 } "list children after setting update range" 170 171 # This should return just the items in [1,2). 172 mi_list_varobj_children_range container 1 2 2 { 173 { {container.\[1\]} {\[1\]} 0 int } 174 } "list selected children after setting range" 175 176 # This should not be affected by the previous list-children request. 177 mi_list_varobj_children container { 178 { {container.\[0\]} {\[0\]} 0 int } 179 } "list children after listing selected range" 180 181 mi_next "next over update 4" 182 183 # This should only show the first child, because the update range has 184 # been set. 185 mi_varobj_update_dynamic container \ 186 "update after next with restricted range" { 187 type_changed false new_num_children 1 dynamic 1 has_more 1 188 } { 189 { name {container.\[0\]} in_scope true type_changed false has_more 0 } 190 } { 191 } 192 193 mi_gdb_test "-var-set-update-range container 3 4" \ 194 "\\^done" \ 195 "set update range with non-zero start" 196 197 # Elements were updated but should not be reported. 198 mi_varobj_update_dynamic container \ 199 "update varobj with change outside selected range" { 200 type_changed false new_num_children 3 dynamic 1 has_more 0 201 } { 202 } { 203 } 204 } 205 206 mi_next "next over update 5" 207 208 # Regression test: examine an object that has no children, then update 209 # it to ensure that we don't print the children. 210 mi_create_dynamic_varobj container2 c2 "container .* with 0 elements" 0 \ 211 "create second container varobj" 212 213 mi_gdb_test "-var-update container2" \ 214 "\\^done,changelist=.." \ 215 "update varobj, no children requested" 216 217 mi_next "next over update 6" 218 219 # Now container2 has an element -- and an update should mention that 220 # it has_more. But, because we did not request children, we still 221 # should not actually see them. 222 mi_varobj_update_dynamic container2 \ 223 "update varobj 2, no children requested" { 224 type_changed false dynamic 1 has_more 1 225 } {} {} 226 227 mi_continue_to_line \ 228 [gdb_get_line_number {MI outer breakpoint here} ${srcfile}] \ 229 "step to first outer breakpoint" 230 231 mi_create_dynamic_varobj outer outer "x = 0" 1 \ 232 "create outer varobj" 233 234 mi_list_varobj_children outer { 235 { outer.s s 2 "struct substruct" } 236 { outer.x x 0 "int" } 237 } "list children of outer" 238 239 mi_list_varobj_children outer.s { 240 { outer.s.a a 0 int } 241 { outer.s.b b 0 int } 242 } "list children of outer.s" 243 244 mi_next "next over outer update" 245 246 mi_gdb_test "-var-update outer" \ 247 ".done,changelist=.{name=\"outer.s.a\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"}." \ 248 "update after updating element of outer" 249 250 mi_continue_to_line \ 251 [gdb_get_line_number {Another MI breakpoint} ${srcfile}] \ 252 "step to second breakpoint" 253 254 mi_varobj_update_with_type_change container int 0 "update after type change" 255 256 257 mi_continue_to_line \ 258 [gdb_get_line_number {break to inspect struct and union} ${srcfile}] \ 259 "step to second outer breakpoint" 260 261 with_test_prefix "varobj nscont" { 262 mi_create_dynamic_varobj nscont nstype ".*" 1 \ 263 "create nstype varobj" 264 265 mi_list_varobj_children nscont { 266 { {nscont.\[0\]} {\[0\]} 0 int } 267 { {nscont.\[1\]} {\[1\]} 0 int } 268 } "list children after setting update range" 269 270 mi_gdb_test "-var-set-visualizer nscont None" \ 271 "\\^done" \ 272 "clear visualizer" 273 274 mi_gdb_test "-var-update nscont" \ 275 "\\^done,changelist=\\\[\\\]" \ 276 "varobj update after clearing" 277 278 mi_gdb_test "-var-set-visualizer nscont gdb.default_visualizer" \ 279 "\\^done" \ 280 "choose default visualizer" 281 } 282 283 set cmd "python exception_flag = True" 284 set re [string_list_to_regexp & {"} $cmd \\ n {"} \r\n ^ done] 285 mi_gdb_test $cmd $re 286 287 mi_create_dynamic_varobj nstype2 nstype2 ".*" 1 \ 288 "create nstype2 varobj" 289 290 mi_list_varobj_children nstype2 { 291 { {nstype2.<error at 0>} {<error at 0>} 7 {char \[7\]} } 292 } "list children after setting exception flag" 293 294 mi_create_varobj me me \ 295 "create me varobj" 296 297 mi_gdb_test "-var-evaluate-expression me" \ 298 "\\^done,value=\"<error reading variable: Cannot access memory.>.*\"" \ 299 "evaluate me varobj" 300 301 # Regression test for python/14836. 302 mi_create_dynamic_varobj children_as_list children_as_list \ 303 children_as_list_val 1 \ 304 "printer whose children are returned as a list" 305 306 # Test that when a pretty-printer returns a gdb.Value in its to_string, we call 307 # the pretty-printer of that value too. 308 mi_create_varobj_checked tsrvw tsrvw \ 309 "struct to_string_returns_value_wrapper" \ 310 "create tsrvw varobj" 311 mi_check_varobj_value tsrvw "Inner to_string 1989" "check tsrvw varobj value" 312 mi_gdb_test "-data-evaluate-expression tsrvw" \ 313 "\\^done,value=\"Inner to_string 1989\"" \ 314 "check tsrvw expression value" 315 316 # Regression test for bug 14741. 317 mi_continue_to_line \ 318 [gdb_get_line_number {breakpoint bug 14741} ${srcfile}] \ 319 "step to breakpoint for bug 14741" 320 321 mi_create_dynamic_varobj c c "container .* with 1 elements" 1 \ 322 "create varobj for c" 323 324 mi_gdb_test "-var-set-visualizer c ArrayPrinter" \ 325 "\\^done" \ 326 "choose array visualizer for c" 327 328 mi_list_varobj_children c { 329 { {c.\[0\]} {\[0\]} 0 int } 330 } "list children of c" 331 332 mi_next "next over change of array element" 333 334 # 'c' is noticed as changing here due to an artifact of the 335 # -var-update implementation. However, it seems harmless. 336 mi_gdb_test "-var-update c" \ 337 "\\^done,changelist=\\\[{name=\"c\",in_scope=\"true\",type_changed=\"false\",displayhint=\"array\",dynamic=\"1\",has_more=\"0\"},{name=\"c.\\\[0\\\]\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"}\\\]" \ 338 "update varobj after element change" 339 340 # C++ MI tests 341 gdb_exit 342 if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}-cxx" \ 343 executable {debug c++ additional_flags=-DMI}] != "" } { 344 untested "failed to compile in C++ mode" 345 return -1 346 } 347 348 if {[mi_clean_restart ${::testfile}-cxx]} { 349 return 350 } 351 352 if {[lsearch -exact [mi_get_features] python] < 0} { 353 unsupported "python support is disabled" 354 return -1 355 } 356 357 with_test_prefix "varobj fake" { 358 mi_runto_main 359 mi_continue_to_line \ 360 [gdb_get_line_number {break to inspect struct and union} ${srcfile}] \ 361 "step to breakpoint" 362 363 # Test python/12531. Install visualizer on a cplus_fake_child. 364 mi_create_varobj fake fake \ 365 "create fake varobj" 366 367 mi_list_varobj_children fake { 368 { fake.private private 1 } 369 } "list children of fake" 370 371 mi_list_varobj_children fake.private { 372 { fake.private.sname sname 0 int } 373 } "list children fake.private" 374 375 mi_gdb_test "-var-set-visualizer fake.private gdb.default_visualizer" \ 376 "\\^done" "Install visualizer on a cplus_fake_child" 377 } 378