Home | History | Annotate | Line # | Download | only in gdb.base
      1 # Copyright 2021-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 doing a "run" or an "attach" while the program is running.
     17 #
     18 # We test a non-threaded and a threaded configuration, so that targets
     19 # that don't support threads get some testing, but we also test with
     20 # threads when possible in case that triggers some
     21 # multi-thread-specific bugs.
     22 
     23 standard_testfile
     24 
     25 set binfile_threads ${binfile}-threads
     26 set binfile_nothreads ${binfile}-nothreads
     27 unset binfile
     28 
     29 # Valid parameter / axis values:
     30 #
     31 #   - non-stop: "off" of "on"
     32 #   - threaded: 0 or 1
     33 #   - run-or-attach: "run" or "attach"
     34 
     35 proc_with_prefix test { non-stop threaded run-or-attach } {
     36     global gdb_prompt
     37 
     38     if { ${run-or-attach} == "attach" && ![can_spawn_for_attach] } {
     39 	unsupported "attach not supported"
     40 	return
     41     }
     42 
     43     save_vars ::GDBFLAGS {
     44 	set ::GDBFLAGS "$::GDBFLAGS -ex \"set non-stop ${non-stop}\""
     45 
     46 	# The test doesn't work when the remote target uses the
     47 	# synchronous remote protocol, because GDB can't kill the
     48 	# remote inferior while it is running, when we "run" or
     49 	# "attach" again.  When aswering "yes" to the "Start it from
     50 	# the beginning?" question, we otherwise get:
     51 	#
     52 	#   Cannot execute this command while the target is running.  Use the
     53 	#   "interrupt" command to stop the target and then try again.
     54 	#
     55 	# Interrupting the target would defeat the purpose of the
     56 	# test.  So when non-stop is off and using the remote target,
     57 	# force the target to use the async / non-stop version of the
     58 	# protocol.
     59 	if { [target_info exists gdb_protocol] && ${non-stop} == "off" } {
     60 	    set ::GDBFLAGS "$::GDBFLAGS -ex \"maint set target-non-stop on\""
     61 	}
     62 
     63 	clean_restart $::binfile
     64     }
     65 
     66     if { ![runto_main] } {
     67 	return
     68     }
     69 
     70     gdb_breakpoint "all_started" "temporary"
     71     gdb_continue_to_breakpoint "continue to all_started"
     72 
     73     # If all-stop, everything stopped when we hit the all_started
     74     # breakpoint, so resume execution in background.  If running the
     75     # non-threaded version, our only thread is stopped in any case, so
     76     # resume as well.  But if we are in non-stop with two threads, we
     77     # have one running and one stopped, leave it like this, it makes
     78     # an interesting test case.
     79     if { ${non-stop} == "off" || !${threaded} } {
     80 	gdb_test "continue &" "Continuing."
     81     }
     82 
     83     gdb_test_no_output "set confirm off"
     84 
     85     # Run again (or, connect to a new stub if using a stub), take
     86     # advantage of the fact that runto_main leaves the breakpoint on
     87     # main in place.
     88     if { ${run-or-attach} == "run" } {
     89 	gdb_run_cmd
     90 	gdb_test "" "Breakpoint $::decimal, .*main.*" "hit main breakpoint after re-run"
     91     } elseif { ${run-or-attach} == "attach" } {
     92 	set test_spawn_id [spawn_wait_for_attach $::binfile]
     93 	set test_pid [spawn_id_get_pid $test_spawn_id]
     94 
     95 	gdb_test_multiple "attach $test_pid" "attach to process" {
     96 	    -re "Attaching to program: .*$gdb_prompt " {
     97 		pass $gdb_test_name
     98 	    }
     99 	}
    100 
    101 	gdb_exit
    102 	kill_wait_spawned_process $test_spawn_id
    103     } else {
    104 	error "Invalid value for run-or-attach"
    105     }
    106 }
    107 
    108 foreach_with_prefix threaded {0 1} {
    109     set options [list debug additional_flags=-DWITH_THREADS=$threaded \
    110 		    additional_flags=-std=gnu99]
    111     if { $threaded } {
    112 	set binfile $binfile_threads
    113 	lappend options pthreads
    114     } else {
    115 	set binfile $binfile_nothreads
    116     }
    117     if { [build_executable "failed to prepare" ${binfile} ${srcfile} $options] } {
    118 	continue
    119     }
    120 
    121     foreach_with_prefix run-or-attach {run attach} {
    122 	foreach_with_prefix non-stop {off on} {
    123 	    test ${non-stop} ${threaded} ${run-or-attach}
    124 	}
    125     }
    126 }
    127