import gdb-1999-06-28 snapshot
This commit is contained in:
parent
9cd2c67bac
commit
74cf13956f
20
gdb/testsuite/gdb.base/attach.c
Normal file
20
gdb/testsuite/gdb.base/attach.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* This program is intended to be started outside of gdb, and then
|
||||
attached to by gdb. Thus, it simply spins in a loop. The loop
|
||||
is exited when & if the variable 'should_exit' is non-zero. (It
|
||||
is initialized to zero in this program, so the loop will never
|
||||
exit unless/until gdb sets the variable to non-zero.)
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
int should_exit = 0;
|
||||
|
||||
int main ()
|
||||
{
|
||||
int local_i = 0;
|
||||
|
||||
while (! should_exit)
|
||||
{
|
||||
local_i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
437
gdb/testsuite/gdb.base/attach.exp
Normal file
437
gdb/testsuite/gdb.base/attach.exp
Normal file
@ -0,0 +1,437 @@
|
||||
# Copyright (C) 1997 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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
# Please email any bugs, comments, and/or additions to this file to:
|
||||
# bug-gdb@prep.ai.mit.edu
|
||||
|
||||
# On HP-UX 11.0, this test is causing a process running
|
||||
# the program "attach" to be left around spinning.
|
||||
# Until we figure out why, I am commenting out the test
|
||||
# to avoid polluting tiamat (our 11.0 nightly test machine)
|
||||
# with these processes. RT
|
||||
#
|
||||
# Setting the magic bit in the target app should work.
|
||||
# I added a "kill", and also a test for the R3 register
|
||||
# warning. JB
|
||||
#
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
set prms_id 0
|
||||
set bug_id 0
|
||||
|
||||
|
||||
if { ![istarget "hppa*-*-hpux*"] } {
|
||||
#setup_xfail "*-*-*"
|
||||
return 0
|
||||
}
|
||||
|
||||
set testfile "attach"
|
||||
set srcfile ${testfile}.c
|
||||
set srcfile2 ${testfile}2.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
set binfile2 ${objdir}/${subdir}/${testfile}2
|
||||
set cleanupfile ${objdir}/${subdir}/${testfile}.awk
|
||||
|
||||
#execute_anywhere "rm -f ${binfile} ${binfile2}"
|
||||
remote_exec build "rm -f ${binfile} ${binfile2}"
|
||||
# For debugging this test
|
||||
#
|
||||
#log_user 1
|
||||
|
||||
# Clean out any old files from past runs.
|
||||
#
|
||||
remote_exec build "${cleanupfile}"
|
||||
|
||||
# build the first test case
|
||||
#
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
||||
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
|
||||
# Because we can't attach over nfs, copy binfile to /tmp/${binfile}.${pid}
|
||||
# and replace binfile with a symbolic link
|
||||
|
||||
set pid [pid]
|
||||
exec /bin/cp -f ${binfile} /tmp/attach1.${pid}
|
||||
exec rm -f ${binfile}
|
||||
set binfile /tmp/attach1.${pid}
|
||||
# exec ln -s /tmp/attach1.${pid} ${binfile}
|
||||
|
||||
# Build the in-system-call test
|
||||
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug}] != "" } {
|
||||
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
|
||||
# Because we can't attach over nfs, copy binfile2 to /tmp/${binfile2}.${pid}
|
||||
# and replace binfile2 with a symbolic link
|
||||
|
||||
set pid [pid]
|
||||
exec cp -f ${binfile2} /tmp/attach2.${pid}
|
||||
exec rm -f ${binfile2}
|
||||
set binfile2 /tmp/attach2.${pid}
|
||||
# exec ln -s /tmp/attach2.${pid} ${binfile2}
|
||||
|
||||
|
||||
if [get_compiler_info ${binfile}] {
|
||||
return -1
|
||||
}
|
||||
|
||||
proc do_attach_tests {} {
|
||||
global gdb_prompt
|
||||
global binfile
|
||||
global srcfile
|
||||
global testfile
|
||||
global objdir
|
||||
global subdir
|
||||
global timeout
|
||||
|
||||
# Start the program running and then wait for a bit, to be sure
|
||||
# that it can be attached to.
|
||||
#
|
||||
set testpid [eval exec $binfile &]
|
||||
exec sleep 2
|
||||
|
||||
# Verify that we cannot attach to nonsense.
|
||||
#
|
||||
send_gdb "attach abc\n"
|
||||
gdb_expect {
|
||||
-re ".*Illegal process-id: abc.*$gdb_prompt $"\
|
||||
{pass "attach to nonsense is prohibited"}
|
||||
-re "Attaching to.*$gdb_prompt $"\
|
||||
{fail "attach to nonsense is prohibited (bogus pid allowed)"}
|
||||
-re "$gdb_prompt $" {fail "attach to nonsense is prohibited"}
|
||||
timeout {fail "(timeout) attach to nonsense is prohibited"}
|
||||
}
|
||||
|
||||
# Verify that we cannot attach to what appears to be a valid
|
||||
# process ID, but is a process that doesn't exist. (I don't
|
||||
# believe any process is ever assigned #0, at least on HPUX.)
|
||||
#
|
||||
send_gdb "attach 0\n"
|
||||
gdb_expect {
|
||||
# This reponse is expected on HP-UX 10.20 (i.e., ptrace-based).
|
||||
-re "Attaching to.*, process 0.*No such process.*$gdb_prompt $"\
|
||||
{pass "attach to nonexistent process is prohibited"}
|
||||
# This response is expected on HP-UX 10.30 & 11.0 (i.e., ttrace-based).
|
||||
-re "Attaching to.*, process 0 failed.*Hint.*$gdb_prompt $"\
|
||||
{pass "attach to nonexistent process is prohibited"}
|
||||
-re "$gdb_prompt $" {fail "attach to nonexistent process is prohibited"}
|
||||
timeout {fail "(timeout) attach to nonexistent process is prohibited"}
|
||||
}
|
||||
|
||||
# Verify that we can attach to the process by first giving its
|
||||
# executable name via the file command, and using attach with
|
||||
# the process ID.
|
||||
#
|
||||
# (Actually, the test system appears to do this automatically
|
||||
# for us. So, we must also be prepared to be asked if we want
|
||||
# to discard an existing set of symbols.)
|
||||
#
|
||||
send_gdb "file $binfile\n"
|
||||
gdb_expect {
|
||||
-re "Load new symbol table from.*y or n.*$" {
|
||||
send_gdb "y\n"
|
||||
gdb_expect {
|
||||
-re "Reading symbols from $binfile\.\.\.*done.*$gdb_prompt $"\
|
||||
{pass "(re)set file, before attach1"}
|
||||
-re "$gdb_prompt $" {fail "(re)set file, before attach1"}
|
||||
timeout {fail "(timeout) (re)set file, before attach1"}
|
||||
}
|
||||
}
|
||||
-re "Reading symbols from $binfile\.\.\.*done.*$gdb_prompt $"\
|
||||
{pass "set file, before attach1"}
|
||||
-re "$gdb_prompt $" {fail "set file, before attach1"}
|
||||
timeout {fail "(timeout) set file, before attach1"}
|
||||
}
|
||||
|
||||
send_gdb "attach $testpid\n"
|
||||
gdb_expect {
|
||||
-re "Attaching to program.*$binfile, process $testpid.*main.*at .*$srcfile:.*$gdb_prompt $"\
|
||||
{pass "attach1, after setting file"}
|
||||
-re "$gdb_prompt $" {fail "attach1, after setting file"}
|
||||
timeout {fail "(timeout) attach1, after setting file"}
|
||||
}
|
||||
|
||||
# Verify that we can "see" the variable "should_exit" in the
|
||||
# program, and that it is zero.
|
||||
#
|
||||
send_gdb "print should_exit\n"
|
||||
gdb_expect {
|
||||
-re ".* = 0.*$gdb_prompt $"\
|
||||
{pass "after attach1, print should_exit"}
|
||||
-re "$gdb_prompt $" {fail "after attach1, print should_exit"}
|
||||
timeout {fail "(timeout) after attach1, print should_exit"}
|
||||
}
|
||||
|
||||
# Detach the process.
|
||||
#
|
||||
send_gdb "detach\n"
|
||||
gdb_expect {
|
||||
-re "Detaching from program: .*$binfile.*$gdb_prompt $"\
|
||||
{pass "attach1 detach"}
|
||||
-re "$gdb_prompt $" {fail "attach1 detach"}
|
||||
timeout {fail "(timeout) attach1 detach"}
|
||||
}
|
||||
|
||||
# Wait a bit for gdb to finish detaching
|
||||
#
|
||||
exec sleep 5
|
||||
|
||||
# Purge the symbols from gdb's brain. (We want to be certain
|
||||
# the next attach, which won't be preceded by a "file" command,
|
||||
# is really getting the executable file without our help.)
|
||||
#
|
||||
set old_timeout $timeout
|
||||
set timeout 15
|
||||
send_gdb "file\n"
|
||||
gdb_expect {
|
||||
-re ".*gdb internal error.*$" {
|
||||
fail "Internal error, prob. Memory corruption"
|
||||
}
|
||||
-re "No executable file now.*Discard symbol table.*y or n.*$" {
|
||||
send_gdb "y\n"
|
||||
gdb_expect {
|
||||
-re "No symbol file now.*$gdb_prompt $"\
|
||||
{pass "attach1, purging symbols after detach"}
|
||||
-re "$gdb_prompt $" {fail "attach1, purging symbols after detach"}
|
||||
timeout {fail "(timeout) attach1, purging symbols after detach"}
|
||||
}
|
||||
}
|
||||
-re "$gdb_prompt $" {fail "attach1, purging file after detach"}
|
||||
timeout {
|
||||
fail "(timeout) attach1, purging file after detach"
|
||||
}
|
||||
}
|
||||
set timeout $old_timeout
|
||||
|
||||
# Verify that we can attach to the process just by giving the
|
||||
# process ID.
|
||||
#
|
||||
send_gdb "attach $testpid\n"
|
||||
gdb_expect {
|
||||
-re "Attaching to process $testpid.*Reading symbols from $binfile.*main.*at .*$gdb_prompt $"\
|
||||
{pass "attach2"}
|
||||
-re "$gdb_prompt $" {fail "attach2"}
|
||||
timeout {fail "(timeout) attach2"}
|
||||
}
|
||||
|
||||
# Verify that we can modify the variable "should_exit" in the
|
||||
# program.
|
||||
#
|
||||
send_gdb "set should_exit=1\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "after attach2, set should_exit"}
|
||||
timeout {fail "(timeout) after attach2, set should_exit"}
|
||||
}
|
||||
|
||||
# Verify that the modification really happened.
|
||||
#
|
||||
send_gdb "tbreak 19\n"
|
||||
gdb_expect {
|
||||
-re "Breakpoint .*at.*$srcfile, line 19.*$gdb_prompt $"\
|
||||
{pass "after attach2, set tbreak postloop"}
|
||||
-re "$gdb_prompt $" {fail "after attach2, set tbreak postloop"}
|
||||
timeout {fail "(timeout) after attach2, set tbreak postloop"}
|
||||
}
|
||||
send_gdb "continue\n"
|
||||
gdb_expect {
|
||||
-re "main.*at.*$srcfile:19.*$gdb_prompt $"\
|
||||
{pass "after attach2, reach tbreak postloop"}
|
||||
-re "$gdb_prompt $" {fail "after attach2, reach tbreak postloop"}
|
||||
timeout {fail "(timeout) after attach2, reach tbreak postloop"}
|
||||
}
|
||||
|
||||
# Allow the test process to exit, to cleanup after ourselves.
|
||||
#
|
||||
send_gdb "continue\n"
|
||||
gdb_expect {
|
||||
-re "Program exited normally.*$gdb_prompt $"\
|
||||
{pass "after attach2, exit"}
|
||||
-re "$gdb_prompt $" {fail "after attach2, exit"}
|
||||
timeout {fail "(timeout) after attach2, exit"}
|
||||
}
|
||||
|
||||
# Make sure we don't leave a process around to confuse
|
||||
# the next test run (and prevent the compile by keeping
|
||||
# the text file busy), in case the "set should_exit" didn't
|
||||
# work.
|
||||
#
|
||||
remote_exec build "kill -9 ${testpid}"
|
||||
# Start the program running and then wait for a bit, to be sure
|
||||
# that it can be attached to.
|
||||
#
|
||||
set testpid [eval exec $binfile &]
|
||||
exec sleep 2
|
||||
|
||||
# Verify that we can attach to the process, and find its a.out
|
||||
# when we're cd'd to some directory that doesn't contain the
|
||||
# a.out. (We use the source path set by the "dir" command.)
|
||||
#
|
||||
send_gdb "dir ${objdir}/${subdir}\n"
|
||||
gdb_expect {
|
||||
-re ".*Source directories searched: .*$gdb_prompt $"\
|
||||
{pass "set source path"}
|
||||
-re "$gdb_prompt $" {fail "set source path"}
|
||||
timeout {fail "(timeout) set source path"}
|
||||
}
|
||||
|
||||
send_gdb "cd /tmp\n"
|
||||
gdb_expect {
|
||||
-re ".*Working directory /tmp.*$gdb_prompt $"\
|
||||
{pass "cd away from process' a.out"}
|
||||
-re "$gdb_prompt $" {fail "cd away from process' a.out"}
|
||||
timeout {fail "(timeout) cd away from process' a.out"}
|
||||
}
|
||||
|
||||
# Explicitly flush out any knowledge of the previous attachment.
|
||||
send_gdb "symbol\n"
|
||||
gdb_expect {
|
||||
-re ".*Discard symbol table from.*y or n. $"\
|
||||
{send_gdb "y\n"
|
||||
gdb_expect {
|
||||
-re ".*No symbol file now.*$gdb_prompt $"\
|
||||
{pass "before attach3, flush symbols"}
|
||||
-re "$gdb_prompt $" {fail "before attach3, flush symbols"}
|
||||
timeout {fail "(timeout) before attach3, flush symbols"}
|
||||
}
|
||||
}
|
||||
-re ".*No symbol file now.*$gdb_prompt $"\
|
||||
{pass "before attach3, flush symbols"}
|
||||
-re "$gdb_prompt $" {fail "before attach3, flush symbols"}
|
||||
timeout {fail "(timeout) before attach3, flush symbols"}
|
||||
}
|
||||
send_gdb "exec\n"
|
||||
gdb_expect {
|
||||
-re ".*No executable file now.*$gdb_prompt $"\
|
||||
{pass "before attach3, flush exec"}
|
||||
-re "$gdb_prompt $" {fail "before attach3, flush exec"}
|
||||
timeout {fail "(timeout) before attach3, flush exec"}
|
||||
}
|
||||
|
||||
send_gdb "attach $testpid\n"
|
||||
gdb_expect {
|
||||
-re "Attaching to process $testpid.*Reading symbols from $binfile.*main.*at .*$gdb_prompt $"\
|
||||
{pass "attach when process' a.out not in cwd"}
|
||||
-re "$gdb_prompt $" {fail "attach when process' a.out not in cwd"}
|
||||
timeout {fail "(timeout) attach when process' a.out not in cwd"}
|
||||
}
|
||||
|
||||
send_gdb "kill\n"
|
||||
gdb_expect {
|
||||
-re ".*Kill the program being debugged.*y or n. $"\
|
||||
{send_gdb "y\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "after attach3, exit"}
|
||||
timeout {fail "(timeout) after attach3, exit"}
|
||||
}
|
||||
}
|
||||
-re "$gdb_prompt $" {fail "after attach3, exit"}
|
||||
timeout {fail "(timeout) after attach3, exit"}
|
||||
}
|
||||
}
|
||||
|
||||
proc do_call_attach_tests {} {
|
||||
global gdb_prompt
|
||||
global binfile2
|
||||
|
||||
# Start the program running and then wait for a bit, to be sure
|
||||
# that it can be attached to.
|
||||
#
|
||||
set testpid [eval exec $binfile2 &]
|
||||
exec sleep 2
|
||||
|
||||
# Attach
|
||||
#
|
||||
gdb_test "file $binfile2" ".*" "force switch to gdb64, if necessary"
|
||||
send_gdb "attach $testpid\n"
|
||||
gdb_expect {
|
||||
-re ".*warning: reading register.*I.*O error.*$gdb_prompt $" {
|
||||
fail "attach call, read register 3 error"
|
||||
}
|
||||
-re "Attaching to.*process $testpid.*libc.*$gdb_prompt $" {
|
||||
pass "attach call"
|
||||
}
|
||||
-re "$gdb_prompt $" {fail "attach call"}
|
||||
timeout {fail "(timeout) attach call"}
|
||||
}
|
||||
|
||||
# See if other registers are problems
|
||||
#
|
||||
send_gdb "i r r3\n"
|
||||
gdb_expect {
|
||||
-re ".*warning: reading register.*$gdb_prompt $" {
|
||||
pass "CHFts23490: known bug"
|
||||
}
|
||||
-re ".*r3.*$gdb_prompt $" {
|
||||
pass "Bug fixed, Yayyy!"
|
||||
}
|
||||
timeout { fail "timeout on info reg" }
|
||||
}
|
||||
|
||||
# Get rid of the process
|
||||
#
|
||||
gdb_test "p should_exit = 1" ".*" ""
|
||||
gdb_test "c" ".*Program exited normally.*" ""
|
||||
|
||||
# Be paranoid
|
||||
#
|
||||
remote_exec build "kill -9 ${testpid}"
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Start with a fresh gdb
|
||||
#
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
gdb_load ${binfile}
|
||||
|
||||
# This is a test of gdb's ability to attach to a running process.
|
||||
#
|
||||
do_attach_tests
|
||||
|
||||
# Test attaching when the target is inside a system call
|
||||
#
|
||||
gdb_exit
|
||||
gdb_start
|
||||
|
||||
# this seems not necessary. - guo
|
||||
#
|
||||
# # Since we have moved the executable to /tmp, it will be hard for gdb
|
||||
# # to find the object file/executable to read the symbols. This is
|
||||
# # a known limitation. We try and get the name of the executable the
|
||||
# # process is running from a variety of methods, but none is foolproof.
|
||||
# # Using "dir" will get us the symbols.
|
||||
#
|
||||
# gdb_test "dir ./gdb.base" ".*" "set up directory before attach"
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
do_call_attach_tests
|
||||
|
||||
# Until "set follow-fork-mode" and "catch fork" are implemented on
|
||||
# other targets...
|
||||
#
|
||||
if ![istarget "hppa*-hp-hpux*"] then {
|
||||
setup_xfail "*-*-*"
|
||||
}
|
||||
|
||||
# Cleanup the files placed in /tmp and the symlinks
|
||||
remote_exec build "rm -f ${binfile} ${binfile2} /tmp/attach1.${pid} /tmp/attach2.${pid}"
|
||||
|
||||
return 0
|
24
gdb/testsuite/gdb.base/attach2.c
Normal file
24
gdb/testsuite/gdb.base/attach2.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* This program is intended to be started outside of gdb, and then
|
||||
attached to by gdb. Thus, it simply spins in a loop. The loop
|
||||
is exited when & if the variable 'should_exit' is non-zero. (It
|
||||
is initialized to zero in this program, so the loop will never
|
||||
exit unless/until gdb sets the variable to non-zero.)
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int should_exit = 0;
|
||||
|
||||
int main ()
|
||||
{
|
||||
int local_i = 0;
|
||||
|
||||
sleep( 10 ); /* System call causes register fetch to fail */
|
||||
/* This is a known HPUX "feature" */
|
||||
while (! should_exit)
|
||||
{
|
||||
local_i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
46
gdb/testsuite/gdb.base/average.c
Normal file
46
gdb/testsuite/gdb.base/average.c
Normal file
@ -0,0 +1,46 @@
|
||||
/* This is a sample program for the HP WDB debugger. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
extern int sum(int *, int, int);
|
||||
#else
|
||||
extern int sum();
|
||||
#endif
|
||||
|
||||
#define num 10
|
||||
|
||||
static int my_list[num] = {3,4,2,0,2,1,8,3,6,7};
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
void print_average(int *list, int low, int high)
|
||||
#else
|
||||
void print_average(list, low, high)
|
||||
int *list, low, high;
|
||||
#endif
|
||||
{
|
||||
int total = 0, num_elements = 0, average = 0;
|
||||
total = sum(list, low, high);
|
||||
num_elements = high - low; /* note this is an off-by-one bug */
|
||||
|
||||
average = total / num_elements;
|
||||
printf("%10.d\n", average);
|
||||
}
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int main(void)
|
||||
#else
|
||||
main ()
|
||||
#endif
|
||||
{
|
||||
char c;
|
||||
int first = 0, last = 0;
|
||||
last = num-1;
|
||||
|
||||
/* Try two test cases. */
|
||||
print_average (my_list, first, last);
|
||||
print_average (my_list, first, last - 3);
|
||||
|
||||
exit(0);
|
||||
}
|
319
gdb/testsuite/gdb.base/dbx.exp
Normal file
319
gdb/testsuite/gdb.base/dbx.exp
Normal file
@ -0,0 +1,319 @@
|
||||
# Copyright (C) 1998 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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
# Please email any bugs, comments, and/or additions to this file to:
|
||||
# bug-gdb@prep.ai.mit.edu
|
||||
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
set testfile1 "average"
|
||||
set testfile2 "sum"
|
||||
set testfile "dbx-test"
|
||||
set binfile1 ${objdir}/${subdir}/${testfile1}
|
||||
set binfile2 ${objdir}/${subdir}/${testfile2}
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
|
||||
|
||||
|
||||
if { [gdb_compile "${srcdir}/${subdir}/average.c" "${binfile1}.o" object {debug}] != "" } {
|
||||
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
|
||||
if { [gdb_compile "${srcdir}/${subdir}/sum.c" "${binfile2}.o" object {debug}] != "" } {
|
||||
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
|
||||
if { [gdb_compile "${binfile1}.o ${binfile2}.o" ${binfile} executable {debug}] != "" } {
|
||||
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
|
||||
#
|
||||
# start gdb -- start gdb running, default procedure
|
||||
#
|
||||
proc dbx_gdb_start { } {
|
||||
global verbose
|
||||
global GDB
|
||||
global GDBFLAGS
|
||||
global prompt
|
||||
global spawn_id
|
||||
global timeout
|
||||
verbose "Spawning $GDB -nw $GDBFLAGS"
|
||||
|
||||
if { [which $GDB] == 0 } then {
|
||||
perror "$GDB does not exist."
|
||||
exit 1
|
||||
}
|
||||
|
||||
set oldtimeout $timeout
|
||||
set timeout [expr "$timeout + 60"]
|
||||
eval "spawn $GDB -nw -dbx $GDBFLAGS"
|
||||
gdb_expect {
|
||||
-re ".*\r\n$gdb_prompt $" {
|
||||
verbose "GDB initialized."
|
||||
}
|
||||
-re "$prompt $" {
|
||||
perror "GDB never initialized."
|
||||
return -1
|
||||
}
|
||||
timeout {
|
||||
perror "(timeout) GDB never initialized."
|
||||
return -1
|
||||
}
|
||||
}
|
||||
set timeout $oldtimeout
|
||||
# force the height to "unlimited", so no pagers get used
|
||||
send_gdb "set height 0\n"
|
||||
gdb_expect {
|
||||
-re ".*$prompt $" {
|
||||
verbose "Setting height to 0." 2
|
||||
}
|
||||
timeout {
|
||||
warning "Couldn't set the height to 0."
|
||||
}
|
||||
}
|
||||
# force the width to "unlimited", so no wraparound occurs
|
||||
send_gdb "set width 0\n"
|
||||
gdb_expect {
|
||||
-re ".*$prompt $" {
|
||||
verbose "Setting width to 0." 2
|
||||
}
|
||||
timeout {
|
||||
warning "Couldn't set the width to 0."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc dbx_reinitialize_dir { subdir } {
|
||||
global gdb_prompt
|
||||
|
||||
send_gdb "use\n"
|
||||
gdb_expect {
|
||||
-re "Reinitialize source path to empty.*y or n. " {
|
||||
send_gdb "y\n"
|
||||
gdb_expect {
|
||||
-re "Source directories searched.*$gdb_prompt $" {
|
||||
send_gdb "use $subdir\n"
|
||||
gdb_expect {
|
||||
-re "Source directories searched.*$gdb_prompt $" {
|
||||
verbose "Dir set to $subdir"
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
perror "Dir \"$subdir\" failed."
|
||||
}
|
||||
}
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
perror "Dir \"$subdir\" failed."
|
||||
}
|
||||
}
|
||||
}
|
||||
-re ".*$gdb_prompt $" {
|
||||
perror "Dir \"$subdir\" failed."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# In "testsuite/config/unix-gdb.exp", the routine "gdb_load"
|
||||
# is defined as "gdb_file_cmd". The binding of "gdb_file_cmd"
|
||||
# is done at invocation time. Before this file is processed,
|
||||
# it binds to the definition in "testsuite/lib/gdb.exp"; after
|
||||
# this file is processed, it binds to this definition.
|
||||
# TCL lets us overrides a previous routine definition without a
|
||||
# warning (isn't that special?).
|
||||
#
|
||||
# This means that tests before use "file" to load a target, and
|
||||
# tests afterwards use the pair "symbol-file" "exec-file".
|
||||
#
|
||||
# I'm leaving it as it is for now because at the moment it
|
||||
# is the only test we have of the use of the combination of
|
||||
# "symbol-file" and "exec-file" to load a debugging target (the
|
||||
# other definition uses "file".
|
||||
#
|
||||
# Symbol-file and exec-file should be tested explicitly, not
|
||||
# as a side effect of running a particular test (in this case,
|
||||
# "testsuite/gdb.compat/dbx.exp").
|
||||
#
|
||||
# CM: Renamed the procedure so it does not override the orginal file name.
|
||||
# Having the test suite change behavior depending on the tests run makes
|
||||
# it extremely difficult to reproduce errors. I've also added a
|
||||
# "dbx_gdb_load" procedure. This and only this test will call these
|
||||
# procedures now. I also added an "expect" to the "send exec-file" line.
|
||||
# The "expect" waits for a prompt to appear. Otherwise, if the tests run
|
||||
# too quickly, the caller could send another command before the prompt
|
||||
# of this command returns, causing the test to get out of sync and fail
|
||||
# seemingly randomly or only on a loaded system.
|
||||
#
|
||||
proc dbx_gdb_file_cmd {arg } {
|
||||
global verbose
|
||||
global loadpath
|
||||
global loadfile
|
||||
global GDB
|
||||
global gdb_prompt
|
||||
global spawn_id
|
||||
upvar timeout timeout
|
||||
|
||||
send_gdb "symbol-file $arg\n"
|
||||
gdb_expect {
|
||||
-re "Detected 64-bit symbol file.\r\nInvoking.*gdb64.*$gdb_prompt $" {
|
||||
verbose "\t\tLoaded $arg into the $GDB"
|
||||
send_gdb "exec-file $arg\n"
|
||||
gdb_expect {
|
||||
-re ".*$gdb_prompt $" {
|
||||
verbose "\t\tLoaded $arg with new symbol table into $GDB"
|
||||
return 0
|
||||
}
|
||||
timeout {
|
||||
perror "(timeout) Couldn't load $arg"
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
-re "Reading symbols from.*done.*$gdb_prompt $" {
|
||||
verbose "\t\tLoaded $arg into the $GDB"
|
||||
send_gdb "exec-file $arg\n"
|
||||
gdb_expect {
|
||||
-re ".*$gdb_prompt $" {
|
||||
verbose "\t\tLoaded $arg with new symbol table into $GDB"
|
||||
return 0
|
||||
}
|
||||
timeout {
|
||||
perror "(timeout) Couldn't load $arg"
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
-re "has no symbol-table.*$gdb_prompt $" {
|
||||
perror "$arg wasn't compiled with \"-g\""
|
||||
return -1
|
||||
}
|
||||
-re "A program is being debugged already.*Kill it.*y or n. $" {
|
||||
send_gdb "y\n"
|
||||
verbose "\t\tKilling previous program being debugged"
|
||||
exp_continue
|
||||
}
|
||||
-re "Load new symbol table from \".*\".*y or n. $" {
|
||||
send_gdb "y\n"
|
||||
gdb_expect {
|
||||
-re "Reading symbols from.*done.*$gdb_prompt $" {
|
||||
verbose "\t\tLoaded $arg with new symbol table into $GDB"
|
||||
return 0
|
||||
}
|
||||
timeout {
|
||||
perror "(timeout) Couldn't load $arg, other program already loaded."
|
||||
return -1
|
||||
}
|
||||
}
|
||||
}
|
||||
-re ".*No such file or directory.*$gdb_prompt $" {
|
||||
perror "($arg) No such file or directory\n"
|
||||
return -1
|
||||
}
|
||||
-re "$gdb_prompt $" {
|
||||
perror "couldn't load $arg into $GDB."
|
||||
return -1
|
||||
}
|
||||
timeout {
|
||||
perror "couldn't load $arg into $GDB (timed out)."
|
||||
return -1
|
||||
}
|
||||
eof {
|
||||
# This is an attempt to detect a core dump, but seems not to
|
||||
# work. Perhaps we need to match .* followed by eof, in which
|
||||
# expect does not seem to have a way to do that.
|
||||
perror "couldn't load $arg into $GDB (end of file)."
|
||||
return -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc dbx_gdb_load { arg } {
|
||||
global verbose
|
||||
global loadpath
|
||||
global loadfile
|
||||
global GDB
|
||||
global prompt
|
||||
upvar timeout timeout
|
||||
|
||||
return [dbx_gdb_file_cmd $arg]
|
||||
}
|
||||
|
||||
#
|
||||
#test_breakpoints
|
||||
#
|
||||
proc test_breakpoints { } {
|
||||
gdb_test "stop in main" "Breakpoint.*at.*: file.*average\.c, line 38\."
|
||||
gdb_test "status" "Num.*Type.*Disp.*Enb.*Address.*What\r\n1\[ \r\]+breakpoint\[ \r\]+keep y.*in main at.*average\.c:38.*"
|
||||
gdb_test "stop at 43" "Breakpoint.*at.*: file.*average\.c, line 43.*"
|
||||
gdb_test "stop in 43" "Usage: stop in <function . address>"
|
||||
gdb_test "stop at main" "Usage: stop at <line>"
|
||||
}
|
||||
|
||||
#
|
||||
#test_assign
|
||||
#
|
||||
proc test_assign { } {
|
||||
gdb_test "run" ""
|
||||
gdb_test "assign first=1" ""
|
||||
gdb_test "print first" ".1 = 1"
|
||||
}
|
||||
|
||||
#
|
||||
#test_whereis
|
||||
#
|
||||
proc test_whereis { } {
|
||||
gdb_test "whereis my_list" "All variables matching regular expression \"my_list\":\r\n\r\nFile.*average\.c:\r\nstatic int my_list\\\[10\\\];"
|
||||
}
|
||||
|
||||
#
|
||||
#test_func
|
||||
#
|
||||
proc test_func { } {
|
||||
gdb_test "cont" ""
|
||||
gdb_test "step" ""
|
||||
gdb_test "func sum" "'sum' not within current stack frame\."
|
||||
gdb_test "stop in sum" "Breakpoint.*at.*: file.*sum\.c, line 11\."
|
||||
gdb_test "cont"
|
||||
gdb_test "func print_average" ".*in print_average.*\\(list=.*, low=0, high=6\\).*at.*average\.c:24\r\n24\[ \t\]+total = sum\\(list, low, high\\);"
|
||||
}
|
||||
|
||||
# Start with a fresh gdb.
|
||||
|
||||
gdb_exit
|
||||
global GDBFLAGS
|
||||
set saved_gdbflags $GDBFLAGS
|
||||
|
||||
set GDBFLAGS "$GDBFLAGS --dbx"
|
||||
gdb_start
|
||||
dbx_reinitialize_dir $srcdir/$subdir
|
||||
dbx_gdb_load ${binfile}
|
||||
|
||||
test_breakpoints
|
||||
test_assign
|
||||
test_whereis
|
||||
gdb_test "file average.c:1" "1\[ \t\]+/. This is a sample program.*"
|
||||
test_func
|
||||
|
||||
#exit and cleanup
|
||||
gdb_exit
|
||||
|
||||
set GDBFLAGS $saved_gdbflags
|
||||
return 0
|
34
gdb/testsuite/gdb.base/execd-prog.c
Normal file
34
gdb/testsuite/gdb.base/execd-prog.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* There is a global_i in foll-exec, which exec's us. We
|
||||
should not be able to see that other definition of global_i
|
||||
after we are exec'd.
|
||||
*/
|
||||
int global_i = 0;
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int main (int argc, char **argv)
|
||||
#else
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char * argv[];
|
||||
#endif
|
||||
{
|
||||
/* There is a local_j in foll-exec, which exec's us. We
|
||||
should not be able to see that other definition of local_j
|
||||
after we are exec'd.
|
||||
*/
|
||||
int local_j = argc;
|
||||
char * s;
|
||||
|
||||
printf ("Hello from execd-prog...\n");
|
||||
if (argc != 2)
|
||||
{
|
||||
printf ("expected one string argument\n");
|
||||
exit (-1);
|
||||
}
|
||||
s = argv[1];
|
||||
printf ("argument received: %s\n", s);
|
||||
}
|
43
gdb/testsuite/gdb.base/foll-exec.c
Normal file
43
gdb/testsuite/gdb.base/foll-exec.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
int global_i = 100;
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int main (void)
|
||||
#else
|
||||
main ()
|
||||
#endif
|
||||
{
|
||||
int local_j = global_i+1;
|
||||
int local_k = local_j+1;
|
||||
|
||||
printf ("foll-exec is about to execlp(execd-prog)...\n");
|
||||
|
||||
execlp ("gdb.base/execd-prog",
|
||||
"gdb.base/execd-prog",
|
||||
"execlp arg1 from foll-exec",
|
||||
(char *)0);
|
||||
|
||||
printf ("foll-exec is about to execl(execd-prog)...\n");
|
||||
|
||||
execl ("gdb.base/execd-prog",
|
||||
"gdb.base/execd-prog",
|
||||
"execl arg1 from foll-exec",
|
||||
"execl arg2 from foll-exec",
|
||||
(char *)0);
|
||||
|
||||
{
|
||||
static char * argv[] = {
|
||||
(char *)"gdb.base/execd-prog",
|
||||
(char *)"execv arg1 from foll-exec",
|
||||
(char *)0};
|
||||
|
||||
printf ("foll-exec is about to execv(execd-prog)...\n");
|
||||
|
||||
execv ("gdb.base/execd-prog", argv);
|
||||
}
|
||||
}
|
396
gdb/testsuite/gdb.base/foll-exec.exp
Normal file
396
gdb/testsuite/gdb.base/foll-exec.exp
Normal file
@ -0,0 +1,396 @@
|
||||
# Copyright (C) 1997 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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
# Please email any bugs, comments, and/or additions to this file to:
|
||||
# bug-gdb@prep.ai.mit.edu
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
set prms_id 0
|
||||
set bug_id 0
|
||||
|
||||
set testfile "foll-exec"
|
||||
set testfile2 "execd-prog"
|
||||
set srcfile ${testfile}.c
|
||||
set srcfile2 ${testfile2}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
set binfile2 ${objdir}/${subdir}/${testfile2}
|
||||
|
||||
# build the first test case
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug}] != "" } {
|
||||
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
||||
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
|
||||
|
||||
# Until "catch exec" is implemented on other targets...
|
||||
#
|
||||
if ![istarget "hppa*-hp-hpux*"] then {
|
||||
continue
|
||||
}
|
||||
|
||||
proc zap_session {} {
|
||||
global gdb_prompt
|
||||
global binfile
|
||||
|
||||
send_gdb "kill\n"
|
||||
gdb_expect {
|
||||
-re ".*Kill the program being debugged.*y or n. $" {
|
||||
send_gdb "y\n"
|
||||
send_gdb "file $binfile\n"
|
||||
gdb_expect {
|
||||
-re ".*Load new symbol table from.*y or n. $" {
|
||||
send_gdb "y\n"
|
||||
gdb_expect {
|
||||
-re "Reading symbols from.*$gdb_prompt $" {}
|
||||
timeout { fail "loading symbols (timeout)"; return }
|
||||
}
|
||||
}
|
||||
-re ".*gdb_prompt $" {}
|
||||
timeout { fail "loading symbols (timeout)"; return }
|
||||
}
|
||||
}
|
||||
-re ".*$gdb_prompt $" {}
|
||||
timeout { fail "killing inferior (timeout)" ; return }
|
||||
}
|
||||
}
|
||||
|
||||
proc do_exec_tests {} {
|
||||
global gdb_prompt
|
||||
global binfile
|
||||
global srcfile
|
||||
global srcfile2
|
||||
global testfile
|
||||
global testfile2
|
||||
|
||||
# Start the program running, and stop at main.
|
||||
#
|
||||
if ![runto_main] then {
|
||||
perror "Couldn't run ${testfile}"
|
||||
return
|
||||
}
|
||||
|
||||
# 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 "next 3\n"
|
||||
gdb_expect {
|
||||
-re "20.*execlp.*$gdb_prompt $"\
|
||||
{pass "step to exec call"}
|
||||
-re "$gdb_prompt $" {fail "step to exec call"}
|
||||
timeout {fail "(timeout) step to exec call"}
|
||||
}
|
||||
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.
|
||||
#
|
||||
send_gdb "next\n"
|
||||
gdb_expect {
|
||||
-re "Executing new program: .*${testfile2}.*${srcfile2}:23.*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 "26.*printf.*$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...
|
||||
zap_session
|
||||
|
||||
# Start the program running, and stop at main.
|
||||
#
|
||||
if ![runto_main] then {
|
||||
perror "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.
|
||||
#
|
||||
send_gdb "info breakpoints\n"
|
||||
gdb_expect {
|
||||
-re ".*catch exec.*keep y.*$gdb_prompt $"\
|
||||
{pass "info shows catchpoint without exec pathname"}
|
||||
-re ".*catch exec.*program \"\".*$gdb_prompt $"\
|
||||
{fail "info shows catchpoint without exec pathname"}
|
||||
-re "$gdb_prompt $" {fail "info shows catchpoint without exec pathname"}
|
||||
timeout {fail "(timeout) info shows catchpoint without exec pathname"}
|
||||
}
|
||||
|
||||
# DTS CLLbs16760
|
||||
# PA64 doesn't know about $START$ in dld.sl at this point. It should.
|
||||
# - Michael Coulter
|
||||
setup_xfail hppa2.0w-hp-hpux*
|
||||
send_gdb "continue\n"
|
||||
gdb_expect {
|
||||
-re ".*Executing new program:.*${testfile2}.*Catchpoint .*(exec\'d .*${testfile2}).*in .START..*$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.
|
||||
#
|
||||
send_gdb "info breakpoints\n"
|
||||
gdb_expect {
|
||||
-re ".*catch exec .*program \".*${testfile2}\".*$gdb_prompt $"\
|
||||
{pass "info shows catchpoint exec pathname"}
|
||||
-re "$gdb_prompt $" {fail "info shows catchpoint exec pathname"}
|
||||
timeout {fail "(timeout) info shows catchpoint exec pathname"}
|
||||
}
|
||||
|
||||
# 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}:23.*$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...
|
||||
zap_session
|
||||
|
||||
# Start the program running, and stop at main.
|
||||
#
|
||||
if ![runto_main] then {
|
||||
perror "Couldn't run ${testfile} (3rd try)"
|
||||
return
|
||||
}
|
||||
|
||||
# Verify that we can follow through follow an execl()
|
||||
# call. (We must jump around earlier exec* calls.)
|
||||
#
|
||||
send_gdb "tbreak 27\n"
|
||||
gdb_expect {
|
||||
-re "Breakpoint .*file .*${srcfile}, line 27.*$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 27\n"
|
||||
gdb_expect {
|
||||
-re "main.* at .*${srcfile}:27.*$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 "Executing new program: .*${testfile2}.*${srcfile2}:23.*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 "26.*printf.*$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...
|
||||
zap_session
|
||||
|
||||
# Start the program running, and stop at main.
|
||||
#
|
||||
if ![runto_main] then {
|
||||
perror "Couldn't run ${testfile} (4th try)"
|
||||
return
|
||||
}
|
||||
|
||||
# Verify that we can follow through follow an execv()
|
||||
# call. (We must jump around earlier exec* calls.)
|
||||
#
|
||||
send_gdb "tbreak 41\n"
|
||||
gdb_expect {
|
||||
-re "Breakpoint .*file .*${srcfile}, line 41.*$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 41\n"
|
||||
gdb_expect {
|
||||
-re "main.* at .*${srcfile}:41.*$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 "Executing new program: .*${testfile2}.*${srcfile2}:23.*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 "26.*printf.*$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...
|
||||
zap_session
|
||||
|
||||
# Start the program running, and stop at main.
|
||||
#
|
||||
if ![runto_main] then {
|
||||
perror "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 "Executing new program: .*${testfile2}.*${srcfile2}:23.*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
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
gdb_load ${binfile}
|
||||
|
||||
|
||||
# This is a test of gdb's ability to follow a process through a
|
||||
# Unix exec() system call.
|
||||
#
|
||||
do_exec_tests
|
||||
|
||||
return 0
|
34
gdb/testsuite/gdb.base/foll-fork.c
Normal file
34
gdb/testsuite/gdb.base/foll-fork.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
void callee (int i)
|
||||
#else
|
||||
void callee (i)
|
||||
int i;
|
||||
#endif
|
||||
{
|
||||
printf("callee: %d\n", i);
|
||||
}
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int main (void)
|
||||
#else
|
||||
main ()
|
||||
#endif
|
||||
{
|
||||
int pid;
|
||||
int v = 5;
|
||||
|
||||
pid = fork ();
|
||||
if (pid == 0)
|
||||
{
|
||||
v++;
|
||||
/* printf ("I'm the child!\n"); */
|
||||
}
|
||||
else
|
||||
{
|
||||
v--;
|
||||
/* printf ("I'm the proud parent of child #%d!\n", pid); */
|
||||
}
|
||||
}
|
363
gdb/testsuite/gdb.base/foll-fork.exp
Normal file
363
gdb/testsuite/gdb.base/foll-fork.exp
Normal file
@ -0,0 +1,363 @@
|
||||
# Copyright (C) 1997 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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
# Please email any bugs, comments, and/or additions to this file to:
|
||||
# bug-gdb@prep.ai.mit.edu
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
set prms_id 0
|
||||
set bug_id 0
|
||||
|
||||
set testfile "foll-fork"
|
||||
set srcfile ${testfile}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
||||
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Until "set follow-fork-mode" and "catch fork" are implemented on
|
||||
# other targets...
|
||||
#
|
||||
if ![istarget "hppa*-hp-hpux*"] then {
|
||||
continue
|
||||
}
|
||||
|
||||
proc default_fork_parent_follow {} {
|
||||
global gdb_prompt
|
||||
|
||||
send_gdb "show follow\n"
|
||||
gdb_expect {
|
||||
-re "Debugger response to a program call of fork or vfork is \"parent\"..*$gdb_prompt $"\
|
||||
{pass "default show parent follow, no catchpoints"}
|
||||
-re "$gdb_prompt $" {fail "default show parent follow, no catchpoints"}
|
||||
timeout {fail "(timeout) default show parent follow, no catchpoints"}
|
||||
}
|
||||
send_gdb "next 2\n"
|
||||
gdb_expect {
|
||||
-re "Detaching after fork from.*$gdb_prompt $"\
|
||||
{pass "default parent follow, no catchpoints"}
|
||||
-re "$gdb_prompt $" {fail "default parent follow, no catchpoints"}
|
||||
timeout {fail "(timeout) default parent follow, no catchpoints" }
|
||||
}
|
||||
# The child has been detached; allow time for any output it might
|
||||
# generate to arrive, so that output doesn't get confused with
|
||||
# any expected debugger output from a subsequent testpoint.
|
||||
#
|
||||
exec sleep 1
|
||||
}
|
||||
|
||||
proc explicit_fork_parent_follow {} {
|
||||
global gdb_prompt
|
||||
|
||||
send_gdb "set follow parent\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "set follow parent"}
|
||||
timeout {fail "(timeout) set follow parent"}
|
||||
}
|
||||
send_gdb "show follow\n"
|
||||
gdb_expect {
|
||||
-re "Debugger response to a program call of fork or vfork is \"parent\"..*$gdb_prompt $"\
|
||||
{pass "explicit show parent follow, no catchpoints"}
|
||||
-re "$gdb_prompt $" {fail "explicit show parent follow, no catchpoints"}
|
||||
timeout {fail "(timeout) explicit show parent follow, no catchpoints"}
|
||||
}
|
||||
send_gdb "next 2\n"
|
||||
gdb_expect {
|
||||
-re "Detaching after fork from.*$gdb_prompt $"\
|
||||
{pass "explicit parent follow, no catchpoints"}
|
||||
-re "$gdb_prompt $" {fail "explicit parent follow, no catchpoints"}
|
||||
timeout {fail "(timeout) explicit parent follow, no catchpoints"}
|
||||
}
|
||||
# The child has been detached; allow time for any output it might
|
||||
# generate to arrive, so that output doesn't get confused with
|
||||
# any expected debugger output from a subsequent testpoint.
|
||||
#
|
||||
exec sleep 1
|
||||
}
|
||||
|
||||
proc explicit_fork_child_follow {} {
|
||||
global gdb_prompt
|
||||
|
||||
send_gdb "set follow child\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "set follow child"}
|
||||
timeout {fail "(timeout) set follow child"}
|
||||
}
|
||||
send_gdb "show follow\n"
|
||||
gdb_expect {
|
||||
-re "Debugger response to a program call of fork or vfork is \"child\"..*$gdb_prompt $"\
|
||||
{pass "explicit show child follow, no catchpoints"}
|
||||
-re "$gdb_prompt $" {fail "explicit show child follow, no catchpoints"}
|
||||
timeout {fail "(timeout) explicit show child follow, no catchpoints"}
|
||||
}
|
||||
send_gdb "next 2\n"
|
||||
gdb_expect {
|
||||
-re "Detaching from program:.*Attaching after fork to.*$gdb_prompt $"\
|
||||
{pass "explicit child follow, no catchpoints"}
|
||||
-re "$gdb_prompt $" {fail "explicit child follow, no catchpoints"}
|
||||
timeout {fail "(timeout) explicit child follow, no catchpoints"}
|
||||
}
|
||||
# The child has been detached; allow time for any output it might
|
||||
# generate to arrive, so that output doesn't get confused with
|
||||
# any gdb_expected debugger output from a subsequent testpoint.
|
||||
#
|
||||
exec sleep 1
|
||||
}
|
||||
|
||||
proc catch_fork_child_follow {} {
|
||||
global gdb_prompt
|
||||
|
||||
send_gdb "catch fork\n"
|
||||
gdb_expect {
|
||||
-re "Catchpoint .*(fork).*$gdb_prompt $"\
|
||||
{pass "explicit child follow, set catch fork"}
|
||||
-re "$gdb_prompt $" {fail "explicit child follow, set catch fork"}
|
||||
timeout {fail "(timeout) explicit child follow, set catch fork"}
|
||||
}
|
||||
|
||||
# Verify that the catchpoint is mentioned in an "info breakpoints",
|
||||
# and further that the catchpoint mentions no process id.
|
||||
#
|
||||
send_gdb "info breakpoints\n"
|
||||
gdb_expect {
|
||||
-re ".*catch fork.*keep y.*$gdb_prompt $"\
|
||||
{pass "info shows catchpoint without pid"}
|
||||
-re ".*catch fork.*process .*$gdb_prompt $"\
|
||||
{fail "info shows catchpoint without pid"}
|
||||
-re "$gdb_prompt $" {fail "info shows catchpoint without pid"}
|
||||
timeout {fail "(timeout) info shows catchpoint without pid"}
|
||||
}
|
||||
|
||||
send_gdb "continue\n"
|
||||
gdb_expect {
|
||||
-re "Catchpoint.*(forked process.*),.*in _fork_sys.*$gdb_prompt $"\
|
||||
{pass "explicit child follow, catch fork"}
|
||||
-re "$gdb_prompt $" {fail "explicit child follow, catch fork"}
|
||||
timeout {fail "(timeout) explicit child follow, catch fork"}
|
||||
}
|
||||
|
||||
# Verify that the catchpoint is mentioned in an "info breakpoints",
|
||||
# and further that the catchpoint managed to capture a process id.
|
||||
#
|
||||
send_gdb "info breakpoints\n"
|
||||
gdb_expect {
|
||||
-re ".*catch fork .*process \[0-9\]+.*$gdb_prompt $"\
|
||||
{pass "info shows catchpoint pid"}
|
||||
-re "$gdb_prompt $" {fail "info shows catchpoint pid"}
|
||||
timeout {fail "(timeout) info shows catchpoint pid"}
|
||||
}
|
||||
|
||||
send_gdb "set follow child\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "set follow child"}
|
||||
timeout {fail "(timeout) set follow child"}
|
||||
}
|
||||
send_gdb "tbreak 24\n"
|
||||
gdb_expect {
|
||||
-re "Breakpoint.*, line 24.*$gdb_prompt $"\
|
||||
{pass "set follow child, tbreak"}
|
||||
-re "$gdb_prompt $" {fail "set follow child, tbreak"}
|
||||
timeout {fail "(timeout) set follow child, tbreak"}
|
||||
}
|
||||
send_gdb "continue\n"
|
||||
gdb_expect {
|
||||
-re ".*Detaching from program:.*Attaching after fork to.* at .*24.*$gdb_prompt $"\
|
||||
{pass "set follow child, hit tbreak"}
|
||||
-re "$gdb_prompt $" {fail "set follow child, hit tbreak"}
|
||||
timeout {fail "(timeout) set follow child, hit tbreak"}
|
||||
}
|
||||
# The child has been detached; allow time for any output it might
|
||||
# generate to arrive, so that output doesn't get confused with
|
||||
# any expected debugger output from a subsequent testpoint.
|
||||
#
|
||||
exec sleep 1
|
||||
send_gdb "delete breakpoints\n"
|
||||
gdb_expect {
|
||||
-re "Delete all breakpoints.*$" {
|
||||
send_gdb "y\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $"\
|
||||
{pass "set follow child, cleanup"}
|
||||
timeout {fail "(timeout) set follow child, cleanup"}
|
||||
}
|
||||
}
|
||||
-re "$gdb_prompt $" {fail "set follow child, cleanup"}
|
||||
timeout {fail "(timeout) set follow child, cleanup"}
|
||||
}
|
||||
}
|
||||
|
||||
proc tcatch_fork_parent_follow {} {
|
||||
global gdb_prompt
|
||||
|
||||
send_gdb "catch fork\n"
|
||||
gdb_expect {
|
||||
-re "Catchpoint .*(fork).*$gdb_prompt $"\
|
||||
{pass "explicit parent follow, set tcatch fork"}
|
||||
-re "$gdb_prompt $" {fail "explicit parent follow, set tcatch fork"}
|
||||
timeout {fail "(timeout) explicit parent follow, set tcatch fork"}
|
||||
}
|
||||
# ??rehrauer: I don't yet know how to get the id of the tcatch
|
||||
# via this script, so that I can add a -do list to it. For now,
|
||||
# do the follow stuff after the catch happens.
|
||||
|
||||
send_gdb "continue\n"
|
||||
gdb_expect {
|
||||
-re ".*in _fork_sys.*$gdb_prompt $"\
|
||||
{pass "explicit parent follow, tcatch fork"}
|
||||
-re "$gdb_prompt $" {fail "explicit parent follow, tcatch fork"}
|
||||
timeout {fail "(timeout) explicit parent follow, tcatch fork"}
|
||||
}
|
||||
send_gdb "set follow parent\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "set follow parent"}
|
||||
timeout {fail "(timeout) set follow parent"}
|
||||
}
|
||||
send_gdb "tbreak 24\n"
|
||||
gdb_expect {
|
||||
-re "Breakpoint.*, line 24.*$gdb_prompt $"\
|
||||
{pass "set follow parent, tbreak"}
|
||||
-re "$gdb_prompt $" {fail "set follow parent, tbreak"}
|
||||
timeout {fail "(timeout) set follow child, tbreak"}
|
||||
}
|
||||
send_gdb "continue\n"
|
||||
gdb_expect {
|
||||
-re ".*Detaching after fork from.* at .*24.*$gdb_prompt $"\
|
||||
{pass "set follow parent, hit tbreak"}
|
||||
-re "$gdb_prompt $" {fail "set follow parent, hit tbreak"}
|
||||
timeout {fail "(timeout) set follow parent, hit tbreak"}
|
||||
}
|
||||
# The child has been detached; allow time for any output it might
|
||||
# generate to arrive, so that output doesn't get confused with
|
||||
# any expected debugger output from a subsequent testpoint.
|
||||
#
|
||||
exec sleep 1
|
||||
send_gdb "delete breakpoints\n"
|
||||
gdb_expect {
|
||||
-re "Delete all breakpoints.*$" {
|
||||
send_gdb "y\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $"\
|
||||
{pass "set follow parent, cleanup"}
|
||||
timeout {fail "(timeout) set follow parent, cleanup"}
|
||||
}
|
||||
}
|
||||
-re "$gdb_prompt $" {fail "set follow parent, cleanup"}
|
||||
timeout {fail "(timeout) set follow parent, cleanup"}
|
||||
}
|
||||
}
|
||||
|
||||
proc do_fork_tests {} {
|
||||
global gdb_prompt
|
||||
|
||||
# Verify that help is available for "set follow-fork-mode".
|
||||
#
|
||||
send_gdb "help set follow-fork-mode\n"
|
||||
gdb_expect {
|
||||
-re "Set debugger response to a program call of fork or vfork..*
|
||||
A fork or vfork creates a new process. follow-fork-mode can be:.*
|
||||
.*parent - the original process is debugged after a fork.*
|
||||
.*child - the new process is debugged after a fork.*
|
||||
.*ask - the debugger will ask for one of the above choices.*
|
||||
For \"parent\" or \"child\", the unfollowed process will run free..*
|
||||
By default, the debugger will follow the parent process..*$gdb_prompt $"\
|
||||
{ pass "help set follow" }
|
||||
-re "$gdb_prompt $" { fail "help set follow" }
|
||||
timeout { fail "(timeout) help set follow" }
|
||||
}
|
||||
|
||||
# Verify that we can set follow-fork-mode, using an abbreviation
|
||||
# for both the flag and its value.
|
||||
#
|
||||
send_gdb "set follow ch\n"
|
||||
send_gdb "show fol\n"
|
||||
gdb_expect {
|
||||
-re "Debugger response to a program call of fork or vfork is \"child\".*$gdb_prompt $"\
|
||||
{pass "set follow, using abbreviations"}
|
||||
timeout {fail "(timeout) set follow, using abbreviations"}
|
||||
}
|
||||
|
||||
# Verify that we cannot set follow-fork-mode to nonsense.
|
||||
#
|
||||
send_gdb "set follow chork\n"
|
||||
gdb_expect {
|
||||
-re "Undefined item: \"chork\".*$gdb_prompt $"\
|
||||
{pass "set follow to nonsense is prohibited"}
|
||||
-re "$gdb_prompt $" {fail "set follow to nonsense is prohibited"}
|
||||
timeout {fail "(timeout) set follow to nonsense is prohibited"}
|
||||
}
|
||||
send_gdb "set follow parent\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "set follow to nonsense is prohibited (reset parent)"}
|
||||
timeout {fail "set follow to nonsense is prohibited (reset parent)"}
|
||||
}
|
||||
|
||||
# Test the default behaviour, which is to follow the parent of a
|
||||
# fork, and detach from the child. Do this without catchpoints.
|
||||
#
|
||||
if [runto_main] then { default_fork_parent_follow }
|
||||
|
||||
# Test the ability to explicitly follow the parent of a fork, and
|
||||
# detach from the child. Do this without catchpoints.
|
||||
#
|
||||
if [runto_main] then { explicit_fork_parent_follow }
|
||||
|
||||
# Test the ability to follow the child of a fork, and detach from
|
||||
# the parent. Do this without catchpoints.
|
||||
#
|
||||
if [runto_main] then { explicit_fork_child_follow }
|
||||
|
||||
# Test the ability to follow both child and parent of a fork. Do
|
||||
# this without catchpoints.
|
||||
# ??rehrauer: NYI. Will add testpoints here when implemented.
|
||||
#
|
||||
|
||||
# Test the ability to have the debugger ask the user at fork-time
|
||||
# whether to follow the parent, child or both. Do this without
|
||||
# catchpoints.
|
||||
# ??rehrauer: NYI. Will add testpoints here when implemented.
|
||||
#
|
||||
|
||||
# Test the ability to catch a fork, specify that the child be
|
||||
# followed, and continue. Make the catchpoint permanent.
|
||||
#
|
||||
if [runto_main] then { catch_fork_child_follow }
|
||||
|
||||
# Test the ability to catch a fork, specify via a -do clause that
|
||||
# the parent be followed, and continue. Make the catchpoint temporary.
|
||||
#
|
||||
if [runto_main] then { tcatch_fork_parent_follow }
|
||||
}
|
||||
|
||||
# Start with a fresh gdb
|
||||
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
gdb_load ${binfile}
|
||||
|
||||
|
||||
# This is a test of gdb's ability to follow the parent, child or both
|
||||
# parent and child of a Unix fork() system call.
|
||||
#
|
||||
do_fork_tests
|
||||
|
||||
return 0
|
20
gdb/testsuite/gdb.base/foll-vfork.c
Normal file
20
gdb/testsuite/gdb.base/foll-vfork.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int main (void)
|
||||
#else
|
||||
main ()
|
||||
#endif
|
||||
{
|
||||
int pid;
|
||||
|
||||
pid = vfork ();
|
||||
if (pid == 0) {
|
||||
printf ("I'm the child!\n");
|
||||
execlp ("gdb.base/vforked-prog", "gdb.base/vforked-prog", (char *)0);
|
||||
}
|
||||
else {
|
||||
printf ("I'm the proud parent of child #%d!\n", pid);
|
||||
}
|
||||
}
|
365
gdb/testsuite/gdb.base/foll-vfork.exp
Normal file
365
gdb/testsuite/gdb.base/foll-vfork.exp
Normal file
@ -0,0 +1,365 @@
|
||||
# Copyright (C) 1997 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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
# Please email any bugs, comments, and/or additions to this file to:
|
||||
# bug-gdb@prep.ai.mit.edu
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
if [istarget "hppa2.0w-hp-hpux*"] {
|
||||
warning "Don't run gdb.base/foll-vfork.exp until JAGaa43495 kernel problem is fixed."
|
||||
return 0
|
||||
}
|
||||
|
||||
set prms_id 0
|
||||
set bug_id 0
|
||||
|
||||
set testfile "foll-vfork"
|
||||
set testfile2 "vforked-prog"
|
||||
set srcfile ${testfile}.c
|
||||
set srcfile2 ${testfile2}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
set binfile2 ${objdir}/${subdir}/${testfile2}
|
||||
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
||||
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug}] != "" } {
|
||||
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
|
||||
|
||||
# Until "set follow-fork-mode" and "catch vfork" are implemented on
|
||||
# other targets...
|
||||
#
|
||||
if ![istarget "hppa*-hp-hpux*"] then {
|
||||
continue
|
||||
}
|
||||
|
||||
# Test to see if we are on an HP-UX 10.20 and if so,
|
||||
# do not run these tests as catching vfork is disabled for
|
||||
# 10.20.
|
||||
|
||||
if [istarget "hppa*-hp-hpux10.20"] then {
|
||||
return 0
|
||||
}
|
||||
|
||||
# A few of these tests require a little more time than the standard
|
||||
# timeout allows.
|
||||
set oldtimeout $timeout
|
||||
set timeout [expr "$timeout + 10"]
|
||||
|
||||
proc vfork_parent_follow_through_step {} {
|
||||
global gdb_prompt
|
||||
|
||||
send_gdb "set follow parent\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "set follow parent, vfork through step"}
|
||||
timeout {fail "set follow parent, vfork through step"}
|
||||
}
|
||||
send_gdb "next\n"
|
||||
gdb_expect {
|
||||
-re "Detaching after fork from.*13.*$gdb_prompt $"\
|
||||
{pass "vfork parent follow, through step"}
|
||||
-re "$gdb_prompt $" {fail "vfork parent follow, through step"}
|
||||
timeout {fail "(timeout) vfork parent follow, through step" }
|
||||
}
|
||||
# The child has been detached; allow time for any output it might
|
||||
# generate to arrive, so that output doesn't get confused with
|
||||
# any gdb_expected debugger output from a subsequent testpoint.
|
||||
#
|
||||
exec sleep 1
|
||||
}
|
||||
|
||||
proc vfork_parent_follow_to_bp {} {
|
||||
global gdb_prompt
|
||||
|
||||
send_gdb "set follow parent\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "set follow parent, vfork to bp"}
|
||||
timeout {fail "set follow parent, vfork to bp"}
|
||||
}
|
||||
send_gdb "break 18\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "break, vfork to bp"}
|
||||
timeout {fail "break, vfork to bp"}
|
||||
}
|
||||
send_gdb "continue\n"
|
||||
gdb_expect {
|
||||
-re ".*Detaching after fork from process.*Breakpoint.*18.*$gdb_prompt $"\
|
||||
{pass "vfork parent follow, to bp"}
|
||||
-re "$gdb_prompt $" {fail "vfork parent follow, to bp"}
|
||||
timeout {fail "(timeout) vfork parent follow, to bp" }
|
||||
}
|
||||
# The child has been detached; allow time for any output it might
|
||||
# generate to arrive, so that output doesn't get confused with
|
||||
# any expected debugger output from a subsequent testpoint.
|
||||
#
|
||||
exec sleep 1
|
||||
}
|
||||
|
||||
proc vfork_and_exec_child_follow_to_main_bp {} {
|
||||
global gdb_prompt
|
||||
global binfile
|
||||
|
||||
send_gdb "set follow child\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "set follow child, vfork and exec to main bp"}
|
||||
timeout {fail "set follow child, vfork and exec to main bp"}
|
||||
}
|
||||
send_gdb "continue\n"
|
||||
gdb_expect {
|
||||
-re "Detaching from program.*Attaching after fork to.*Executing new program.*Breakpoint.*vforked-prog.c:9.*$gdb_prompt $"\
|
||||
{pass "vfork and exec child follow, to main bp"}
|
||||
-re "$gdb_prompt $" {fail "vfork and exec child follow, to main bp"}
|
||||
timeout {fail "(timeout) vfork and exec child follow, to main bp" }
|
||||
}
|
||||
# The parent has been detached; allow time for any output it might
|
||||
# generate to arrive, so that output doesn't get confused with
|
||||
# any gdb_expected debugger output from a subsequent testpoint.
|
||||
#
|
||||
exec sleep 1
|
||||
|
||||
# Explicitly kill this child, or a subsequent rerun actually runs
|
||||
# the exec'd child, not the original program...
|
||||
send_gdb "kill\n"
|
||||
gdb_expect {
|
||||
-re ".*Kill the program being debugged.*y or n. $" {
|
||||
send_gdb "y\n"
|
||||
send_gdb "file $binfile\n"
|
||||
gdb_expect {
|
||||
-re ".*Load new symbol table from.*y or n. $" {
|
||||
send_gdb "y\n"
|
||||
gdb_expect {
|
||||
-re "Reading symbols from.*$gdb_prompt $" {}
|
||||
timeout { fail "loading symbols (timeout)"; return }
|
||||
}
|
||||
}
|
||||
-re ".*gdb_prompt $" {}
|
||||
timeout { fail "loading symbols (timeout)"; return }
|
||||
}
|
||||
}
|
||||
-re ".*$gdb_prompt $" {}
|
||||
timeout { fail "killing inferior (timeout)" ; return }
|
||||
}
|
||||
}
|
||||
|
||||
proc vfork_and_exec_child_follow_through_step {} {
|
||||
global gdb_prompt
|
||||
global binfile
|
||||
|
||||
# This test cannot be performed prior to HP-UX 10.30, because ptrace-based
|
||||
# debugging of a vforking program basically doesn't allow the child to do
|
||||
# things like hit a breakpoint between a vfork and exec. This means that
|
||||
# saying "set follow child; next" at a vfork() call won't work, because
|
||||
# the implementation of "next" sets a "step resume" breakpoint at the
|
||||
# return from the vfork(), which the child will hit on its way to exec'ing.
|
||||
#
|
||||
if { ![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"] } {
|
||||
verbose "vfork child-following next test ignored for non-hppa or pre-HP/UX-10.30 targets."
|
||||
return 0
|
||||
}
|
||||
|
||||
send_gdb "set follow child\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "set follow child, vfork and exec through step"}
|
||||
timeout {fail "set follow child, vfork and exec through step"}
|
||||
}
|
||||
send_gdb "next\n"
|
||||
gdb_expect {
|
||||
-re "Detaching from program.*Attaching after fork to.*Executing new program.*Breakpoint.*vforked-prog.c:9.*$gdb_prompt $"\
|
||||
{pass "vfork and exec child follow, through step"}
|
||||
-re "$gdb_prompt $" {fail "vfork and exec child follow, through step"}
|
||||
timeout {fail "(timeout) vfork and exec child follow, through step" }
|
||||
}
|
||||
# The parent has been detached; allow time for any output it might
|
||||
# generate to arrive, so that output doesn't get confused with
|
||||
# any expected debugger output from a subsequent testpoint.
|
||||
#
|
||||
exec sleep 1
|
||||
|
||||
# Explicitly kill this child, or a subsequent rerun actually runs
|
||||
# the exec'd child, not the original program...
|
||||
send_gdb "kill\n"
|
||||
gdb_expect {
|
||||
-re ".*Kill the program being debugged.*y or n. $" {
|
||||
send_gdb "y\n"
|
||||
send_gdb "file $binfile\n"
|
||||
gdb_expect {
|
||||
-re ".*Load new symbol table from.*y or n. $" {
|
||||
send_gdb "y\n"
|
||||
gdb_expect {
|
||||
-re "Reading symbols from.*$gdb_prompt $" {}
|
||||
timeout { fail "loading symbols (timeout)"; return }
|
||||
}
|
||||
}
|
||||
-re ".*gdb_prompt $" {}
|
||||
timeout { fail "loading symbols (timeout)"; return }
|
||||
}
|
||||
}
|
||||
-re ".*$gdb_prompt $" {}
|
||||
timeout { fail "killing inferior (timeout)" ; return }
|
||||
}
|
||||
}
|
||||
|
||||
proc tcatch_vfork_then_parent_follow {} {
|
||||
global gdb_prompt
|
||||
global srcfile
|
||||
|
||||
send_gdb "set follow parent\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "set follow parent, tcatch vfork"}
|
||||
timeout {fail "set follow parent, tcatch vfork"}
|
||||
}
|
||||
send_gdb "tcatch vfork\n"
|
||||
gdb_expect {
|
||||
-re "Catchpoint .*(vfork).*$gdb_prompt $"\
|
||||
{pass "vfork parent follow, set tcatch vfork"}
|
||||
-re "$gdb_prompt $" {fail "vfork parent follow, set tcatch vfork"}
|
||||
timeout {fail "(timeout) vfork parent follow, set tcatch vfork"}
|
||||
}
|
||||
send_gdb "continue\n"
|
||||
# HP-UX 10.20 seems to stop you in "vfork", while more recent HP-UXs
|
||||
# stop you in "_vfork".
|
||||
gdb_expect {
|
||||
-re "0x\[0-9a-fA-F\]*.*vfork.*$gdb_prompt $"\
|
||||
{pass "vfork parent follow, tcatch vfork"}
|
||||
-re "0x\[0-9a-fA-F\]*.*_vfork.*$gdb_prompt $"\
|
||||
{pass "vfork parent follow, tcatch vfork"}
|
||||
-re "$gdb_prompt $" {fail "vfork parent follow, tcatch vfork"}
|
||||
timeout {fail "(timeout) vfork parent follow, tcatch vfork"}
|
||||
}
|
||||
send_gdb "finish\n"
|
||||
gdb_expect {
|
||||
-re "Run till exit from.*vfork.*0x\[0-9a-fA-F\]* in main .* at .*${srcfile}:12.*$gdb_prompt $"\
|
||||
{pass "vfork parent follow, finish after tcatch vfork"}
|
||||
-re "$gdb_prompt $" {fail "vfork parent follow, finish after tcatch vfork"}
|
||||
timeout {fail "(timeout) vfork parent follow, finish after tcatch vfork" }
|
||||
}
|
||||
# The child has been detached; allow time for any output it might
|
||||
# generate to arrive, so that output doesn't get confused with
|
||||
# any expected debugger output from a subsequent testpoint.
|
||||
#
|
||||
exec sleep 1
|
||||
}
|
||||
|
||||
proc tcatch_vfork_then_child_follow {} {
|
||||
global gdb_prompt
|
||||
global srcfile2
|
||||
|
||||
send_gdb "set follow child\n"
|
||||
gdb_expect {
|
||||
-re "$gdb_prompt $" {pass "set follow child, tcatch vfork"}
|
||||
timeout {fail "set follow child, tcatch vfork"}
|
||||
}
|
||||
send_gdb "tcatch vfork\n"
|
||||
gdb_expect {
|
||||
-re "Catchpoint .*(vfork).*$gdb_prompt $"\
|
||||
{pass "vfork child follow, set tcatch vfork"}
|
||||
-re "$gdb_prompt $" {fail "vfork child follow, set tcatch vfork"}
|
||||
timeout {fail "(timeout) vfork child follow, set tcatch vfork"}
|
||||
}
|
||||
send_gdb "continue\n"
|
||||
# HP-UX 10.20 seems to stop you in "vfork", while more recent HP-UXs
|
||||
# stop you in "_vfork".
|
||||
gdb_expect {
|
||||
-re "0x\[0-9a-fA-F\]*.*vfork.*$gdb_prompt $"\
|
||||
{pass "vfork child follow, tcatch vfork"}
|
||||
-re "0x\[0-9a-fA-F\]*.*_vfork.*$gdb_prompt $"\
|
||||
{pass "vfork child follow, tcatch vfork"}
|
||||
-re "$gdb_prompt $" {fail "vfork child follow, tcatch vfork"}
|
||||
timeout {fail "(timeout) vfork child follow, tcatch vfork"}
|
||||
}
|
||||
send_gdb "finish\n"
|
||||
gdb_expect {
|
||||
-re "Run till exit from.*vfork.*${srcfile2}:9.*$gdb_prompt $"\
|
||||
{pass "vfork child follow, finish after tcatch vfork"}
|
||||
-re "$gdb_prompt $" {fail "vfork child follow, finish after tcatch vfork"}
|
||||
timeout {fail "(timeout) vfork child follow, finish after tcatch vfork" }
|
||||
}
|
||||
# The parent has been detached; allow time for any output it might
|
||||
# generate to arrive, so that output doesn't get confused with
|
||||
# any expected debugger output from a subsequent testpoint.
|
||||
#
|
||||
exec sleep 1
|
||||
}
|
||||
|
||||
proc do_vfork_and_exec_tests {} {
|
||||
global gdb_prompt
|
||||
|
||||
# Try following the parent process by stepping through a call to
|
||||
# vfork. Do this without catchpoints.
|
||||
if [runto_main] then { vfork_parent_follow_through_step }
|
||||
|
||||
# Try following the parent process by setting a breakpoint on the
|
||||
# other side of a vfork, and running to that point. Do this
|
||||
# without catchpoints.
|
||||
if [runto_main] then { vfork_parent_follow_to_bp }
|
||||
|
||||
# Try following the child process by just continuing through the
|
||||
# vfork, and letting the parent's breakpoint on "main" be auto-
|
||||
# magically reset in the child.
|
||||
#
|
||||
if [runto_main] then { vfork_and_exec_child_follow_to_main_bp }
|
||||
|
||||
# Try following the child process by stepping through a call to
|
||||
# vfork. The child also executes an exec. Since the child cannot
|
||||
# be debugged until after it has exec'd, and since there's a bp on
|
||||
# "main" in the parent, and since the bp's for the parent are
|
||||
# recomputed in the exec'd child, the step through a vfork should
|
||||
# land us in the "main" for the exec'd child, too.
|
||||
#
|
||||
if [runto_main] then { vfork_and_exec_child_follow_through_step }
|
||||
|
||||
# Try catching a vfork, and stepping out to the parent.
|
||||
#
|
||||
if [runto_main] then { tcatch_vfork_then_parent_follow }
|
||||
|
||||
# Try catching a vfork, and stepping out to the child.
|
||||
#
|
||||
if [runto_main] then { tcatch_vfork_then_child_follow }
|
||||
|
||||
# Test the ability to follow both child and parent of a vfork. Do
|
||||
# this without catchpoints.
|
||||
# ??rehrauer: NYI. Will add testpoints here when implemented.
|
||||
#
|
||||
|
||||
# Test the ability to have the debugger ask the user at vfork-time
|
||||
# whether to follow the parent, child or both. Do this without
|
||||
# catchpoints.
|
||||
# ??rehrauer: NYI. Will add testpoints here when implemented.
|
||||
#
|
||||
}
|
||||
|
||||
# Start with a fresh gdb
|
||||
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
gdb_load ${binfile}
|
||||
|
||||
|
||||
# This is a test of gdb's ability to follow the parent or child
|
||||
# of a Unix vfork() system call. (The child will subsequently
|
||||
# call a variant of a Unix exec() system call.)
|
||||
#
|
||||
do_vfork_and_exec_tests
|
||||
|
||||
set timeout $oldtimeout
|
||||
return 0
|
40
gdb/testsuite/gdb.base/page.exp
Normal file
40
gdb/testsuite/gdb.base/page.exp
Normal file
@ -0,0 +1,40 @@
|
||||
# Copyright (C) 1992, 1994, 1995 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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
# Please email any bugs, comments, and/or additions to this file to:
|
||||
# bug-gdb@prep.ai.mit.edu
|
||||
|
||||
# This file was written by Fred Fish. (fnf@cygnus.com)
|
||||
|
||||
if $tracelevel {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
global message
|
||||
global timeout
|
||||
|
||||
set timeout 200
|
||||
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_test "set pagination off" ""
|
||||
gdb_test "info set" ".*pagination: State of pagination is off.*"
|
||||
gdb_test "set pagination on" ""
|
||||
gdb_test "info set" ".*pagination: State of pagination is on.*"
|
||||
|
||||
gdb_exit
|
||||
return 0
|
||||
|
211
gdb/testsuite/gdb.base/structs.c
Normal file
211
gdb/testsuite/gdb.base/structs.c
Normal file
@ -0,0 +1,211 @@
|
||||
/* Copyright (C) 1996 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 2 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, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Please email any bugs, comments, and/or additions to this file to:
|
||||
bug-gdb@prep.ai.mit.edu */
|
||||
|
||||
struct struct1 { char a;};
|
||||
struct struct2 { char a, b;};
|
||||
struct struct3 { char a, b, c; };
|
||||
struct struct4 { char a, b, c, d; };
|
||||
struct struct5 { char a, b, c, d, e; };
|
||||
struct struct6 { char a, b, c, d, e, f; };
|
||||
struct struct7 { char a, b, c, d, e, f, g; };
|
||||
struct struct8 { char a, b, c, d, e, f, g, h; };
|
||||
struct struct9 { char a, b, c, d, e, f, g, h, i; };
|
||||
struct struct10 { char a, b, c, d, e, f, g, h, i, j; };
|
||||
struct struct11 { char a, b, c, d, e, f, g, h, i, j, k; };
|
||||
struct struct12 { char a, b, c, d, e, f, g, h, i, j, k, l; };
|
||||
struct struct16 { char a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p; };
|
||||
|
||||
struct struct1 foo1 = {'1'}, L1;
|
||||
struct struct2 foo2 = { 'a', 'b'}, L2;
|
||||
struct struct3 foo3 = { 'A', 'B', 'C'}, L3;
|
||||
struct struct4 foo4 = {'1', '2', '3', '4'}, L4;
|
||||
struct struct5 foo5 = {'a', 'b', 'c', 'd', 'e'}, L5;
|
||||
struct struct6 foo6 = {'A', 'B', 'C', 'D', 'E', 'F'}, L6;
|
||||
struct struct7 foo7 = {'1', '2', '3', '4', '5', '6', '7'}, L7;
|
||||
struct struct8 foo8 = {'1', '2', '3', '4', '5', '6', '7', '8'}, L8;
|
||||
struct struct9 foo9 = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}, L9;
|
||||
struct struct10 foo10 = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'}, L10;
|
||||
struct struct11 foo11 = {
|
||||
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B'}, L11;
|
||||
struct struct12 foo12 = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'}, L12;
|
||||
struct struct16 foo16 = {
|
||||
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'}, L16;
|
||||
|
||||
struct struct1 fun1()
|
||||
{
|
||||
return foo1;
|
||||
}
|
||||
struct struct2 fun2()
|
||||
{
|
||||
return foo2;
|
||||
}
|
||||
struct struct3 fun3()
|
||||
{
|
||||
return foo3;
|
||||
}
|
||||
struct struct4 fun4()
|
||||
{
|
||||
return foo4;
|
||||
}
|
||||
struct struct5 fun5()
|
||||
{
|
||||
return foo5;
|
||||
}
|
||||
struct struct6 fun6()
|
||||
{
|
||||
return foo6;
|
||||
}
|
||||
struct struct7 fun7()
|
||||
{
|
||||
return foo7;
|
||||
}
|
||||
struct struct8 fun8()
|
||||
{
|
||||
return foo8;
|
||||
}
|
||||
struct struct9 fun9()
|
||||
{
|
||||
return foo9;
|
||||
}
|
||||
struct struct10 fun10()
|
||||
{
|
||||
return foo10;
|
||||
}
|
||||
struct struct11 fun11()
|
||||
{
|
||||
return foo11;
|
||||
}
|
||||
struct struct12 fun12()
|
||||
{
|
||||
return foo12;
|
||||
}
|
||||
struct struct16 fun16()
|
||||
{
|
||||
return foo16;
|
||||
}
|
||||
|
||||
void Fun1(foo1)
|
||||
struct struct1 foo1;
|
||||
{
|
||||
L1 = foo1;
|
||||
}
|
||||
void Fun2(foo2)
|
||||
struct struct2 foo2;
|
||||
{
|
||||
L2 = foo2;
|
||||
}
|
||||
void Fun3(foo3)
|
||||
struct struct3 foo3;
|
||||
{
|
||||
L3 = foo3;
|
||||
}
|
||||
void Fun4(foo4)
|
||||
struct struct4 foo4;
|
||||
{
|
||||
L4 = foo4;
|
||||
}
|
||||
void Fun5(foo5)
|
||||
struct struct5 foo5;
|
||||
{
|
||||
L5 = foo5;
|
||||
}
|
||||
void Fun6(foo6)
|
||||
struct struct6 foo6;
|
||||
{
|
||||
L6 = foo6;
|
||||
}
|
||||
void Fun7(foo7)
|
||||
struct struct7 foo7;
|
||||
{
|
||||
L7 = foo7;
|
||||
}
|
||||
void Fun8(foo8)
|
||||
struct struct8 foo8;
|
||||
{
|
||||
L8 = foo8;
|
||||
}
|
||||
void Fun9(foo9)
|
||||
struct struct9 foo9;
|
||||
{
|
||||
L9 = foo9;
|
||||
}
|
||||
void Fun10(foo10)
|
||||
struct struct10 foo10;
|
||||
{
|
||||
L10 = foo10;
|
||||
}
|
||||
void Fun11(foo11)
|
||||
struct struct11 foo11;
|
||||
{
|
||||
L11 = foo11;
|
||||
}
|
||||
void Fun12(foo12)
|
||||
struct struct12 foo12;
|
||||
{
|
||||
L12 = foo12;
|
||||
}
|
||||
void Fun16(foo16)
|
||||
struct struct16 foo16;
|
||||
{
|
||||
L16 = foo16;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef usestubs
|
||||
set_debug_traps();
|
||||
breakpoint();
|
||||
#endif
|
||||
|
||||
/* TEST C FUNCTIONS */
|
||||
L1 = fun1();
|
||||
L2 = fun2();
|
||||
L3 = fun3();
|
||||
L4 = fun4();
|
||||
L5 = fun5();
|
||||
L6 = fun6();
|
||||
L7 = fun7();
|
||||
L8 = fun8();
|
||||
L9 = fun9();
|
||||
L10 = fun10();
|
||||
L11 = fun11();
|
||||
L12 = fun12();
|
||||
L16 = fun16();
|
||||
|
||||
foo1.a = foo2.a = foo3.a = foo4.a = foo5.a = foo6.a = foo7.a = foo8.a =
|
||||
foo9.a = foo10.a = foo11.a = foo12.a = foo16.a = '$';
|
||||
|
||||
Fun1(foo1);
|
||||
Fun2(foo2);
|
||||
Fun3(foo3);
|
||||
Fun4(foo4);
|
||||
Fun5(foo5);
|
||||
Fun6(foo6);
|
||||
Fun7(foo7);
|
||||
Fun8(foo8);
|
||||
Fun9(foo9);
|
||||
Fun10(foo10);
|
||||
Fun11(foo11);
|
||||
Fun12(foo12);
|
||||
Fun16(foo16);
|
||||
|
||||
return 0;
|
||||
}
|
148
gdb/testsuite/gdb.base/structs.exp
Normal file
148
gdb/testsuite/gdb.base/structs.exp
Normal file
@ -0,0 +1,148 @@
|
||||
# Copyright (C) 1996, 1997 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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# Please email any bugs, comments, and/or additions to this file to:
|
||||
# bug-gdb@prep.ai.mit.edu
|
||||
|
||||
# This file was written by Jeff Law. (law@cygnus.com)
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
set prms_id 0
|
||||
set bug_id 0
|
||||
|
||||
set prototypes 1
|
||||
set testfile "structs"
|
||||
set srcfile ${testfile}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
|
||||
# build the first test case
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
||||
# built the second test case since we can't use prototypes
|
||||
warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES"
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DNO_PROTOTYPES}] != "" } {
|
||||
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
set prototypes 0
|
||||
}
|
||||
|
||||
# Create and source the file that provides information about the compiler
|
||||
# used to compile the test case.
|
||||
if [get_compiler_info ${binfile}] {
|
||||
return -1;
|
||||
}
|
||||
|
||||
# The a29k can't call functions, so don't even bother with this test.
|
||||
if [istarget "a29k-*-udi"] then {
|
||||
setup_xfail "a29k-*-udi" 2416
|
||||
fail "a29k-*-udi can not call functions"
|
||||
continue
|
||||
}
|
||||
|
||||
# FIXME: Before calling this proc, we should probably verify that
|
||||
# we can call inferior functions and get a valid integral value
|
||||
# returned.
|
||||
# Note that it is OK to check for 0 or 1 as the returned values, because C
|
||||
# specifies that the numeric value of a relational or logical expression
|
||||
# (computed in the inferior) is 1 for true and 0 for false.
|
||||
|
||||
proc do_function_calls {} {
|
||||
global prototypes
|
||||
global gcc_compiled
|
||||
global gdb_prompt
|
||||
|
||||
# First, call the "fun" functions and examine the value they return.
|
||||
gdb_test "p fun1()" " = {a = 49 '1'}"
|
||||
gdb_test "p fun2()" " = {a = 97 'a', b = 98 'b'}"
|
||||
gdb_test "p fun3()" " = {a = 65 'A', b = 66 'B', c = 67 'C'}"
|
||||
gdb_test "p fun4()" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4'}"
|
||||
gdb_test "p fun5()" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e'}"
|
||||
gdb_test "p fun6()" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F'}"
|
||||
gdb_test "p fun7()" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7'}"
|
||||
gdb_test "p fun8()" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8'}"
|
||||
gdb_test "p fun9()" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i'}"
|
||||
gdb_test "p fun10()" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J'}"
|
||||
gdb_test "p fun11()" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8', i = 57 '9', j = 65 'A', k = 66 'B'}"
|
||||
gdb_test "p fun12()" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J', k = 75 'K', l = 76 'L'}"
|
||||
gdb_test "p fun16()" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i', j = 106 'j', k = 107 'k', l = 108 'l', m = 109 'm', n = 110 'n', o = 111 'o', p = 112 'p'}"
|
||||
|
||||
# Now call the Fun functions to set the L* variables. This
|
||||
# tests that gdb properly passes structures to functions.
|
||||
gdb_test "p Fun1(foo1)" " = (void|0)"
|
||||
gdb_test "p Fun2(foo2)" " = (void|0)"
|
||||
gdb_test "p Fun3(foo3)" " = (void|0)"
|
||||
gdb_test "p Fun4(foo4)" " = (void|0)"
|
||||
gdb_test "p Fun5(foo5)" " = (void|0)"
|
||||
gdb_test "p Fun6(foo6)" " = (void|0)"
|
||||
gdb_test "p Fun7(foo7)" " = (void|0)"
|
||||
gdb_test "p Fun8(foo8)" " = (void|0)"
|
||||
gdb_test "p Fun9(foo9)" " = (void|0)"
|
||||
gdb_test "p Fun10(foo10)" " = (void|0)"
|
||||
gdb_test "p Fun11(foo11)" " = (void|0)"
|
||||
gdb_test "p Fun12(foo12)" " = (void|0)"
|
||||
gdb_test "p Fun16(foo16)" " = (void|0)"
|
||||
|
||||
# Now print the L* variables and examine their values.
|
||||
gdb_test "p L1" " = {a = 49 '1'}"
|
||||
gdb_test "p L2" " = {a = 97 'a', b = 98 'b'}"
|
||||
gdb_test "p L3" " = {a = 65 'A', b = 66 'B', c = 67 'C'}"
|
||||
gdb_test "p L4" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4'}"
|
||||
if {$gcc_compiled} then {
|
||||
setup_xfail "hppa*-*-*"
|
||||
}
|
||||
gdb_test "p L5" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e'}"
|
||||
if {$gcc_compiled} then {
|
||||
setup_xfail "hppa*-*-*"
|
||||
}
|
||||
gdb_test "p L6" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F'}"
|
||||
if {$gcc_compiled} then {
|
||||
setup_xfail "hppa*-*-*"
|
||||
}
|
||||
gdb_test "p L7" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7'}"
|
||||
gdb_test "p L8" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8'}"
|
||||
gdb_test "p L9" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i'}"
|
||||
gdb_test "p L10" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J'}"
|
||||
gdb_test "p L11" " = {a = 49 '1', b = 50 '2', c = 51 '3', d = 52 '4', e = 53 '5', f = 54 '6', g = 55 '7', h = 56 '8', i = 57 '9', j = 65 'A', k = 66 'B'}"
|
||||
gdb_test "p L12" " = {a = 65 'A', b = 66 'B', c = 67 'C', d = 68 'D', e = 69 'E', f = 70 'F', g = 71 'G', h = 72 'H', i = 73 'I', j = 74 'J', k = 75 'K', l = 76 'L'}"
|
||||
gdb_test "p L16" " = {a = 97 'a', b = 98 'b', c = 99 'c', d = 100 'd', e = 101 'e', f = 102 'f', g = 103 'g', h = 104 'h', i = 105 'i', j = 106 'j', k = 107 'k', l = 108 'l', m = 109 'm', n = 110 'n', o = 111 'o', p = 112 'p'}"
|
||||
}
|
||||
# Start with a fresh gdb.
|
||||
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
gdb_load ${binfile}
|
||||
|
||||
gdb_test "set print sevenbit-strings" "" ""
|
||||
gdb_test "set print address off" "" ""
|
||||
gdb_test "set width 0" "" ""
|
||||
|
||||
if [target_info exists gdb,cannot_call_functions] {
|
||||
setup_xfail "*-*-*" 2416
|
||||
fail "This target can not call functions"
|
||||
return 0
|
||||
}
|
||||
|
||||
if { ![runto_main] } then {
|
||||
gdb_suppress_tests;
|
||||
}
|
||||
|
||||
do_function_calls;
|
||||
|
||||
gdb_stop_suppressing_tests;
|
||||
|
||||
return 0
|
15
gdb/testsuite/gdb.base/sum.c
Normal file
15
gdb/testsuite/gdb.base/sum.c
Normal file
@ -0,0 +1,15 @@
|
||||
/* This is a sample program for the HP/DDE debugger. */
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int sum(int *list, int low, int high)
|
||||
#else
|
||||
int sum(list, low, high)
|
||||
int *list, low, high;
|
||||
#endif
|
||||
{
|
||||
int i = 0, s = 0;
|
||||
for (i = low; i <= high; i++)
|
||||
s += list[i];
|
||||
return(s);
|
||||
}
|
11
gdb/testsuite/gdb.base/vforked-prog.c
Normal file
11
gdb/testsuite/gdb.base/vforked-prog.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
int main (void)
|
||||
#else
|
||||
main()
|
||||
#endif
|
||||
{
|
||||
printf("Hello from vforked-prog...\n");
|
||||
return 0;
|
||||
}
|
12
gdb/testsuite/gdb.chill/xstruct-grt.ch
Normal file
12
gdb/testsuite/gdb.chill/xstruct-grt.ch
Normal file
@ -0,0 +1,12 @@
|
||||
pot1: MODULE
|
||||
|
||||
SYNMODE m_array1 = ARRAY (2:3) ulong;
|
||||
SYNMODE m_struct = STRUCT (f1 int,
|
||||
f2 REF m_array1,
|
||||
f3 m_array1);
|
||||
SYNMODE m_array3 = ARRAY (5:6) m_struct;
|
||||
SYNMODE m_array4 = ARRAY (7:8) ARRAY (9:10) m_struct;
|
||||
|
||||
GRANT all;
|
||||
|
||||
END pot1;
|
16
gdb/testsuite/gdb.chill/xstruct.ch
Normal file
16
gdb/testsuite/gdb.chill/xstruct.ch
Normal file
@ -0,0 +1,16 @@
|
||||
pottendo: MODULE
|
||||
|
||||
<> USE_SEIZE_FILE "xstruct-grt.grt" <>
|
||||
SEIZE m_array3;
|
||||
SEIZE m_array4;
|
||||
|
||||
SYNMODE m_x = STRUCT (i long,
|
||||
ar m_array3);
|
||||
SYNMODE m_y = STRUCT (i long,
|
||||
ar m_array4);
|
||||
|
||||
DCL x LONG;
|
||||
|
||||
x := 10;
|
||||
|
||||
END pottendo;
|
66
gdb/testsuite/gdb.chill/xstruct.exp
Normal file
66
gdb/testsuite/gdb.chill/xstruct.exp
Normal file
@ -0,0 +1,66 @@
|
||||
# Copyright (C) 1992, 1994, 1997 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 2 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, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# Please email any bugs, comments, and/or additions to this file to:
|
||||
# bug-gdb@prep.ai.mit.edu
|
||||
|
||||
# This file was written by Per Bothner. (bothner@cygnus.com)
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
if [skip_chill_tests] then { continue }
|
||||
|
||||
set testfile2 "xstruct-grt"
|
||||
set srcfile2 ${srcdir}/$subdir/${testfile2}.ch
|
||||
set objfile2 ${objdir}/$subdir/${testfile2}.o
|
||||
if { [compile "${srcfile2} -g -c -o ${objfile2}"] != "" } {
|
||||
perror "Couldn't compile ${srcfile2}"
|
||||
return -1
|
||||
}
|
||||
|
||||
set testfile "xstruct"
|
||||
set srcfile ${srcdir}/$subdir/${testfile}.ch
|
||||
set binfile ${objdir}/${subdir}/${testfile}.exe
|
||||
if { [compile "${srcfile} -g ${objfile2} -o ${binfile} ${CHILL_RT0} ${CHILL_LIB}"] != "" } {
|
||||
perror "Couldn't compile ${srcfile}"
|
||||
return -1
|
||||
}
|
||||
|
||||
proc do_tests {} {
|
||||
global prms_id bug_id subdir objdir srcdir binfile gdb_prompt
|
||||
|
||||
set prms_id 0
|
||||
set bug_id 0
|
||||
|
||||
# Start with a fresh gdb.
|
||||
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
gdb_load $binfile
|
||||
|
||||
gdb_test "set language chill" ""
|
||||
|
||||
gdb_test "set var \$i := m_x\[\]" ""
|
||||
gdb_test "print \$i" { = \[.i: 0, .ar: \[\(5:6\): \[.f1: 0, .f2: NULL, .f3: \[\(2:3\): 0\]\]\]\]}
|
||||
|
||||
gdb_test "set var \$j := m_y\[\]" ""
|
||||
gdb_test "print \$j" { = \[.i: 0, .ar: \[\(7:8\): \[\(9:10\): \[.f1: 0, .f2: NULL, .f3: \[\(2:3\): 0\]\]\]\]\]}
|
||||
}
|
||||
|
||||
do_tests
|
Loading…
x
Reference in New Issue
Block a user