]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/testsuite/gdb.base/dlmopen.exp
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.base / dlmopen.exp
1 # This testcase is part of GDB, the GNU debugger.
2 #
3 # Copyright 2021-2024 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 require allow_dlmopen_tests
25
26 standard_testfile
27
28 set basename_lib dlmopen-lib
29 set srcfile_lib $srcdir/$subdir/$basename_lib.c
30 set binfile_lib1 [standard_output_file $basename_lib.1.so]
31 set binfile_lib2 [standard_output_file $basename_lib.2.so]
32 set srcfile_lib_dep $srcdir/$subdir/$basename_lib-dep.c
33 set binfile_lib_dep [standard_output_file $basename_lib-dep.so]
34
35 if { [gdb_compile_shlib $srcfile_lib_dep $binfile_lib_dep {debug}] != "" } {
36 untested "failed to prepare shlib"
37 return -1
38 }
39
40 if { [gdb_compile_shlib $srcfile_lib $binfile_lib1 \
41 [list debug shlib_load libs=$binfile_lib_dep]] != "" } {
42 untested "failed to prepare shlib"
43 return -1
44 }
45
46 if { [gdb_compile_shlib $srcfile_lib $binfile_lib2 \
47 [list debug shlib_load libs=$binfile_lib_dep]] != "" } {
48 untested "failed to prepare shlib"
49 return -1
50 }
51
52 if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
53 [list additional_flags=-DDSO1_NAME=\"$binfile_lib1\" \
54 additional_flags=-DDSO2_NAME=\"$binfile_lib2\" \
55 shlib_load debug]] } {
56 return -1
57 }
58
59 if { ![runto_main] } {
60 return -1
61 }
62
63 # Check that 'info shared' show NUM occurrences of DSO.
64 proc check_dso_count { dso num } {
65 global gdb_prompt hex
66
67 set count 0
68 gdb_test_multiple "info shared" "info shared" {
69 -re "$hex $hex Yes \[^\r\n\]*$dso\r\n" {
70 # use longer form so debug remote does not interfere
71 set count [expr $count + 1]
72 exp_continue
73 }
74 -re "$gdb_prompt " {
75 verbose -log "library: $dso, expected: $num, found: $count"
76 gdb_assert {$count == $num} "$gdb_test_name"
77 }
78 }
79 }
80
81 # The DSO part of the test. We run it once per DSO call.
82 proc test_dlmopen_one { ndso1 ndso2 exp_glob } {
83 global srcfile_lib srcfile_lib basename_lib bp_inc
84
85 # Try to reach the breakpoint in the dynamically loaded library.
86 gdb_continue_to_breakpoint "cont to bp.inc" \
87 ".*$srcfile_lib:$bp_inc\r\n.*"
88
89 # We opened all DSOs initially and close them one by one.
90 with_test_prefix "dso 1" { check_dso_count $basename_lib.1.so $ndso1 }
91 with_test_prefix "dso 2" { check_dso_count $basename_lib.2.so $ndso2 }
92
93 # This might help debugging.
94 gdb_test "info breakpoints" ".*"
95 gdb_test "print \$pc" ".*"
96
97 # We expect different instances of GDB_DLMOPEN_GLOB per DSO.
98 gdb_test "print amount" "= $exp_glob"
99 gdb_test "print gdb_dlmopen_glob" "= $exp_glob"
100
101 # Modify that DSO's instance, which should leave the others intact.
102 gdb_test "print &gdb_dlmopen_glob" "= .*"
103 gdb_test "print gdb_dlmopen_glob = -1" "= -1"
104 }
105
106 # The actual test. We run it twice.
107 proc test_dlmopen {} {
108 global srcfile basename_lib bp_main
109
110 # Note that when loading dlmopen-lib.1.so and dlmopen-lib.2.so into
111 # the same namespace, dlmopen-lib-dep.so is loaded only once, so in
112 # this case, the changes to gdb_dlmopen_glob inside test_dlmopen_one
113 # will actually be visible.
114 #
115 # Hence, we supply the expected value of this variable as argument to
116 # test_dlmopen_one.
117 with_test_prefix "dlmopen 1" { test_dlmopen_one 3 1 1 }
118 with_test_prefix "dlmopen 2" { test_dlmopen_one 2 1 1 }
119 with_test_prefix "dlmopen 3" { test_dlmopen_one 1 1 1 }
120 with_test_prefix "dlmopen 4" { test_dlmopen_one 0 1 -1 }
121
122 with_test_prefix "main" {
123 # Try to reach the breakpoint in the dynamically loaded library.
124 gdb_continue_to_breakpoint "cont to bp.main" \
125 ".*$srcfile:$bp_main\r\n.*"
126
127 # The library should not be listed.
128 with_test_prefix "dso 1" { check_dso_count $basename_lib.1.so 0 }
129 with_test_prefix "dso 2" { check_dso_count $basename_lib.2.so 0 }
130 }
131 }
132
133 # Remove the pause. We only need it for the attach test.
134 gdb_test "print wait_for_gdb = 0" "\\\$1 = 0"
135
136 # Break in the to-be-loaded library and at the end of main.
137 set bp_inc [gdb_get_line_number "bp.inc" $srcfile_lib]
138 set bp_main [gdb_get_line_number "bp.main" $srcfile]
139
140 delete_breakpoints
141 gdb_breakpoint $srcfile_lib:$bp_inc allow-pending
142 gdb_breakpoint $srcfile:$bp_main
143
144 test_dlmopen
145
146 # Try the same again when attaching after dlmopen().
147 require can_spawn_for_attach
148
149 clean_restart $binfile
150
151 # Start the test program.
152 set test_spawn_id [spawn_wait_for_attach $binfile]
153 set testpid [spawn_id_get_pid $test_spawn_id]
154
155 # Attach.
156 if { ![gdb_attach $testpid] } {
157 return
158 }
159
160 with_test_prefix "attach" {
161 # Remove the pause. We no longer need it.
162 gdb_test "print wait_for_gdb = 0" "\\\$1 = 0"
163
164 # Set the same breakpoints again. This time, however, we do not allow the
165 # breakpoint to be pending since the library has already been loaded.
166 gdb_breakpoint $srcfile_lib:$bp_inc
167 gdb_breakpoint $srcfile:$bp_main
168
169 test_dlmopen
170 }