Home | History | Annotate | Line # | Download | only in gdb.python
      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