Home | History | Annotate | Line # | Download | only in gdb.base
infcall-timeout.exp revision 1.1.1.1
      1 # Copyright 2022-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 GDB's direct-call-timeout setting, that is, ensure that if an
     17 # inferior function call, invoked from e.g. a 'print' command, takes
     18 # too long, then GDB can interrupt it, and return control to the user.
     19 
     20 standard_testfile
     21 
     22 if { [build_executable "failed to prepare" ${binfile} "${srcfile}" \
     23 	  {debug}] == -1 } {
     24     return
     25 }
     26 
     27 # Start GDB according to TARGET_ASYNC, TARGET_NON_STOP, and NON_STOP,
     28 # then adjust the direct-call-timeout, and make an inferior function
     29 # call that will never return.  GDB should eventually timeout and stop
     30 # the inferior.
     31 #
     32 # When UNWIND is "off" the inferior wil be left in the frame where the
     33 # timeout occurs, otherwise, when UNWIND is "on", GDB should unwind
     34 # back to the frame where the inferior call was made.
     35 proc run_test { target_async target_non_stop non_stop unwind } {
     36     save_vars { ::GDBFLAGS } {
     37 	append ::GDBFLAGS \
     38 	    " -ex \"maint set target-non-stop $target_non_stop\""
     39 	append ::GDBFLAGS \
     40 	    " -ex \"set non-stop $non_stop\""
     41 	append ::GDBFLAGS \
     42 	    " -ex \"maintenance set target-async ${target_async}\""
     43 
     44 	clean_restart ${::binfile}
     45     }
     46 
     47     if {![runto_main]} {
     48 	return
     49     }
     50 
     51     gdb_test_no_output "set direct-call-timeout 5"
     52     gdb_test_no_output "set unwind-on-timeout $unwind"
     53 
     54     if { $unwind } {
     55 	gdb_test "print function_that_never_returns ()" \
     56 	    [multi_line \
     57 		 "The program being debugged timed out while in a function called from GDB\\." \
     58 		 "GDB has restored the context to what it was before the call\\." \
     59 		 "To change this behavior use \"set unwind-on-timeout off\"\\." \
     60 		 "Evaluation of the expression containing the function" \
     61 		 "\\(function_that_never_returns\\) will be abandoned\\."]
     62 
     63 	gdb_test "bt" \
     64 	    "#0\\s+main \\(\\).*"
     65     } else {
     66 	# When non-stop mode is off we get slightly different output from GDB.
     67 	if { ([target_info gdb_protocol] == "remote"
     68 	      || [target_info gdb_protocol] == "extended-remote")
     69 	     && !$target_non_stop } {
     70 	    set stopped_line_pattern "Program received signal SIGINT, Interrupt\\."
     71 	} else {
     72 	    set stopped_line_pattern "Program stopped\\."
     73 	}
     74 
     75 	gdb_test "print function_that_never_returns ()" \
     76 	    [multi_line \
     77 		 $stopped_line_pattern \
     78 		 ".*" \
     79 		 "The program being debugged timed out while in a function called from GDB\\." \
     80 		 "GDB remains in the frame where the timeout occurred\\." \
     81 		 "To change this behavior use \"set unwind-on-timeout on\"\\." \
     82 		 "Evaluation of the expression containing the function" \
     83 		 "\\(function_that_never_returns\\) will be abandoned\\." \
     84 		 "When the function is done executing, GDB will silently stop\\."]
     85 
     86 	gdb_test "bt" \
     87 	    ".* function_that_never_returns .*<function called from gdb>.*"
     88     }
     89 }
     90 
     91 foreach_with_prefix target_async { "on" "off" } {
     92 
     93     if { !$target_async } {
     94 	# GDB can't timeout while waiting for a thread if the target
     95 	# runs with async-mode turned off; once the target is running
     96 	# GDB is effectively blocked until the target stops for some
     97 	# reason.
     98 	continue
     99     }
    100 
    101     foreach_with_prefix target_non_stop { "on" "off" } {
    102 	foreach_with_prefix non_stop { "on" "off" } {
    103 	    if { $non_stop && !$target_non_stop } {
    104 		# It doesn't make sense to operate GDB in non-stop
    105 		# mode when the target has (in theory) non-stop mode
    106 		# disabled.
    107 		continue
    108 	    }
    109 
    110 	    foreach_with_prefix unwind { "on" "off" } {
    111 		run_test $target_async $target_non_stop $non_stop $unwind
    112 	    }
    113 	}
    114     }
    115 }
    116