31d913c7e4
BASEDIR was added by https://sourceware.org/ml/gdb-patches/2013-10/msg00587.html in order to handle the different directory layout in serial testing and parallel testing. BASEDIR is "gdb.base" in serial testing and is "outputs/gdb.base/TESTNAME" in parallel testing. However, it doesn't work if the GDBserver is in remote target, like this, $ make check RUNTESTFLAGS='--target_board=remote-gdbserver-on-localhost foll-vfork.exp foll-exec.exp' FAIL: gdb.base/foll-exec.exp: continue to first exec catchpoint (the program exited) FAIL: gdb.base/foll-vfork.exp: exec: vfork and exec child follow, to main bp: continue to bp (the program exited) FAIL: gdb.base/foll-vfork.exp: exec: vfork child follow, finish after tcatch vfork: finish (the program exited) FAIL: gdb.base/foll-vfork.exp: exec: vfork relations in info inferiors: continue to bp (the program exited) these tests fail because the executable can't be found. With target board native-gdbserver, the program is spawned this way, spawn ../gdbserver/gdbserver --once :2347 /scratch/yao/gdb/build-git/x86_64/gdb/testsuite/gdb.base/foll-vfork so BASEDIR is correct. However, with target board remote-gdbserver-on-localhost, the program is spawned spawn /usr/bin/ssh -l yao localhost /scratch/yao/gdb/build-git/x86_64/gdb/testsuite/../gdbserver/gdbserver --once :2346 /scratch/yao/gdb/build-git/x86_64/gdb/testsuite/gdb.base/foll-vfork so BASEDIR (either "gdb.base" or "outputs/gdb.base/TESTNAME") makes no sense. I had a fix that pass absolute directory to BASEDIR, but it assumes that directory structure is the same on build and target, and it doesn't work in remote host case. The current fix in this patch is to get the directory from argv[0]. In any case, the program to be exec'ed is at the same directory with the main program. Note that these tests do "next N" to let program stop at the desired line, but it is fragile, because GDB for different targets may skip function prologue slightly differently, so I replace some of them by "tbreak on LINE NUMBER and continue". gdb/testsuite: 2016-02-04 Yao Qi <yao.qi@linaro.org> * gdb.base/foll-exec-mode.c: Include limits.h. (main): Add parameters argc and argv. Get directory from argv[0]. * gdb.base/foll-exec-mode.exp: Don't pass -DBASEDIR in compilation. * gdb.base/foll-exec.c: Include limits.h. (main): Add parameters argc and argv. Get directory from argv[0]. * gdb.base/foll-exec.exp: Don't pass -DBASEDIR in compilation. Adjust tests on the number of lines as source code changed. * gdb.base/foll-vfork-exit.c: Include limits.h. (main): Add one line of statement before vfork. * gdb.base/foll-vfork.c: Include limits.h and string.h. (main): Add parameters argc and argv. Get directory from argv[0]. * gdb.base/foll-vfork.exp: Don't pass -DBASEDIR in compilation. (setup_gdb): Set tbreak to skip some source lines. * gdb.multi/bkpt-multi-exec.c: Include limits.h. (main): Add parameters argc and argv. Get directory from argv[0]. * gdb.multi/bkpt-multi-exec.exp: Don't pass -DBASEDIR in compilation. * gdb.multi/multi-arch-exec.c: Include limits.h and string.h. (main): Add parameters argc and argv. Get directory from argv[0]. * gdb.multi/multi-arch-exec.exp: Don't pass -DBASEDIR in compilation.
202 lines
5.8 KiB
Text
202 lines
5.8 KiB
Text
# Copyright 1997-2016 Free Software Foundation, Inc.
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# This is a test of gdb's follow-exec-mode.
|
|
#
|
|
# It first checks that exec events are supported by using a catchpoint,
|
|
# then tests multiple scenarios for follow-exec-mode using parameters
|
|
# that test:
|
|
# - each mode
|
|
# - different commands to execute past the exec
|
|
# - re-running both the original and new inferiors.
|
|
#
|
|
# Note that we can't single-step past an exec call. There has to
|
|
# be a breakpoint in order to stop after the exec, even if we use
|
|
# a single-step command to execute past the exec.
|
|
|
|
# Remote mode doesn't support the 'run' command, which is
|
|
# required for follow-exec-mode testing.
|
|
if { [target_info exists gdb_protocol]
|
|
&& [target_info gdb_protocol] == "remote" } {
|
|
continue
|
|
}
|
|
|
|
# Until "catch exec" is implemented on other targets...
|
|
#
|
|
if {![istarget "*-linux*"]} then {
|
|
continue
|
|
}
|
|
|
|
standard_testfile foll-exec-mode.c
|
|
|
|
set testfile2 "execd-prog"
|
|
set srcfile2 ${testfile2}.c
|
|
set binfile2 [standard_output_file ${testfile2}]
|
|
|
|
set compile_options debug
|
|
|
|
# build the first test case
|
|
if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable $compile_options] != "" } {
|
|
untested foll-exec-mode.exp
|
|
return -1
|
|
}
|
|
|
|
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $compile_options] != "" } {
|
|
untested foll-exec-mode.exp
|
|
return -1
|
|
}
|
|
|
|
# Test exec catchpoints to ensure exec events are supported.
|
|
#
|
|
proc do_catch_exec_test { } {
|
|
global testfile
|
|
global gdb_prompt
|
|
|
|
clean_restart $testfile
|
|
|
|
# Start the program running, and stop at main.
|
|
#
|
|
if ![runto_main] then {
|
|
fail "Couldn't run ${testfile}"
|
|
return
|
|
}
|
|
|
|
# Verify that the system supports "catch exec".
|
|
gdb_test "catch exec" "Catchpoint \[0-9\]* \\(exec\\)" "insert first exec catchpoint"
|
|
set has_exec_catchpoints 0
|
|
gdb_test_multiple "continue" "continue to first exec catchpoint" {
|
|
-re ".*Your system does not support this type\r\nof catchpoint.*$gdb_prompt $" {
|
|
unsupported "continue to first exec catchpoint"
|
|
}
|
|
-re ".*Catchpoint.*$gdb_prompt $" {
|
|
set has_exec_catchpoints 1
|
|
pass "continue to first exec catchpoint"
|
|
}
|
|
}
|
|
|
|
if {$has_exec_catchpoints == 0} {
|
|
unsupported "exec catchpoints"
|
|
return
|
|
}
|
|
}
|
|
|
|
# Test follow-exec-mode in the specified scenario.
|
|
# MODE determines whether follow-exec-mode is "same" or "new".
|
|
# CMD determines the command used to execute past the exec call.
|
|
# INFSWITCH is ignored for MODE == "same", and for "new" it is
|
|
# used to determine whether to switch to the original inferior
|
|
# before re-running.
|
|
|
|
proc do_follow_exec_mode_tests { mode cmd infswitch } {
|
|
global binfile srcfile srcfile2 testfile testfile2
|
|
global gdb_prompt
|
|
|
|
with_test_prefix "$mode,$cmd,$infswitch" {
|
|
clean_restart $testfile
|
|
|
|
# Start the program running, and stop at main.
|
|
#
|
|
if ![runto_main] then {
|
|
fail "Couldn't run ${testfile}"
|
|
return
|
|
}
|
|
|
|
# Set the follow-exec mode.
|
|
#
|
|
gdb_test_no_output "set follow-exec-mode $mode"
|
|
|
|
# Run to the line of the exec call.
|
|
#
|
|
gdb_breakpoint [gdb_get_line_number "Set breakpoint here"]
|
|
gdb_continue_to_breakpoint "continue to line of exec call"
|
|
|
|
# Set up the output we expect to see after we execute past the exec.
|
|
#
|
|
set execd_line [gdb_get_line_number "after-exec" $srcfile2]
|
|
set expected_re ".*xecuting new program: .*${testfile2}.*Breakpoint .,.*${srcfile2}:${execd_line}.*$gdb_prompt $"
|
|
|
|
# Set a breakpoint after the exec call if we aren't single-stepping
|
|
# past it.
|
|
#
|
|
if {$cmd == "continue"} {
|
|
gdb_breakpoint "$execd_line"
|
|
}
|
|
|
|
# Execute past the exec call.
|
|
#
|
|
set test "$cmd past exec"
|
|
gdb_test_multiple $cmd $test {
|
|
-re "$expected_re" {
|
|
pass $test
|
|
}
|
|
}
|
|
|
|
# Set expected output, given the test parameters.
|
|
#
|
|
if {$mode == "same"} {
|
|
set expected_re "\\* 1.*process.*"
|
|
} else {
|
|
set expected_re " 1.*null.*$testfile.*\r\n\\* 2.*process.*$testfile2 .*"
|
|
}
|
|
|
|
# Check that the inferior list is correct:
|
|
# - one inferior for MODE == "same"
|
|
# - two inferiors for MODE == "new", current is execd program
|
|
#
|
|
gdb_test "info inferiors" $expected_re "Check inferior list"
|
|
|
|
set expected_inf ""
|
|
if {$mode == "same"} {
|
|
# One inferior, the execd program.
|
|
set expected_inf $testfile2
|
|
} elseif {$infswitch == "infswitch"} {
|
|
# Two inferiors, we have switched to the original program.
|
|
set expected_inf $testfile
|
|
gdb_test "inferior 1" "Switching to inferior 1.*$testfile.*" "Switch inferiors"
|
|
} else {
|
|
# Two inferiors, run the execd program
|
|
set expected_inf $testfile2
|
|
}
|
|
|
|
# Now check that a 'run' command will run the correct inferior.
|
|
#
|
|
set test "use correct executable ($expected_inf) for run after follow exec"
|
|
gdb_run_cmd
|
|
gdb_test_multiple "" $test {
|
|
-re {Start it from the beginning\? \(y or n\) $} {
|
|
send_gdb "y\n"
|
|
exp_continue
|
|
}
|
|
-re "Starting program: .*$expected_inf.*Breakpoint .,.*\r\n$gdb_prompt $" {
|
|
pass $test
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
do_catch_exec_test
|
|
|
|
foreach cmd {"next" "continue"} {
|
|
foreach mode {"same" "new"} {
|
|
# Test basic follow-exec-mode.
|
|
do_follow_exec_mode_tests $mode $cmd "no_infswitch"
|
|
if {$mode == "new"} {
|
|
# Test that when we do 'run' we get the correct executable.
|
|
do_follow_exec_mode_tests $mode $cmd "infswitch"
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0
|