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