1 # Copyright 2020-2024 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 stepping over an exec syscall instruction in a multi-threaded program. 17 18 standard_testfile .c -execd.c 19 20 set syscalls_src $srcdir/lib/my-syscalls.S 21 22 # EXECR_THREAD is "leader" or "other", and decides which thread does the exec. 23 # 24 # If DIFFERENT_TEXT_SEGMENTS is true, the exec'er and exec'd program are 25 # compiled with different, explicit text segment addresses. This makes it so 26 # the address of the displaced stepping buffer in the old executable is likely 27 # not accessible in the new executable. This might catch cases where GDB tries 28 # (wrongfully) to restore the bytes saved from the old executable in the new 29 # executable. 30 # 31 # DISPLACED_STEPPING is "auto" or "off" and controls the value of "set 32 # displaced-stepping". 33 34 proc do_test { execr_thread different_text_segments displaced_stepping } { 35 global srcdir subdir srcfile srcfile2 binfile 36 global syscalls_src 37 global decimal hex 38 39 set execr_srcs [list $srcdir/$subdir/$srcfile $syscalls_src] 40 set execd_srcs [list $srcdir/$subdir/$srcfile2] 41 42 # Generate unique filenames for each case. 43 set execr_binfile $binfile-execr-thread-$execr_thread-diff-text-segs-$different_text_segments 44 set execd_binfile $execr_binfile-execd 45 46 set execr_opts [list debug] 47 set execd_opts [list debug] 48 49 lappend_include_file execr_opts $::srcdir/lib/my-syscalls.h 50 51 if { $different_text_segments } { 52 lappend execr_opts "text_segment=0x600000" 53 lappend execd_opts "text_segment=0x800000" 54 } 55 56 if { $execr_thread == "leader" } { 57 lappend execr_opts "additional_flags=-DLEADER_DOES_EXEC" 58 } elseif { $execr_thread == "other" } { 59 lappend execr_opts "additional_flags=-DOTHER_DOES_EXEC" 60 } else { 61 error "Invalid execr_thread value: $execr_thread." 62 } 63 64 # Compile execr binary (the one that does the exec). 65 if {[gdb_compile_pthreads $execr_srcs $execr_binfile executable $execr_opts] != "" } { 66 return -1 67 } 68 69 # Compile the second binary (the one that gets exec'd). 70 if {[gdb_compile $execd_srcs $execd_binfile executable $execd_opts] != "" } { 71 return -1 72 } 73 74 clean_restart ${execr_binfile} 75 76 gdb_test_no_output "set displaced-stepping $displaced_stepping" 77 78 if ![runto_main] { 79 return 80 } 81 82 # Leave breakpoint main inserted, we expect to hit it after exec. 83 84 # This breakpoint will be stepped by whatever thread does the exec. 85 gdb_test "break my_execve_syscall if 0" "Breakpoint $decimal at $hex.*" 86 87 # Continue across exec to main. 88 if { [target_is_gdbserver] } { 89 setup_kfail gdb/27020 "*-*-*" 90 } 91 set failed [gdb_test "continue" \ 92 "process $decimal is executing new program: .* hit Breakpoint $decimal, main .*" \ 93 "continue across exec"] 94 if { $failed } { 95 return 96 } 97 98 # Just to confirm we are indeed in the execd program. 99 gdb_test "print a_variable_in_execd" " = 1212" 100 101 # Continue execution to make sure we can step over the breakpoint on main. 102 # It would be nice to use gdb_continue_to_end to ensure the program can 103 # exit properly, but it hangs due to PR gdb/26995. 104 gdb_breakpoint foo 105 gdb_test "continue" "Breakpoint $decimal, foo .*" \ 106 "continue to foo" 107 } 108 109 foreach_with_prefix displaced_stepping {auto off} { 110 foreach_with_prefix different_text_segments {true false} { 111 foreach_with_prefix execr_thread {leader other} { 112 do_test $execr_thread $different_text_segments $displaced_stepping 113 } 114 } 115 } 116