Home | History | Annotate | Line # | Download | only in gdb.base
dlmopen.exp revision 1.1.1.1
      1 # This testcase is part of GDB, the GNU debugger.
      2 #
      3 # Copyright 2021-2023 Free Software Foundation, Inc.
      4 #
      5 # This program is free software; you can redistribute it and/or modify
      6 # it under the terms of the GNU General Public License as published by
      7 # the Free Software Foundation; either version 3 of the License, or
      8 # (at your option) any later version.
      9 #
     10 # This program is distributed in the hope that it will be useful,
     11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 # GNU General Public License for more details.
     14 #
     15 # You should have received a copy of the GNU General Public License
     16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 #
     18 #
     19 # Test shared libraries loaded into different namespaces with dlmopen().
     20 #
     21 # We test that GDB shows the correct number of instances of the libraries
     22 # the test loaded while unloading them one-by-one.
     23 
     24 if { [skip_dlmopen_tests] } {
     25     unsupported "target does not support dlmopen debugging"
     26     return -1
     27 }
     28 
     29 standard_testfile
     30 
     31 set basename_lib dlmopen-lib
     32 set srcfile_lib $srcdir/$subdir/$basename_lib.c
     33 set binfile_lib1 [standard_output_file $basename_lib.1.so]
     34 set binfile_lib2 [standard_output_file $basename_lib.2.so]
     35 set srcfile_lib_dep $srcdir/$subdir/$basename_lib-dep.c
     36 set binfile_lib_dep [standard_output_file $basename_lib-dep.so]
     37 
     38 if { [gdb_compile_shlib $srcfile_lib_dep $binfile_lib_dep {debug}] != "" } {
     39     untested "failed to prepare shlib"
     40     return -1
     41 }
     42 
     43 if { [gdb_compile_shlib $srcfile_lib $binfile_lib1 \
     44 	  [list debug shlib_load libs=$binfile_lib_dep]] != "" } {
     45     untested "failed to prepare shlib"
     46     return -1
     47 }
     48 
     49 if { [gdb_compile_shlib $srcfile_lib $binfile_lib2 \
     50 	  [list debug shlib_load libs=$binfile_lib_dep]] != "" } {
     51     untested "failed to prepare shlib"
     52     return -1
     53 }
     54 
     55 if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
     56 	  [list additional_flags=-DDSO1_NAME=\"$binfile_lib1\" \
     57 	       additional_flags=-DDSO2_NAME=\"$binfile_lib2\" \
     58 	       shlib_load debug]] } {
     59     return -1
     60 }
     61 
     62 if { ![runto_main] } {
     63     return -1
     64 }
     65 
     66 # Check that 'info shared' show NUM occurrences of DSO.
     67 proc check_dso_count { dso num } {
     68     global gdb_prompt hex
     69 
     70     set count 0
     71     gdb_test_multiple "info shared" "info shared" {
     72 	-re "$hex  $hex  Yes \[^\r\n\]*$dso\r\n" {
     73 	    # use longer form so debug remote does not interfere
     74 	    set count [expr $count + 1]
     75 	    exp_continue
     76 	}
     77 	-re "$gdb_prompt " {
     78 	    verbose -log "library: $dso, expected: $num, found: $count"
     79 	    gdb_assert {$count == $num} "$gdb_test_name"
     80 	}
     81     }
     82 }
     83 
     84 # The DSO part of the test.  We run it once per DSO call.
     85 proc test_dlmopen_one { ndso1 ndso2 exp_glob } {
     86     global srcfile_lib srcfile_lib basename_lib bp_inc
     87 
     88     # Try to reach the breakpoint in the dynamically loaded library.
     89     gdb_continue_to_breakpoint "cont to bp.inc" \
     90 	".*$srcfile_lib:$bp_inc\r\n.*"
     91 
     92     # We opened all DSOs initially and close them one by one.
     93     with_test_prefix "dso 1" { check_dso_count $basename_lib.1.so $ndso1 }
     94     with_test_prefix "dso 2" { check_dso_count $basename_lib.2.so $ndso2 }
     95 
     96     # This might help debugging.
     97     gdb_test "info breakpoints" ".*"
     98     gdb_test "print \$pc" ".*"
     99 
    100     # We expect different instances of GDB_DLMOPEN_GLOB per DSO.
    101     gdb_test "print amount" "= $exp_glob"
    102     gdb_test "print gdb_dlmopen_glob" "= $exp_glob"
    103 
    104     # Modify that DSO's instance, which should leave the others intact.
    105     gdb_test "print &gdb_dlmopen_glob" "= .*"
    106     gdb_test "print gdb_dlmopen_glob = -1" "= -1"
    107 }
    108 
    109 # The actual test.  We run it twice.
    110 proc test_dlmopen {} {
    111     global srcfile basename_lib bp_main
    112 
    113     # Note that when loading dlmopen-lib.1.so and dlmopen-lib.2.so into
    114     # the same namespace, dlmopen-lib-dep.so is loaded only once, so in
    115     # this case, the changes to gdb_dlmopen_glob inside test_dlmopen_one
    116     # will actually be visible.
    117     #
    118     # Hence, we supply the expected value of this variable as argument to
    119     # test_dlmopen_one.
    120     with_test_prefix "dlmopen 1" { test_dlmopen_one 3 1 1 }
    121     with_test_prefix "dlmopen 2" { test_dlmopen_one 2 1 1 }
    122     with_test_prefix "dlmopen 3" { test_dlmopen_one 1 1 1 }
    123     with_test_prefix "dlmopen 4" { test_dlmopen_one 0 1 -1 }
    124 
    125     with_test_prefix "main" {
    126 	# Try to reach the breakpoint in the dynamically loaded library.
    127 	gdb_continue_to_breakpoint "cont to bp.main" \
    128 	    ".*$srcfile:$bp_main\r\n.*"
    129 
    130 	# The library should not be listed.
    131 	with_test_prefix "dso 1" { check_dso_count $basename_lib.1.so 0 }
    132 	with_test_prefix "dso 2" { check_dso_count $basename_lib.2.so 0 }
    133     }
    134 }
    135 
    136 # Remove the pause.  We only need it for the attach test.
    137 gdb_test "print wait_for_gdb = 0" "\\\$1 = 0"
    138 
    139 # Break in the to-be-loaded library and at the end of main.
    140 set bp_inc [gdb_get_line_number "bp.inc" $srcfile_lib]
    141 set bp_main [gdb_get_line_number "bp.main" $srcfile]
    142 
    143 delete_breakpoints
    144 gdb_breakpoint $srcfile_lib:$bp_inc allow-pending
    145 gdb_breakpoint $srcfile:$bp_main
    146 
    147 test_dlmopen
    148 
    149 # Try the same again when attaching after dlmopen().
    150 if { ![can_spawn_for_attach] } {
    151     unsupported "target does not support attach"
    152     return -1
    153 }
    154 
    155 clean_restart $binfile
    156 
    157 # Start the test program.
    158 set test_spawn_id [spawn_wait_for_attach $binfile]
    159 set testpid [spawn_id_get_pid $test_spawn_id]
    160 
    161 # Attach.
    162 if { ![gdb_attach $testpid] } {
    163     return
    164 }
    165 
    166 with_test_prefix "attach" {
    167     # Remove the pause.  We no longer need it.
    168     gdb_test "print wait_for_gdb = 0" "\\\$1 = 0"
    169 
    170     # Set the same breakpoints again.  This time, however, we do not allow the
    171     # breakpoint to be pending since the library has already been loaded.
    172     gdb_breakpoint $srcfile_lib:$bp_inc
    173     gdb_breakpoint $srcfile:$bp_main
    174 
    175     test_dlmopen
    176 }
    177