Home | History | Annotate | Line # | Download | only in gdb.mi
mi-var-invalidate-shlib.exp revision 1.1.1.1
      1 # Copyright 2007-2023 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 # Test that varobj are invalidated after the shlib they point to goes
     17 # away.
     18 
     19 
     20 load_lib mi-support.exp
     21 set MIFLAGS "-i=mi"
     22 
     23 if { [skip_shlib_tests] } {
     24     return 0
     25 }
     26 
     27 standard_testfile .c -lib.c
     28 set shlib_path [standard_output_file ${testfile}-lib.so]
     29 
     30 if { [gdb_compile_shlib $srcdir/$subdir/$srcfile2 $shlib_path {debug}] != "" } {
     31     untested "failed to compile"
     32     return -1
     33 }
     34 
     35 
     36 set opts [list shlib_load debug additional_flags=-DSHLIB_PATH="${shlib_path}"]
     37 if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $opts] != "" } {
     38     untested "failed to compile"
     39     return -1
     40 }
     41 
     42 proc do_test { separate_debuginfo } {
     43     if { [mi_clean_restart] } {
     44 	unsupported "failed to start GDB"
     45 	return
     46     }
     47 
     48     # Start the process once and create varobjs referencing the loaded objfiles.
     49     with_test_prefix "setup" {
     50 	mi_load_shlibs $::shlib_path
     51 	if { $separate_debuginfo } {
     52 	    mi_load_shlibs ${::shlib_path}.debug
     53 	}
     54 	mi_delete_breakpoints
     55 	mi_gdb_reinitialize_dir $::srcdir/$::subdir
     56 	mi_gdb_load $::binfile
     57 
     58 	mi_runto foo -pending
     59 
     60 	mi_create_varobj global_var global_var "create global global_var"
     61 	mi_create_varobj global_shlib_var global_shlib_var "create global gloal_shlib_var"
     62 	mi_create_floating_varobj floating_local local_var "create floating local_var"
     63 
     64 	# Advance to a point where the shlib's objfile have been deleted.
     65 	mi_continue_to "no_varobj_in_scope"
     66     }
     67 
     68     with_test_prefix "after objfile deleted" {
     69 	# The global shlib var was invalidated when the objfile got unloaded.
     70 	mi_gdb_test "-var-update global_shlib_var" \
     71 	    "\\^done,changelist=\\\[\{name=\"global_shlib_var\",in_scope=\"invalid\",has_more=\"0\"\}\]" \
     72 	    "global_shlib_var invalidated"
     73 
     74 	# The floating var is still valid but not in scope.
     75 	mi_gdb_test "-var-update floating_local" \
     76 	    "\\^done,changelist=\\\[{name=\"floating_local\",in_scope=\"false\",type_changed=\"false\",has_more=\"0\"}\\\]" \
     77 	    "floating_local still valid but not in scope"
     78 
     79 	mi_gdb_test "-var-update global_var" \
     80 	    "\\^done,changelist=\\\[\\\]" \
     81 	    "global_var still valid"
     82 
     83 	# The varobj can be re-evaluated if the expression is valid in the current
     84 	# frame.
     85 	mi_continue_to "floating_varobj_in_scope"
     86 	mi_gdb_test "-var-update floating_local" \
     87 	    "\\^done,changelist=\\\[{name=\"floating_local\",in_scope=\"true\",type_changed=\"true\",new_type=\"int\",new_num_children=\"0\",has_more=\"0\"}\\\]" \
     88 	    "floating_local in scope with new type and value"
     89     }
     90 
     91     # Reload the entire process
     92     with_test_prefix "restart process" {
     93 	mi_delete_breakpoints
     94 	mi_gdb_load ${::binfile}
     95 	mi_runto_main
     96     }
     97 
     98     with_test_prefix "in new process" {
     99 	# When reloading the symbol file, only the var for the global in the main
    100 	# executable is re-created.
    101 	mi_gdb_test "-var-update global_var" \
    102 	    "\\^done,changelist=\\\[\\\]" \
    103 	    "global_var recreated"
    104 	mi_gdb_test "-var-update global_shlib_var" \
    105 	    "\\^done,changelist=\\\[{name=\"global_shlib_var\",in_scope=\"invalid\",has_more=\"0\"}\\\]" \
    106 	    "global_shlib_var invalid"
    107 
    108 	# Floating varobj should still be valid, but out of scope at the moment.
    109 	mi_gdb_test "-var-update floating_local" \
    110 	    "\\^done,changelist=\\\[{name=\"floating_local\",in_scope=\"false\",type_changed=\"false\",has_more=\"0\"}\\\]" \
    111 	    "floating_local still valid but not in scope"
    112 
    113 	# Continue inside foo
    114 	mi_gdb_test "299-break-insert -f -t foo" \
    115 	    "&\"Function \\\\\"foo\\\\\" not defined.\\\\n\"\r\n299\\^done,[mi_make_breakpoint_pending -type breakpoint -disp del -pending foo]"
    116 	mi_send_resuming_command "exec-continue" "continue to foo"
    117 	mi_expect_stop "breakpoint-hit" foo ".*" ".*" "\[0-9\]+" { "" "disp=\"del\"" } "arrived at foo"
    118 
    119 	# Floating varobj is still valid, and now in scope.
    120 	mi_gdb_test "-var-update floating_local" \
    121 	    "\\^done,changelist=\\\[{name=\"floating_local\",in_scope=\"true\",type_changed=\"true\",new_type=\"struct bar\",new_num_children=\"2\",has_more=\"0\"}\\\]" \
    122 	    "floating_local still valid and in scope"
    123 
    124 	# The var for the global in the shlib stays invalid even after reloading the shlib.
    125 	mi_gdb_test "-var-update global_shlib_var" \
    126 	    "\\^done,changelist=\\\[{name=\"global_shlib_var\",in_scope=\"invalid\",has_more=\"0\"}\\\]" \
    127 	    "global_shlib_var invalid after shlib loaded"
    128     }
    129 }
    130 
    131 proc_with_prefix local_not_invalidated { separate_debuginfo } {
    132     if { [mi_clean_restart] } {
    133 	unsupported "failed to start GDB"
    134 	return
    135     }
    136 
    137     # Start the process once and create varobjs referencing the loaded objfiles.
    138     with_test_prefix "setup" {
    139 	mi_load_shlibs $::shlib_path
    140 	if { $separate_debuginfo } {
    141 	    mi_load_shlibs ${::shlib_path}.debug
    142 	}
    143 
    144 	mi_gdb_reinitialize_dir $::srcdir/$::subdir
    145 	mi_gdb_load $::binfile
    146 
    147 	mi_runto foo -pending
    148 	mi_next "next"
    149 	mi_create_varobj local_var local_var "create local varobj"
    150     }
    151 
    152     # At this point we are stopped in the shared library.  If we reload symbols
    153     # for the main binary, symbols for the shared library remain valid.  A
    154     # varobj tracking variables in the scope of the shared library only should
    155     # not be invalidated.
    156     mi_gdb_load ${::binfile}
    157     mi_gdb_test "-var-update local_var" \
    158 	"\\^done,changelist=\\\[\\\]" \
    159 	"local_var preserved"
    160 }
    161 
    162 foreach_with_prefix separate_debuginfo {0 1} {
    163     if { $separate_debuginfo } {
    164 	gdb_gnu_strip_debug $::shlib_path
    165     }
    166 
    167     do_test $separate_debuginfo
    168     local_not_invalidated $separate_debuginfo
    169 }
    170