xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.multi/multi-re-run.exp (revision 3587d6f89c746bbb4f886219ddacd41ace480ecf)
1# Copyright 2020 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 loading two inferiors into GDB, and running one of them twice
17# in a row.  GDB used to have a bug that made it so that after an
18# inferior exit, the current program space was left pointing to the
19# wrong inferior's pspace, causing subsequent symbol lookups to
20# misbehave, including failing to load libthread_db.so.  See PR
21# gdb/25410.
22
23# Build two executables, with different symbols.
24
25set exec1 "multi-re-run-1"
26set srcfile1 multi-re-run-1.c
27set binfile1 [standard_output_file ${exec1}]
28
29set exec2 "multi-re-run-2"
30set srcfile2 multi-re-run-2.c
31set binfile2 [standard_output_file ${exec2}]
32
33with_test_prefix "exec1" {
34    if { [prepare_for_testing "failed to prepare" ${exec1} "${srcfile1}" \
35	      [list pthreads debug]] } {
36	return -1
37    }
38}
39
40with_test_prefix "exec2" {
41    if { [prepare_for_testing "failed to prepare" ${exec2} "${srcfile2}" \
42	      [list pthreads debug]] } {
43	return -1
44    }
45}
46
47# Start two inferiors, leave one stopped, and run the other a couple
48# times.  RE_RUN_INF is the inferior that is re-run.
49
50proc test_re_run {re_run_inf} {
51    global binfile1 binfile2
52    global inferior_exited_re
53    global gdb_prompt
54    global last_loaded_file
55
56    clean_restart ${binfile1}
57
58    delete_breakpoints
59
60    # Start another inferior.
61    gdb_test "add-inferior" "Added inferior 2.*" \
62	"add empty inferior 2"
63    gdb_test "inferior 2" "Switching to inferior 2.*" \
64	"switch to inferior 2"
65    gdb_load ${binfile2}
66
67    if {$re_run_inf == 1} {
68	set steady_inf 2
69	set steady_binfile $binfile2
70	set re_run_binfile $binfile1
71    } else {
72	set steady_inf 1
73	set steady_binfile $binfile1
74	set re_run_binfile $binfile2
75    }
76
77    gdb_test "inferior $steady_inf" "Switching to inferior $steady_inf.*" \
78	"switch to steady inferior"
79    set last_loaded_file $steady_binfile
80
81    # Run the steady inferior to a breakpoint, and let it stay stopped
82    # there.
83    if ![runto all_started message] then {
84	untested "setup failed"
85	return 0
86    }
87
88    gdb_test "inferior $re_run_inf" "Switching to inferior $re_run_inf.*" \
89	"switch to re-run inferior"
90    set last_loaded_file $re_run_binfile
91
92    # Now run the RE_RUN_INF inferior a couple times.  GDB used to
93    # have a bug that caused the second run to fail to load
94    # libthread_db.so.
95    foreach_with_prefix iter {1 2} {
96	delete_breakpoints
97
98	if ![runto all_started message] {
99	    return 0
100	}
101
102	# If a thread_stratum target fails to load, then TLS debugging
103	# fails too.
104	gdb_test "print tls_var" " = 1"
105
106	gdb_continue_to_end "" continue 1
107
108	# In the original bug, after an inferior exit, GDB would leave
109	# the current program space pointing to the wrong inferior's
110	# pspace, and thus the wrong symbols were visible.
111	if {$re_run_inf == 1} {
112	    gdb_test "print re_run_var_1" " = 1"
113	} else {
114	    gdb_test "print re_run_var_2" " = 2"
115	}
116    }
117}
118
119# For completeness, test re-running either inferior 1 or inferior 2.
120foreach_with_prefix re_run_inf {1 2} {
121    test_re_run $re_run_inf
122}
123