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