]>
Commit | Line | Data |
---|---|---|
8d56636a MM |
1 | # This testcase is part of GDB, the GNU debugger. |
2 | # | |
213516ef | 3 | # Copyright 2021-2023 Free Software Foundation, Inc. |
8d56636a MM |
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] | |
aebb370b MM |
35 | set srcfile_lib_dep $srcdir/$subdir/$basename_lib-dep.c |
36 | set binfile_lib_dep [standard_output_file $basename_lib-dep.so] | |
8d56636a | 37 | |
aebb370b | 38 | if { [gdb_compile_shlib $srcfile_lib_dep $binfile_lib_dep {debug}] != "" } { |
8d56636a MM |
39 | untested "failed to prepare shlib" |
40 | return -1 | |
41 | } | |
42 | ||
aebb370b MM |
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]] != "" } { | |
8d56636a MM |
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\" \ | |
aebb370b | 58 | shlib_load debug]] } { |
8d56636a MM |
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. | |
aebb370b | 85 | proc test_dlmopen_one { ndso1 ndso2 exp_glob } { |
8d56636a MM |
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" ".*" | |
aebb370b MM |
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" | |
8d56636a MM |
107 | } |
108 | ||
109 | # The actual test. We run it twice. | |
110 | proc test_dlmopen {} { | |
111 | global srcfile basename_lib bp_main | |
112 | ||
aebb370b MM |
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 } | |
8d56636a MM |
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. | |
36354a49 LS |
162 | if { ![gdb_attach $testpid] } { |
163 | return | |
164 | } | |
8d56636a MM |
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 | } |