binutils-gdb/gdb/testsuite/gdb.base/foll-exec.exp
Joel Brobecker 61baf725ec update copyright year range in GDB files
This applies the second part of GDB's End of Year Procedure, which
updates the copyright year range in all of GDB's files.

gdb/ChangeLog:

        Update copyright year range in all GDB files.
2017-01-01 10:52:34 +04:00

383 lines
14 KiB
Plaintext

# Copyright 1997-2017 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 ability to follow a process through a
# Unix exec() system call.
# Until "catch exec" is implemented on other targets...
#
if { ![istarget "*-linux*"] } then {
continue
}
standard_testfile foll-exec.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 "failed to compile"
return -1
}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $compile_options] != "" } {
untested "failed to compile"
return -1
}
proc do_exec_tests {} {
global binfile srcfile srcfile2 testfile testfile2
global gdb_prompt
# 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
}
clean_restart $binfile
# Start the program running, and stop at main.
#
if ![runto_main] then {
fail "couldn't run ${testfile}"
return
}
# Execute the code setting up variable PROG.
set tbreak_line [gdb_get_line_number " tbreak-execlp " $srcfile]
gdb_test "tbreak ${tbreak_line}"
gdb_continue_to_breakpoint "line tbreak-execlp" ".*execlp \\(.*"
# Verify that we can see various global and local variables
# in this program, and that they have expected values. Some
# of these variables are also declared in the program we'll
# exec in a moment.
#
send_gdb "print global_i\n"
gdb_expect {
-re ".* = 100.*$gdb_prompt $"\
{pass "print follow-exec/global_i"}
-re "$gdb_prompt $" {fail "print follow-exec/global_i"}
timeout {fail "(timeout) print follow-exec/global_i"}
}
send_gdb "print local_j\n"
gdb_expect {
-re ".* = 101.*$gdb_prompt $"\
{pass "print follow-exec/local_j"}
-re "$gdb_prompt $" {fail "print follow-exec/local_j"}
timeout {fail "(timeout) print follow-exec/local_j"}
}
send_gdb "print local_k\n"
gdb_expect {
-re ".* = 102.*$gdb_prompt $"\
{pass "print follow-exec/local_k"}
-re "$gdb_prompt $" {fail "print follow-exec/local_k"}
timeout {fail "(timeout) print follow-exec/local_k"}
}
# Try stepping through an execlp call, without catching it.
# We should stop in execd-program, at its first statement.
#
set execd_line [gdb_get_line_number "after-exec" $srcfile2]
send_gdb "next\n"
gdb_expect {
-re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
{pass "step through execlp call"}
-re "$gdb_prompt $" {fail "step through execlp call"}
timeout {fail "(timeout) step through execlp call"}
}
# Verify that we can see the variables defined in the newly-exec'd
# program, and CANNOT see those defined in the exec'ing program.
#
send_gdb "next\n"
gdb_expect {
-re "printf \\(.Hello .*$gdb_prompt $"\
{pass "step after execlp call"}
-re "$gdb_prompt $" {fail "step after execlp call"}
timeout {fail "(timeout) step after execlp call"}
}
send_gdb "print global_i\n"
gdb_expect {
-re ".* = 0.*$gdb_prompt $"\
{pass "print execd-program/global_i (after execlp)"}
-re "$gdb_prompt $" {fail "print execd-program/global_i (after execlp)"}
timeout {fail "(timeout) print execd-program/global_i (after execlp)"}
}
send_gdb "print local_j\n"
gdb_expect {
-re ".* = 2.*$gdb_prompt $"\
{pass "print execd-program/local_j (after execlp)"}
-re "$gdb_prompt $" {fail "print execd-program/local_j (after execlp)"}
timeout {fail "(timeout) print execd-program/local_j (after execlp)"}
}
send_gdb "print local_k\n"
gdb_expect {
-re "No symbol \"local_k\" in current context.*$gdb_prompt $"\
{pass "print follow-exec/local_k (after execlp)"}
-re "$gdb_prompt $" {fail "print follow-exec/local_k (after execlp)"}
timeout {fail "(timeout) print follow-exec/local_k (after execlp)"}
}
# Explicitly kill this program, or a subsequent rerun actually runs
# the exec'd program, not the original program...
clean_restart $binfile
# Start the program running, and stop at main.
#
if ![runto_main] then {
fail "couldn't run ${testfile} (2nd try)"
return
}
# Verify that we can catch an exec event, and then continue
# to follow through the exec. (Since there's a breakpoint on
# "main", it'll also be transferred to the exec'd program,
# and we expect to stop there.)
#
send_gdb "catch exec\n"
gdb_expect {
-re "Catchpoint .*(exec).*$gdb_prompt $"\
{pass "set catch exec"}
-re "$gdb_prompt $" {fail "set catch exec"}
timeout {fail "(timeout) set catch exec"}
}
# Verify that the catchpoint is mentioned in an "info breakpoints",
# and further that the catchpoint mentions no program name.
#
set msg "info shows catchpoint without exec pathname"
gdb_test_multiple "info breakpoints" $msg {
-re ".*catchpoint.*keep y.*exec\[\n\r\]+$gdb_prompt $" {
pass $msg
}
}
send_gdb "continue\n"
gdb_expect {
-re ".*xecuting new program:.*${testfile2}.*Catchpoint .*(exec\'d .*${testfile2}).*$gdb_prompt $"\
{pass "hit catch exec"}
-re "$gdb_prompt $" {fail "hit catch exec"}
timeout {fail "(timeout) hit catch exec"}
}
# DTS CLLbs16760
# test gets out of sync if previous test fails.
gdb_test "bt" ".*" "sync up after possible failure 1"
gdb_test "bt" "#0.*" "sync up after possible failure 2"
# Verify that the catchpoint is mentioned in an "info breakpoints",
# and further that the catchpoint managed to capture the exec'd
# program's name.
#
set msg "info shows catchpoint exec pathname"
gdb_test_multiple "info breakpoints" $msg {
-re ".*catchpoint.*keep y.*exec, program \".*${testfile2}\".*$gdb_prompt $" {
pass $msg
}
}
# Verify that we can continue from the catchpoint, and land in the
# main of the newly-exec'd program.
#
send_gdb "continue\n"
gdb_expect {
-re ".*${srcfile2}:${execd_line}.*$gdb_prompt $"\
{pass "continue after hit catch exec"}
-re "$gdb_prompt $" {fail "continue after hit catch exec"}
timeout {fail "(timeout) continue after hit catch exec"}
}
# Explicitly kill this program, or a subsequent rerun actually runs
# the exec'd program, not the original program...
clean_restart $binfile
# Start the program running, and stop at main.
#
if ![runto_main] then {
fail "couldn't run ${testfile} (3rd try)"
return
}
# Execute the code setting up variable PROG.
set tbreak_line [gdb_get_line_number " tbreak-execlp " $srcfile]
gdb_test "tbreak ${tbreak_line}"
gdb_continue_to_breakpoint "line tbreak-execlp" ".*execlp \\(.*"
# Verify that we can follow through follow an execl()
# call. (We must jump around earlier exec* calls.)
#
set tbreak_line [gdb_get_line_number " tbreak-execl " $srcfile]
send_gdb "tbreak ${tbreak_line}\n"
gdb_expect {
-re "Temporary breakpoint .*file .*${srcfile}, line ${tbreak_line}.*$gdb_prompt $"\
{pass "prepare to jump to execl call"}
-re "$gdb_prompt $" {fail "prepare to jump to execl call"}
timeout {fail "(timeout) prepare to jump to execl call"}
}
send_gdb "jump ${tbreak_line}\n"
gdb_expect {
-re "main.* at .*${srcfile}:${tbreak_line}.*$gdb_prompt $"\
{pass "jump to execl call"}
-re "$gdb_prompt $" {fail "jump to execl call"}
timeout {fail "(timeout) jump to execl call"}
}
# Note that stepping through an exec call causes the step-count
# to be reset to zero. I.e.: you may specify "next 2" at the
# call, but you'll actually stop at the first breakpoint set in
# the newly-exec'd program, not after the remaining step-count
# reaches zero.
#
send_gdb "next 2\n"
gdb_expect {
-re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
{pass "step through execl call"}
-re "$gdb_prompt $" {fail "step through execl call"}
timeout {fail "(timeout) step through execl call"}
}
send_gdb "next\n"
gdb_expect {
-re "printf \\(.Hello .*$gdb_prompt $"\
{pass "step after execl call"}
-re "$gdb_prompt $" {fail "step after execl call"}
timeout {fail "(timeout) step after execl call"}
}
# Verify that we can print a local variable (which happens to be
# assigned the value of main's argc).
#
send_gdb "print local_j\n"
gdb_expect {
-re ".* = 3.*$gdb_prompt $"\
{pass "print execd-program/local_j (after execl)"}
-re "$gdb_prompt $" {fail "print execd-program/local_j (after execl)"}
timeout {fail "(timeout) print execd-program/local_j (after execl)"}
}
# Explicitly kill this program, or a subsequent rerun actually runs
# the exec'd program, not the original program...
clean_restart $binfile
# Start the program running, and stop at main.
#
if ![runto_main] then {
fail "couldn't run ${testfile} (4th try)"
return
}
# Execute the code setting up variable PROG.
set tbreak_line [gdb_get_line_number " tbreak-execlp " $srcfile]
gdb_test "tbreak ${tbreak_line}"
gdb_continue_to_breakpoint "line tbreak-execlp" ".*execlp \\(.*"
# Verify that we can follow through follow an execv()
# call. (We must jump around earlier exec* calls.)
#
set tbreak_line [gdb_get_line_number "tbreak-execv"]
send_gdb "tbreak ${tbreak_line}\n"
gdb_expect {
-re "Temporary breakpoint .*file .*${srcfile}, line ${tbreak_line}.*$gdb_prompt $"\
{pass "prepare to jump to execv call"}
-re "$gdb_prompt $" {fail "prepare to jump to execv call"}
timeout {fail "(timeout) prepare to jump to execv call"}
}
send_gdb "jump ${tbreak_line}\n"
gdb_expect {
-re "main.* at .*${srcfile}:${tbreak_line}.*$gdb_prompt $"\
{pass "jump to execv call"}
-re "$gdb_prompt $" {fail "jump to execv call"}
timeout {fail "(timeout) jump to execv call"}
}
send_gdb "next\n"
gdb_expect {
-re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
{pass "step through execv call"}
-re "$gdb_prompt $" {fail "step through execv call"}
timeout {fail "(timeout) step through execv call"}
}
send_gdb "next\n"
gdb_expect {
-re "printf \\(.Hello .*$gdb_prompt $"\
{pass "step after execv call"}
-re "$gdb_prompt $" {fail "step after execv call"}
timeout {fail "(timeout) step after execv call"}
}
# Verify that we can print a local variable (which happens to be
# assigned the value of main's argc).
#
send_gdb "print local_j\n"
gdb_expect {
-re ".* = 2.*$gdb_prompt $"\
{pass "print execd-program/local_j (after execv)"}
-re "$gdb_prompt $" {fail "print execd-program/local_j (after execv)"}
timeout {fail "(timeout) print execd-program/local_j (after execv)"}
}
# Explicitly kill this program, or a subsequent rerun actually runs
# the exec'd program, not the original program...
clean_restart $binfile
# Start the program running, and stop at main.
#
if ![runto_main] then {
fail "couldn't run ${testfile} (5th try)"
return
}
# Verify that we can just continue and thereby follow through an
# exec call. (Since the breakpoint on "main" is reset, we should
# just stop in main of the newly-exec'd program.)
#
send_gdb "continue\n"
gdb_expect {
-re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int local_j = argc;.*$gdb_prompt $"\
{pass "continue through exec"}
-re "$gdb_prompt $" {fail "continue through exec"}
timeout {fail "(timeout) continue through exec"}
}
}
# Start with a fresh gdb
gdb_exit
clean_restart $binfile
do_exec_tests
return 0