new files -- part of HP merge.

This commit is contained in:
David Taylor 1999-01-11 05:36:48 +00:00
parent 65fedafeb8
commit d55ea55c19
45 changed files with 10789 additions and 0 deletions

View File

@ -0,0 +1,110 @@
void marker1()
{
return;
}
class A1 {
public:
int x;
int y;
};
class A2 {
public:
int x;
int y;
};
class A3 {
public:
int x;
int y;
};
class X : public A1, public A2 {
public:
int z;
};
class L : public A1 {
public:
int z;
};
class LV : public virtual A1 {
public:
int z;
};
class M : public A2 {
public:
int w;
};
class N : public L, public M {
public:
int r;
};
class K : public A1 {
public:
int i;
};
class KV : public virtual A1 {
public:
int i;
};
class J : public K, public L {
public:
int j;
};
class JV : public KV, public LV {
public:
int jv;
};
class JVA1 : public KV, public LV, public A1 {
public:
int jva1;
};
class JVA2 : public KV, public LV, public A2 {
public:
int jva2;
};
class JVA1V : public KV, public LV, public virtual A1 {
public:
int jva1v;
};
int main()
{
A1 a1;
A2 a2;
A3 a3;
X x;
L l;
M m;
N n;
K k;
J j;
JV jv;
JVA1 jva1;
JVA2 jva2;
JVA1V jva1v;
int i;
i += k.i + m.w + a1.x + a2.x + a3.x + x.z + l.z + n.r + j.j;
marker1();
}

View File

@ -0,0 +1,216 @@
# 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
# This file is part of the gdb testsuite
# tests relating to ambiguous class members
# Written by Satish Pai <pai@apollo.hp.com> 1997-07-28
# This file is part of the gdb testsuite
if $tracelevel then {
strace $tracelevel
}
#
# test running programs
#
set prms_id 0
set bug_id 0
set testfile "ambiguous"
set srcfile ${testfile}.cc
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile} "c++"] {
return -1;
}
if {[skip_hp_tests $gcc_compiled]} then { continue }
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
#
# set it up at a breakpoint so we can play with the variable values
#
if ![runto_main] then {
perror "couldn't run to breakpoint"
continue
}
send_gdb "break marker1\n" ; gdb_expect -re ".*$gdb_prompt $"
send_gdb "cont\n"
gdb_expect {
-re "Break.* marker1 \\(\\) at .*:$decimal.*$gdb_prompt $" {
send_gdb "up\n"
gdb_expect {
-re ".*$gdb_prompt $" { pass "up from marker1" }
timeout { fail "up from marker1" }
}
}
-re "$gdb_prompt $" { fail "continue to marker1" }
timeout { fail "(timeout) continue to marker1" }
}
# print out various class objects' members. The values aren't
# important, just check that the warning is emitted at the
# right times.
# X is derived from A1 and A2; both A1 and A2 have a member 'x'
send_gdb "print x.x\n"
gdb_expect {
-re "warning: x ambiguous; using X::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = 0\r\n$gdb_prompt $" {
pass "print x.x"
}
-re ".*$gdb_prompt $" { fail "print x.x" }
timeout { fail "(timeout) print x.x" }
}
# N is derived from A1 and A2, but not immediately -- two steps
# up in the hierarchy. Both A1 and A2 have a member 'x'.
send_gdb "print n.x\n"
gdb_expect {
-re "warning: x ambiguous; using N::L::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = 0\r\n$gdb_prompt $" {
pass "print n.x"
}
-re ".*$gdb_prompt $" { fail "print n.x" }
timeout { fail "(timeout) print n.x" }
}
# J is derived from A1 twice. A1 has a member x.
send_gdb "print j.x\n"
gdb_expect {
-re "warning: x ambiguous; using J::K::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = 0\r\n$gdb_prompt $" {
pass "print j.x"
}
-re ".*$gdb_prompt $" { fail "print j.x" }
timeout { fail "(timeout) print j.x" }
}
# JV is derived from A1 but A1 is a virtual base. Should not
# report an ambiguity in this case.
send_gdb "print jv.x\n"
gdb_expect {
-re "warning: x ambiguous.*Use a cast to disambiguate.\r\n\\$\[0-9\]* = 0\r\n$gdb_prompt $" {
fail "print jv.x (ambiguity reported)"
}
-re "\\$\[0-9\]* = 0\r\n$gdb_prompt $" { pass "print jv.x" }
-re ".*$gdb_prompt $" { fail "print jv.x (??)" }
timeout { fail "(timeout) print jv.x" }
}
# JVA1 is derived from A1; A1 occurs as a virtual base in two
# ancestors, and as a non-virtual immediate base. Ambiguity must
# be reported.
send_gdb "print jva1.x\n"
gdb_expect {
-re "warning: x ambiguous; using JVA1::KV::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = 0\r\n$gdb_prompt $" {
pass "print jva1.x"
}
-re ".*$gdb_prompt $" { fail "print jva1.x" }
timeout { fail "(timeout) print jva1.x" }
}
# JVA2 is derived from A1 & A2; A1 occurs as a virtual base in two
# ancestors, and A2 is a non-virtual immediate base. Ambiguity must
# be reported as A1 and A2 both have a member 'x'.
send_gdb "print jva2.x\n"
gdb_expect {
-re "warning: x ambiguous; using JVA2::KV::A1::x. Use a cast to disambiguate.\r\n\\$\[0-9\]* = 0\r\n$gdb_prompt $" {
pass "print jva2.x"
}
-re ".*$gdb_prompt $" { fail "print jva2.x" }
timeout { fail "(timeout) print jva2.x" }
}
# JVA1V is derived from A1; A1 occurs as a virtual base in two
# ancestors, and also as a virtual immediate base. Ambiguity must
# not be reported.
send_gdb "print jva1v.x\n"
gdb_expect {
-re "warning: x ambiguous.*Use a cast to disambiguate.\r\n\\$\[0-9\]* = 0\r\n$gdb_prompt $" {
fail "print jva1v.x (ambiguity reported)"
}
-re "\\$\[0-9\]* = 0\r\n$gdb_prompt $" { pass "print jva1v.x" }
-re ".*$gdb_prompt $" { fail "print jva1v.x (??)" }
timeout { fail "(timeout) print jva1v.x" }
}
# Now check for ambiguous bases.
# J is derived from A1 twice; report ambiguity if a J is
# cast to an A1.
send_gdb "print (A1)j\n"
gdb_expect {
-re "warning: A1 ambiguous; using J::K::A1. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = 0, y = 0\}\r\n$gdb_prompt $" {
pass "print (A1)j"
}
-re ".*$gdb_prompt $" { fail "print (A1)j" }
timeout { fail "(timeout) print (A1)j" }
}
# JV is derived from A1 twice, but A1 is a virtual base; should
# not report ambiguity when a JV is cast to an A1.
send_gdb "print (A1)jv\n"
gdb_expect {
-re "warning: A1 ambiguous.*Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = 0, y = 0\}\r\n$gdb_prompt $" {
fail "print (A1)jv (ambiguity reported)"
}
-re "\\$\[0-9\]* = \{x = 0, y = 0\}\r\n$gdb_prompt $" { pass "print (A1)jv" }
-re ".*$gdb_prompt $" { fail "print (A1)jv (??)" }
timeout { fail "(timeout) print (A1)jv" }
}
# JVA1 is derived from A1; A1 is a virtual base and also a
# non-virtual base. Must report ambiguity if a JVA1 is cast to an A1.
send_gdb "print (A1)jva1\n"
gdb_expect {
-re "warning: A1 ambiguous; using JVA1::KV::A1. Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = 0, y = 0\}\r\n$gdb_prompt $" {
pass "print (A1)jva1"
}
-re ".*$gdb_prompt $" { fail "print (A1)jva1" }
timeout { fail "(timeout) print (A1)jva1" }
}
# JVA1V is derived from A1; A1 is a virtual base indirectly
# and also directly; must not report ambiguity when a JVA1V is cast to an A1.
send_gdb "print (A1)jva1v\n"
gdb_expect {
-re "warning: A1 ambiguous.*Use a cast to disambiguate.\r\n\\$\[0-9\]* = \{x = 0, y = 0\}\r\n$gdb_prompt $" {
fail "print (A1)jva1v (ambiguity reported)"
}
-re "\\$\[0-9\]* = \{x = 0, y = 0\}\r\n$gdb_prompt $" { pass "print (A1)jva1v"
}
-re ".*$gdb_prompt $" { fail "print (A1)jva1v (??)" }
timeout { fail "(timeout) print (A1)jva1v" }
}

View File

@ -0,0 +1,416 @@
# 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
# are we on a target board
if ![isnative] then {
return
}
if { ![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"] } {
#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."
}
# 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."
}
#if { [compile "-E ${srcdir}/${subdir}/compiler.c >> ${objdir}/${subdir}/${testfile}.tmp"] != ""# } {
# perror "Couldn't make ${testfile}.tmp"
# return -1
#}
#execute_anywhere "mv ${objdir}/${subdir}/${testfile}.tmp ${binfile}.ci"
#source ${binfile}.ci
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.*Permission denied.*$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 [expr $timeout + 20]
send_gdb "file\n"
gdb_expect {
-re ".*gdb internal error.*$" {
fail "Internal error, prob. Memory corruption"
}
-re "No exec 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.
#
# execute_anywhere "kill -9 ${testpid}"
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 exec 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
#
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
#
# execute_anywhere "kill -9 ${testpid}"
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
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 "*-*-*"
}
return 0

View File

@ -0,0 +1,263 @@
# attach.exp -- Expect script to test attaching to a threaded pgm
# Copyright (C) 1992 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
# use this to debug:
#
#log_user 1
# Temporarily comment out - hanging
#return 0
if $tracelevel then {
strace $tracelevel
}
# Thread stuff is _slow_; prepare for long waits.
#
# Further, this test has some "null" lines designed
# to consume output from gdb that was too late to be
# matched (sequence is "gdb_test" sends; timeout and
# on to next send; result finally comes in; mismatch).
#
# The null command is 'gdb_test "p \$pc" ".*" ""'
# NOTE: this command undoes any up/down stuff!
#
proc pre_timeout { how_long } {
global timeout
set timeout [expr "$timeout + $how_long"]
}
proc post_timeout {} {
global timeout
global oldtimeout
set timeout $oldtimeout
gdb_test "p \$pc" ".*" ""
}
if { ![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"] } {
verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
return 0
}
# We used to wait 5 seconds , but tiamat is faster than
# hydra...or is it that the OS allocates time differently(?).
#
set delay 5
if { ![istarget "hppa*-*-hpux11.*"] } {
set delay 45
}
set testfile quicksort
set srcfile ${srcdir}/${subdir}/${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile}] {
return -1
}
set oldtimeout $timeout
#set timeout [expr "$timeout + 100"]
set oldverbose $verbose
#set verbose 40
# To build the executable we need to link against the thread library.
#
# cc -Ae -g -o quicksort -lpthread quicksort.c
#
#remote_exec build "${srcfile} -Ae -g -lpthread -o ${binfile}"
#gdb_compile "${srcfile} -Ae -g -lpthread -o ${binfile}"
if {$gcc_compiled == 0} {
set additional_flags "additional_flags=-Ae"
} else {
set additional_flags ""
}
if { [gdb_compile "${srcdir}/${subdir}/${testfile}.c" "${binfile}.o" object [list debug $additional_flags]] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
remote_exec build "ld /usr/ccs/lib/crt0.o ${binfile}.o -lcl -lpthread -lc /opt/langtools/lib/end.o -o ${binfile}"
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
# Start the application running and get its pid.
# Then we wait for it to get started and attach.
#
set testpid [eval exec $binfile 1 &]
exec sleep $delay
# Now attach to the file.
#
pre_timeout 100
gdb_test "attach $testpid" ".*Attaching to process.*Reading symbols from.*done.*" "attach to target"
post_timeout
# Wait for things to quiesce.
#
exec sleep 0
send_gdb "bt\n"
set do_return 0
set do_go_to_118 0
pre_timeout 400
gdb_expect {
-re ".*sleep.*work_init.*main.*$gdb_prompt $" {
pass "at expected location"
}
-re ".*drand48.*$gdb_prompt $" {
set do_go_to_118 1
}
-re ".*pthread_mutex_lock.*$gdb_prompt $" {
set do_go_to_118 1
}
-re ".*pthread_mutex_unlock.*$gdb_prompt $" {
set do_go_to_118 1
}
-re ".*main.*$gdb_prompt $" {
set do_go_to_118 1
}
-re ".*No stack.*$gdb_prompt $" {
fail "Failed attach, change wait amount down, rest would fail"
set do_return 1
}
-re ".*$gdb_prompt $" {
# Who knows?
#
set do_go_to_118 1
}
timeout {
set do_return 1
fail "timeout on bt, avoiding rest of test"
}
}
post_timeout
# Too late; just give up.
#
if { $do_return } {
set timeout $oldtimeout
set verbose $oldverbose
return 0
}
# Maybe too early--set a temp break and continue.
# We have to set this on both paths, so that we can
# know what numbers breakpoints will be.
#
gdb_test "tb 118" ".*Breakpoint 1.*118.*" ""
if { $do_go_to_118 } {
pre_timeout 100
send_gdb "c\n"
gdb_expect {
-re ".*at.*118.*118.*$gdb_prompt $" {
# Ok, just keep going
}
-re ".*Program exited.*$gdb_prompt $" {
fail "Attached too late, set wait amount downwards"
set timeout $oldtimeout
set verbose $oldverbose
return 0
}
-re ".*$gdb_prompt $" {
fail "Unexpected result on attach"
set timeout $oldtimeout
set verbose $oldverbose
return 0
}
timeout {
fail "timeout on continue "
}
}
post_timeout
}
# Look at the threads.
#
pre_timeout 100
gdb_test "info thread" ".*7.*6.*5.*4.*3.*2.*\\\* 1.*thread.*" "first info thread"
post_timeout
# We expect to be inside the "sleep" call, so check that.
#
if { [expr "!$do_go_to_118"] } {
gdb_test "up" ".*\#1.*nanosleep.*" "up 1"
gdb_test "up" ".*\#2.*sleep.*" "up 2"
pre_timeout 100
gdb_test "up" ".*\#3.*work_init.*$testfile.*c:118.*sleep.*" "up 3"
post_timeout
} else {
send_user "Skipped three tests\n"
}
# Get out of that call.
#
gdb_test "b 120" ".*Breakpoint 2.*120.*" "set bp"
pre_timeout 100
gdb_test "c" ".*Breakpoint 2.*at.*120.*" "hit bp"
post_timeout
# Look at the threads.
#
pre_timeout 100
gdb_test "info thread" ".*7.*6.*5.*4.*3.*2.*1.*thread.*$testfile.*c*120.*" "2nd info thread"
post_timeout
# Do some more stuff, to make sure we can
#
gdb_test "thread 3" ".*Switching to.*thread.*ksleep.*" "switch thread"
gdb_test "up" ".*_lwp_cond_timedwait.*" "up 5"
gdb_test "up" ".*pthread_cond_wait.*" "up 6"
gdb_test "up" ".*\#3.*worker.*144.*" "up 7"
gdb_test "up" ".*__pthread_exit.*" "up 8"
gdb_test "up" ".*Initial.*cannot go up.*" "found thread base"
gdb_test "b 145 thr 3" ".*Breakpoint 3.*145.*" "thread-specific bp"
gdb_test "i b" ".*2.*breakpoint.*at.*120.*3.*breakpoint.*at.*145 thread 3.*" "show thread-specific bp"
gdb_test "del 2" ".*" ""
gdb_test "c" ".*Breakpoint 3.*145.*" "hit thread-specific bp"
gdb_test "i th" ".*\\\* 3.*145.*" "at correct thread"
pre_timeout 100
gdb_test "n" ".*146.*" "next from thread-specific bp"
post_timeout
gdb_test "d 3" ".*" ""
gdb_test "c" ".*Program exited normally\..*" "run to finish"
# Done!
#
gdb_exit
set timeout $oldtimeout
set verbose $oldverbose
# execute_anywhere "rm -f ${binfile}"
#
return 0

View File

@ -0,0 +1,859 @@
# Copyright (C) 1992, 1994, 1995, 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 Fred Fish. (fnf@cygnus.com)
set ws "\[\r\n\t \]+"
if $tracelevel then {
strace $tracelevel
}
# Check to see if we have an executable to test. If not, then either we
# haven't tried to compile one, or the compilation failed for some reason.
# In either case, just notify the user and skip the tests in this file.
set testfile "misc-hp"
set srcfile ${testfile}.cc
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile} "c++"] {
return -1;
}
if {[skip_hp_tests $gcc_compiled]} then { continue }
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
#
# Test ptype of class objects.
#
proc test_ptype_class_objects {} {
global gdb_prompt
global ws
# Note that struct members are public by default, so we don't print
# "public:" for the public members of structs.
# Accept it as an expected failure if gdb just fails to distinguish between
# class and struct, and everything else is OK.
send_gdb "ptype struct default_public_struct\n"
gdb_expect {
-re "type = struct default_public_struct \{${ws}int a;${ws}int b;\r\n\}\r\n$gdb_prompt $" {
pass "ptype struct default_public_struct"
}
-re "type = class default_public_struct \{\r\n.*int a;${ws}int b;\r\n.*\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype struct default_public_struct"
}
-re ".*$gdb_prompt $" { fail "ptype struct default_public_struct" }
timeout { fail "ptype struct default_public_struct (timeout)" ; return }
}
# Note that struct members are public by default, so we don't print
# "public:" for the public members of structs.
# Accept it as an expected failure if gdb just fails to distinguish between
# class and struct, and everything else is OK.
send_gdb "ptype struct explicit_public_struct\n"
gdb_expect {
-re "type = struct explicit_public_struct \{${ws}int a;${ws}int b;\r\n.*\}\r\n$gdb_prompt $" {
pass "ptype struct explicit_public_struct"
}
-re "type = class explicit_public_struct \{\r\n.*int a;${ws}int b;\r\n.*\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype struct explicit_public_struct"
}
-re ".*$gdb_prompt $" { fail "ptype struct explicit_public_struct" }
timeout { fail "ptype struct explicit_public_struct (timeout)" ; return }
}
# Accept it as an expected failure if gdb just fails to distinguish between
# class and struct, and everything else is OK.
setup_xfail_format "DWARF 1"
send_gdb "ptype struct protected_struct\n"
gdb_expect {
-re "type = struct protected_struct \{${ws}protected:${ws}int a;${ws}int b;\r\n\}\r\n$gdb_prompt $" {
pass "ptype struct protected_struct (FIXME)"
}
-re "type = class protected_struct \{${ws}protected:${ws}int a;${ws}int b;\r\n.*\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype struct protected_struct (FIXME)"
}
-re ".*$gdb_prompt $" { fail "ptype struct protected_struct" }
timeout { fail "ptype struct protected_struct (timeout)" ; return }
}
# Accept it as an expected failure if gdb just fails to distinguish between
# class and struct, and everything else is OK.
setup_xfail_format "DWARF 1"
send_gdb "ptype struct private_struct\n"
gdb_expect {
-re "type = struct private_struct \{${ws}private:${ws}int a;${ws}int b;\r\n\}\r\n$gdb_prompt $" {
pass "ptype struct private_struct (FIXME)"
}
-re "type = class private_struct \{${ws}private:${ws}int a;${ws}int b;\r\n.*\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype struct private_struct (FIXME)"
}
-re ".*$gdb_prompt $" { fail "ptype struct private_struct" }
timeout { fail "ptype struct private_struct (timeout)" ; return }
}
# Accept it as an expected failure if gdb just fails to distinguish between
# class and struct, and everything else is OK.
setup_xfail_format "DWARF 1"
send_gdb "ptype struct mixed_protection_struct\n"
gdb_expect {
-re "type = struct mixed_protection_struct \{${ws}int a;${ws}int b;${ws}private:${ws}int c;${ws}int d;${ws}protected:${ws}int e;${ws}int f;${ws}public:${ws}int g;${ws}private:${ws}int h;${ws}protected:${ws}int i;\[\r\n\]+\}\[\r\n\]+$gdb_prompt $" {
pass "ptype struct mixed_protection_struct (FIXME)"
}
-re "type = struct mixed_protection_struct \{\r\n\[ \]*public:\r\n\[ \]*int a;\r\n\[ \]*int b;\r\n\[ \]*private:\r\n\[ \]*int c;\r\n\[ \]*int d;\r\n\[ \]*protected:\r\n\[ \]*int e;\r\n\[ \]*int f;\r\n\[ \]*public:\r\n\[ \]*int g;\r\n\[ \]*private:\r\n\[ \]*int h;\r\n\[ \]*protected:\r\n\[ \]*int i;\r\n.*\}\r\n$gdb_prompt $" {
pass "ptype struct mixed_protection_struct (extra public)"
}
-re "type = class mixed_protection_struct \{${ws}public:${ws}int a;${ws}int b;${ws}private:${ws}int c;${ws}int d;${ws}protected:${ws}int e;${ws}int f;${ws}public:${ws}int g;${ws}private:${ws}int h;${ws}protected:${ws}int i;\r\n.*\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype struct mixed_protection_struct (FIXME)"
}
-re ".*$gdb_prompt $" { fail "ptype struct mixed_protection_struct" }
timeout { fail "ptype struct mixed_protection_struct (timeout)" ; return }
}
# Accept it as an expected failure if gdb just fails to distinguish between
# class and struct, and everything else is OK.
send_gdb "ptype class public_class\n"
gdb_expect {
-re "type = class public_class \{${ws}public:${ws}int a;${ws}int b;\r\n.*\}\r\n$gdb_prompt $" {
pass "ptype class public_class (FIXME)"
}
-re "type = struct public_class \{${ws}int a;${ws}int b;\r\n\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class public_class (FIXME)"
}
-re ".*$gdb_prompt $" { fail "ptype class public_class" }
timeout { fail "ptype class public_class (timeout)" ; return }
}
send_gdb "ptype class protected_class\n"
gdb_expect {
-re "type = class protected_class \{${ws}protected:${ws}int a;${ws}int b;\r\n.*\}\r\n$gdb_prompt $" {
pass "ptype class protected_class"
}
-re "type = struct protected_class \{${ws}int a;${ws}int b;\r\n\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class protected_class"
}
-re ".*$gdb_prompt $" { fail "ptype class protected_class" }
timeout { fail "ptype class protected_class (timeout)" ; return }
}
# Accept it as an expected failure if gdb just emits a superflous "private:"
# attribute, since classes default to private and for consistency with
# structs (where we don't print the "public:" attribute) we don't print
# the "private:" attribute.
setup_xfail_format "DWARF 1"
send_gdb "ptype class default_private_class\n"
gdb_expect {
-re "type = class default_private_class \{${ws}int a;${ws}int b;\r\n.*\}\r\n$gdb_prompt $" {
pass "ptype class default_private_class (FIXME)"
}
-re "type = class default_private_class \{${ws}private:${ws}int a;${ws}int b;\r\n.*\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class default_private_class (FIXME)"
}
-re ".*$gdb_prompt $" { fail "ptype class default_private_class" }
timeout { fail "ptype class default_private_class (timeout)" ; return }
}
send_gdb "ptype class explicit_private_class\n"
gdb_expect {
-re "type = class explicit_private_class \{${ws}private:${ws}int a;${ws}int b;\r\n.*\}\r\n$gdb_prompt $" {
pass "ptype class explicit_private_class"
}
-re "type = class explicit_private_class \{\r\n\[ \]*int a;\r\n\[ \]*int b;\r\n.*\}\r\n$gdb_prompt $" {
pass "ptype class explicit_private_class (OK for HP aCC)"
}
-re "type = struct explicit_private_class \{${ws}int a;${ws}int b;\r\n.*\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class explicit_private_class"
}
-re ".*$gdb_prompt $" { fail "ptype class explicit_private_class" }
timeout { fail "ptype class explicit_private_class (timeout)" ; return }
}
send_gdb "ptype class mixed_protection_class\n"
gdb_expect {
-re "type = class mixed_protection_class \{${ws}public:${ws}int a;${ws}int b;${ws}private:${ws}int c;${ws}int d;${ws}protected:${ws}int e;${ws}int f;${ws}public:${ws}int g;${ws}private:${ws}int h;${ws}protected:${ws}int i;\r\n.*\}\r\n$gdb_prompt $" {
pass "ptype class mixed_protection_class"
}
-re "type = struct mixed_protection_class \{${ws}int a;${ws}int b;${ws}int c;${ws}int d;${ws}int e;${ws}int f;${ws}int g;${ws}int h;${ws}int i;\r\n.*\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class mixed_protection_class"
}
-re ".*$gdb_prompt $" { fail "ptype class mixed_protection_class" }
timeout { fail "ptype class mixed_protection_class (timeout)" ; return }
}
# This class does not use any C++-specific features, so it's fine for
# it to print as "struct".
send_gdb "ptype class A\n"
gdb_expect {
-re "type = (class|struct) A \{(${ws}public:|)${ws}int a;${ws}int x;((${ws}A & operator=\\(A const &\\);)|(${ws}A\\(A const &\\);)|(${ws}A\\(void\\);))*${ws}\}\r\n$gdb_prompt $" {
pass "ptype class A"
}
-re ".*$gdb_prompt $" {
fail "ptype class A"
}
timeout {
fail "ptype class A (timeout)"
return
}
}
setup_xfail_format "DWARF 1"
send_gdb "ptype class B\n"
gdb_expect {
-re "type = class B : public A \{${ws}public:${ws}int b;${ws}int x;${ws}B & operator=\\(B const &\\);${ws}B\\(B const &\\);${ws}B\\(void\\);${ws}\}\r\n$gdb_prompt $" {
pass "ptype class B"
}
-re "type = class B : public A \{${ws}public:${ws}int b;${ws}int x;((${ws}B & operator=\\(B const &\\);)|(${ws}B\\(B const &\\);)|(${ws}B\\(void\\);))*${ws}\}\r\n$gdb_prompt $" {
pass "ptype class B (obsolescent gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype class B"
}
timeout {
fail "ptype class B (timeout)"
return
}
}
setup_xfail_format "DWARF 1"
send_gdb "ptype class C\n"
gdb_expect {
-re "type = class C : public A \{${ws}public:${ws}int c;${ws}int x;${ws}C & operator=\\(C const &\\);${ws}C\\(C const &\\);${ws}C\\(void\\);${ws}\}\r\n$gdb_prompt $" {
pass "ptype class C"
}
-re "type = class C : public A \{${ws}public:${ws}int c;${ws}int x;((${ws}C & operator=\\(C const &\\);)|(${ws}C\\(C const &\\);)|(${ws}C\\(void\\);))*${ws}\}\r\n$gdb_prompt $" {
pass "ptype class C (obsolescent gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype class C"
}
timeout {
fail "ptype class C (timeout)"
return
}
}
setup_xfail_format "DWARF 1"
send_gdb "ptype class D\n"
gdb_expect {
-re "type = class D : public B, public C \{${ws}public:${ws}int d;${ws}int x;${ws}D & operator=\\(D const &\\);${ws}D\\(D const &\\);${ws}D\\(void\\);${ws}\}\r\n$gdb_prompt $" {
pass "ptype class D"
}
-re "type = class D : public B, public C \{${ws}public:${ws}int d;${ws}int x;((${ws}D & operator=\\(D const &\\);)|(${ws}D\\(D const &\\);)|(${ws}D\\(void\\);))*${ws}\}\r\n$gdb_prompt $" {
pass "ptype class D (obsolescent gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype class D"
}
timeout {
fail "ptype class D (timeout)"
return
}
}
setup_xfail_format "DWARF 1"
send_gdb "ptype class E\n"
gdb_expect {
-re "type = class E : public D \{${ws}public:${ws}int e;${ws}int x;${ws}E & operator=\\(E const &\\);${ws}E\\(E const &\\);${ws}E\\(void\\);${ws}\}\r\n$gdb_prompt $" {
pass "ptype class E"
}
-re "type = class E : public D \{${ws}public:${ws}int e;${ws}int x;((${ws}E & operator=\\(E const &\\);)|(${ws}E\\(E const &\\);)|(${ws}E\\(void\\);))*${ws}\}\r\n$gdb_prompt $" {
pass "ptype class E"
}
-re ".*$gdb_prompt $" {
fail "ptype class E"
}
timeout {
fail "ptype class E (timeout)"
return
}
}
send_gdb "ptype class vA\n"
gdb_expect {
-re "type = (class|struct) vA \{(${ws}public:|)${ws}int va;${ws}int vx;${ws}vA & operator=\\(vA const &\\);${ws}vA\\(vA const &\\);${ws}vA\\(void\\);${ws}\}\r\n$gdb_prompt $" {
pass "ptype class vA"
}
-re "type = (class|struct) vA \{(${ws}public:|)${ws}int va;${ws}int vx;((${ws}vA & operator=\\(vA const &\\);)|(${ws}vA\\(vA const &\\);)|(${ws}vA\\(void\\);))*${ws}\}\r\n$gdb_prompt $" {
pass "ptype class vA (obsolescent gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype class vA"
}
timeout {
fail "ptype class vA (timeout)"
return
}
}
# Accept the form with embedded GNU style mangled virtual table constructs
# for now, but with a FIXME. At some future point, gdb should use a
# portable representation for the virtual table constructs.
setup_xfail_format "DWARF 1"
send_gdb "ptype class vB\n"
gdb_expect {
-re "type = class vB : public virtual vA \{${ws}private:${ws}vA \\*_vb.vA;${ws}public:${ws}int vb;${ws}int vx;${ws}vB & operator=\\(vB const &\\);${ws}vB\\(int, vB const &\\);${ws}vB\\(int\\);${ws}\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class vB (FIXME: non-portable virtual table constructs)"
}
-re "type = class vB : public virtual vA \{\r\n\[ \]*public:\r\n\[ \]*int vb;\r\n\[ \]*int vx;\[\r\n\t \]+\}\r\n$gdb_prompt $" {
pass "ptype class vB (aCC)"
}
-re "type = class vB : public virtual vA \{${ws}private:${ws}vA \\*_vb.vA;${ws}public:${ws}int vb;${ws}int vx;((${ws}vB & operator=\\(vB const &\\);)|(${ws}vB\\(int, vB const &\\);)|(${ws}vB\\(int\\);))*${ws}\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class vB (FIXME) (obsolescent gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype class vB"
}
timeout {
fail "ptype class vB (timeout)"
return
}
}
# Accept the form with embedded GNU style mangled virtual table constructs
# for now, but with a FIXME. At some future point, gdb should use a
# portable representation for the virtual table constructs.
setup_xfail_format "DWARF 1"
send_gdb "ptype class vC\n"
gdb_expect {
-re "type = class vC : public virtual vA \{${ws}private:${ws}vA \\*_vb.vA;${ws}public:${ws}int vc;${ws}int vx;${ws}vC & operator=\\(vC const &\\);${ws}vC\\(int, vC const &\\);${ws}vC\\(int\\);${ws}\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class vC (FIXME: non-portable virtual table constructs)"
}
-re "type = class vC : public virtual vA \{\r\n\[ \]*public:\r\n\[ \]*int vc;\r\n\[ \]*int vx;\[\r\n\t \]+\}\r\n$gdb_prompt $" {
pass "ptype class vC (aCC)"
}
-re "type = class vC : public virtual vA \{${ws}private:${ws}vA \\*_vb.vA;${ws}public:${ws}int vc;${ws}int vx;((${ws}vC & operator=\\(vC const &\\);)|(${ws}vC\\(int, vC const &\\);)|(${ws}vC\\(int\\);))*${ws}\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class vC (FIXME) (obsolescent gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype class vC"
}
timeout {
fail "ptype class vC (timeout)"
return
}
}
# Accept the form with embedded GNU style mangled virtual table constructs
# for now, but with a FIXME. At some future point, gdb should use a
# portable representation for the virtual table constructs.
setup_xfail_format "DWARF 1"
send_gdb "ptype class vD\n"
gdb_expect {
-re "type = class vD : public virtual vB, public virtual vC \{${ws}private:${ws}vC \\*_vb.vC;${ws}vB \\*_vb.vB;${ws}public:${ws}int vd;${ws}int vx;${ws}vD & operator=\\(vD const &\\);${ws}vD\\(int, vD const &\\);${ws}vD\\(int\\);${ws}\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class vD (FIXME: non-portable virtual table constructs)"
}
-re "type = class vD : public virtual vB, public virtual vC \{\r\n\[ \]*public:\r\n\[ \]*int vd;\r\n\[ \]*int vx;\[\r\n\t \]+\}\r\n$gdb_prompt $" {
pass "ptype class vD (aCC)"
}
-re "type = class vD : public virtual vB, public virtual vC \{${ws}private:${ws}vC \\*_vb.vC;${ws}vB \\*_vb.vB;${ws}public:${ws}int vd;${ws}int vx;((${ws}vD & operator=\\(vD const &\\);)|(${ws}vD\\(int, vD const &\\);)|(${ws}vD\\(int\\);))*${ws}\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class vD (FIXME) (obsolescent gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype class vD"
}
timeout {
fail "ptype class vD (timeout)"
return
}
}
# Accept the form with embedded GNU style mangled virtual table constructs
# for now, but with a FIXME. At some future point, gdb should use a
# portable representation for the virtual table constructs.
setup_xfail_format "DWARF 1"
send_gdb "ptype class vE\n"
gdb_expect {
-re "type = class vE : public virtual vD \{${ws}private:${ws}vD \\*_vb.vD;${ws}public:${ws}int ve;${ws}int vx;${ws}vE & operator=\\(vE const &\\);${ws}vE\\(int, vE const &\\);${ws}vE\\(int\\);${ws}\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class vE (FIXME: non-portable virtual table constructs)"
}
-re "type = class vE : public virtual vD \{\r\n\[ \]*public:\r\n\[ \]*int ve;\r\n\[ \]*int vx;\[\r\n\t \]+\}\r\n$gdb_prompt $" {
pass "ptype class vE (aCC)"
}
-re "type = class vE : public virtual vD \{${ws}private:${ws}vD \\*_vb.vD;${ws}public:${ws}int ve;${ws}int vx;((${ws}vE & operator=\\(vE const &\\);)|(${ws}vE\\(int, vE const &\\);)|(${ws}vE\\(int\\);))*${ws}\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class vE (FIXME) (obsolescent gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype class vE"
}
timeout {
fail "ptype class vE (timeout)"
return
}
}
setup_xfail_format "DWARF 1"
send_gdb "ptype class Base1\n"
gdb_expect {
-re "type = class Base1 \{${ws}public:${ws}int x;${ws}Base1 & operator=\\(Base1 const &\\);${ws}Base1\\(Base1 const &\\);${ws}Base1\\(int\\);${ws}\}\r\n$gdb_prompt $" {
pass "ptype class Base1"
}
-re "type = class Base1 \{${ws}public:${ws}int x;((${ws}Base1 & operator=\\(Base1 const &\\);)|(${ws}Base1\\(Base1 const &\\);)|(${ws}Base1\\(int\\);))*${ws}\}\r\n$gdb_prompt $" {
pass "ptype class Base1 (obsolescent gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype class Base1"
}
timeout {
fail "ptype class Base1 (timeout)"
return
}
}
setup_xfail_format "DWARF 1"
send_gdb "ptype class Foo\n"
gdb_expect {
-re "type = class Foo \{\r\n\[ \]*public:\r\n\[ \]*int x;\r\n\[ \]*int y;\r\n\[ \]*static int st;\r\n\r\n\[ \]*Foo\\(int, int\\);\r\n\[ \]*int operator!.void.;\r\n\[ \]*operator int.void.;\r\n\[ \]*int times.int.;\r\n\}\r\n$gdb_prompt $" {
pass "ptype class Foo(aCC)"
}
-re "type = class Foo \{${ws}public:${ws}int x;${ws}int y;${ws}static int st;${ws}Foo & operator=\\(Foo const &\\);${ws}Foo\\(Foo const &\\);${ws}Foo\\(int, int\\);${ws}int operator!\\(void\\);${ws}int operator int\\(void\\);${ws}int times\\(int\\);${ws}\}\r\n$gdb_prompt $" {
pass "ptype class Foo"
}
-re "type = class Foo \{${ws}public:${ws}int x;${ws}int y;${ws}static int st;((${ws}Foo & operator=\\(Foo const &\\);)|(${ws}Foo\\(Foo const &\\);)|(${ws}Foo\\(int, int\\);)|(${ws}int operator!\\(void\\);)|(${ws}int operator int\\(void\\);)|(${ws}int times\\(int\\);))*${ws}\}\r\n$gdb_prompt $" {
pass "ptype class Foo (obsolescent gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype class Foo"
}
timeout {
fail "ptype class Foo (timeout)"
return
}
}
setup_xfail_format "DWARF 1"
send_gdb "ptype class Bar\n"
gdb_expect {
-re "type = class Bar : public Base1, public Foo \{${ws}public:${ws}int z;${ws}Bar & operator=\\(Bar const &\\);${ws}Bar\\(Bar const &\\);${ws}Bar\\(int, int, int\\);${ws}\}\r\n$gdb_prompt $" {
pass "ptype class Bar"
}
-re "type = class Bar : public Base1, public Foo \{${ws}public:${ws}int z;((${ws}Bar & operator=\\(Bar const &\\);)|(${ws}Bar\\(Bar const &\\);)|(${ws}Bar\\(int, int, int\\);))*${ws}\}\r\n$gdb_prompt $" {
pass "ptype class Bar (obsolescent gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype class Bar"
}
timeout {
fail "ptype class Bar (timeout)"
return
}
}
}
#
# Test simple access to class members.
#
proc test_non_inherited_member_access {} {
global gdb_prompt
# Print non-inherited members of g_A.
gdb_test "print g_A.a" ".* = 1" "g_A.a incorrect"
gdb_test "print g_A.x" ".* = 2" "g_A.x incorrect"
# Print non-inherited members of g_B.
gdb_test "print g_B.b" ".* = 5" "g_B.b incorrect"
gdb_test "print g_B.x" ".* = 6" "g_B.x incorrect"
# Print non-inherited members of g_C.
gdb_test "print g_C.c" ".* = 9" "g_C.c incorrect"
gdb_test "print g_C.x" ".* = 10" "g_C.x incorrect"
# Print non-inherited members of g_D.
gdb_test "print g_D.d" ".* = 19" "g_D.d incorrect"
gdb_test "print g_D.x" ".* = 20" "g_D.x incorrect"
# Print non-inherited members of g_E.
gdb_test "print g_E.e" ".* = 31" "g_E.e incorrect"
gdb_test "print g_E.x" ".* = 32" "g_E.x incorrect"
}
#
# Try access to non-members that are members of another class.
# Should give errors.
#
proc test_wrong_class_members {} {
global gdb_prompt
gdb_test "print g_A.b" "There is no member( or method|) named b." "print g_A.b should be error"
gdb_test "print g_B.c" "There is no member( or method|) named c." "print g_B.c should be error"
gdb_test "print g_B.d" "There is no member( or method|) named d." "print g_B.d should be error"
gdb_test "print g_C.b" "There is no member( or method|) named b." "print g_C.b should be error"
gdb_test "print g_C.d" "There is no member( or method|) named d." "print g_C.d should be error"
gdb_test "print g_D.e" "There is no member( or method|) named e." "print g_D.e should be error"
}
#
# Try access to non-members that are not members of any class.
# Should give errors.
#
proc test_nonexistant_members {} {
global gdb_prompt
gdb_test "print g_A.y" "There is no member( or method|) named y." "print g_A.y should be error"
gdb_test "print g_B.z" "There is no member( or method|) named z." "print g_B.z should be error"
gdb_test "print g_C.q" "There is no member( or method|) named q." "print g_C.q should be error"
gdb_test "print g_D.p" "There is no member( or method|) named p." "print g_D.p should be error"
}
#
# Pointers to class members
#
proc test_pointers_to_class_members {} {
global gdb_prompt
global decimal
gdb_test "print Bar::z" ".* = .int\[ \]*\[( \]*Bar::&\[)\]+\[ \]*Bar::z" "print Bar::z"
gdb_test "print &Foo::x" ".* = .int\[ \]*\[( \]*Foo::\[*)\]+\[ \]*&Foo::x" "print &Foo::x"
gdb_test "print (int)&Foo::x" ".* = 0" "print (int)&Foo::x"
send_gdb "print (int)&Bar::y == 2*sizeof(int)\n"
gdb_expect {
-re ".* = true\r\n$gdb_prompt $" {
pass "print (int)&Bar::y == 2*sizeof(int)"
}
-re "There is no field named y.*$gdb_prompt $" {
setup_xfail "*-*-*"
fail "print (int)&Bar::y == 2*sizeof(int)"
}
-re ".*$gdb_prompt $" { fail "print (int)&Bar::y == 2*sizeof(int)" }
timeout { fail "print (int)&Bar::y == 2*sizeof(int) (timeout)" ; return }
}
send_gdb "next\n"
setup_xfail "*-*-*"
gdb_expect {
-re "$decimal\[ \t\]+inheritance3 \[)(\]+;\r\n$gdb_prompt $" {}
-re ".*$gdb_prompt $" { fail "next to inheritance3" ; return }
}
clear_xfail "*-*-*"
setup_xfail_format "DWARF 1"
gdb_test "print (int)pmi == sizeof(int)" ".* = false" "print (int)pmi == sizeof(int)"
}
#
# Test static members.
#
proc test_static_members {} {
global gdb_prompt
global hex
send_gdb "print Foo::st\n"
gdb_expect {
-re ".* = 100\r\n$gdb_prompt $" {
pass "print Foo::st"
}
-re "There is no field named st.*$gdb_prompt $" {
setup_xfail "*-*-*"
fail "print Foo::st"
}
-re ".*$gdb_prompt $" { fail "print Foo::st" }
timeout { fail "print Foo::st (timeout)" ; return }
}
send_gdb "set foo.st = 200\n"
gdb_expect {
-re ".*$gdb_prompt $" {}
}
send_gdb "print bar.st\n"
gdb_expect {
-re ".* = 200\r\n$gdb_prompt $" {
pass "print bar.st"
}
-re "There is no member( or method|) named st.*$gdb_prompt $" {
setup_xfail "*-*-*"
fail "print bar.st"
}
-re ".*$gdb_prompt $" { fail "print bar.st" }
timeout { fail "print bar.st (timeout)" ; return }
}
send_gdb "print &foo.st\n"
gdb_expect {
-re ".* = .int \[*)\]+ $hex\r\n$gdb_prompt $" {
pass "print &foo.st"
}
-re "There is no member( or method|) named st.*$gdb_prompt $" {
setup_xfail "*-*-*"
fail "print &foo.st"
}
-re ".*$gdb_prompt $" { fail "print &foo.st" }
timeout { fail "print &foo.st (timeout)" ; return }
}
set got_bar_st 0
send_gdb "print &Bar::st\n"
gdb_expect {
-re ".* = .int \[*)\]+ $hex\r\n$gdb_prompt $" {
pass "print &Bar::st"
set got_bar_st 1
}
-re "There is no field named st.*$gdb_prompt $" {
setup_xfail "*-*-*"
fail "print &Bar::st"
}
-re ".*$gdb_prompt $" { fail "print &Bar::st" }
timeout { fail "print &Bar::st (timeout)" ; return }
}
if $got_bar_st then {
gdb_test "print *\$" ".* = 200" "print *\$"
}
gdb_test "set print static-members off" ""
gdb_test "print csi" \
"{x = 10, y = 20}" \
"print csi without static members"
gdb_test "print cnsi" \
"{x = 30, y = 40}" \
"print cnsi without static members"
gdb_test "set print static-members on" ""
setup_xfail_format "DWARF 1"
gdb_test "print csi" \
"{x = 10, y = 20, static null = {x = 0, y = 0, static null = <same as static member of an already seen type>}}" \
"print csi with static members"
setup_xfail_format "DWARF 1"
gdb_test "print cnsi" \
"{x = 30, y = 40, static null = {x = 0, y = 0, static null = <same as static member of an already seen type>, static yy = {z = 5, static xx = {x = 1, y = 2, static null = <same as static member of an already seen type>, static yy = <same as static member of an already seen type>}}}, static yy = <same as static member of an already seen type>}" \
"print cnsi with static members"
}
proc do_tests {} {
global prms_id
global bug_id
global subdir
global objdir
global srcdir
global binfile
global 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
send_gdb "set language c++\n"
gdb_expect -re "$gdb_prompt $"
send_gdb "set width 0\n"
gdb_expect -re "$gdb_prompt $"
# Get the debug format for the compiled test case.
if [ runto_main ] then {
get_debug_format
}
test_ptype_class_objects
if [ runto 'inheritance2(void)' ] then {
test_non_inherited_member_access
test_wrong_class_members
test_nonexistant_members
}
if [istarget "mips-idt-*"] then {
# Restart because IDT/SIM runs out of file descriptors.
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $binfile
}
if [ runto_main ] then {
test_pointers_to_class_members
test_static_members
}
if [istarget "mips-idt-*"] then {
# Restart because IDT/SIM runs out of file descriptors.
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $binfile
}
if [ runto marker_reg1 ] then {
gdb_test "finish" "Run till exit from.*" "finish from marker_reg1"
send_gdb "print v.method ()\n"
gdb_expect {
-re "= 82.*$gdb_prompt $" {
pass "calling method for small class"
}
-re "Address requested for identifier .v. which is in a register.*$gdb_prompt $" {
setup_xfail "*-*-*" 2972
fail "calling method for small class"
}
-re ".*$gdb_prompt $" { fail "calling method for small class" }
timeout { fail "calling method for small class (timeout)" }
eof { fail "calling method for small class (eof)" }
}
}
}
do_tests
# Some additional tests for enums inside classes
# set a breakpoint and go there
send_gdb "break 498\n"
gdb_expect {
-re "Breakpoint \[0-9\] at.*$gdb_prompt $" { pass "set break 498" }
-re "$gdb_prompt $" { fail "set break 498" }
timeout { fail "(timeout) set break 498" }
}
send_gdb "continue\n"
gdb_expect {
-re "Continuing\\.\r\n\r\nBreakpoint \[0-9\]*, main....at ${srcdir}/${subdir}/${srcfile}:498\r\n498.*\r\n$gdb_prompt $" { pass "continue" }
-re "$gdb_prompt $" { fail "continue" }
timeout { fail "(timeout) continue" }
}
# print the object
send_gdb "print obj_with_enum\n"
gdb_expect {
-re "\\$\[0-9\]* = \\{priv_enum = red, x = 0\\}.*$gdb_prompt $" { pass "print obj_with_enum (1)" }
-re "$gdb_prompt $" { fail "print obj_with_enum (1)" }
timeout { fail "(timeout) print obj_with_enum (1)" }
}
send_gdb "next\n"
gdb_expect {
-re "$gdb_prompt $" { pass "next" }
timeout { fail "(timeout) next" }
}
# print the object again
send_gdb "print obj_with_enum\n"
gdb_expect {
-re "\\$\[0-9\]* = \\{priv_enum = green, x = 0\\}.*$gdb_prompt $" { pass "print obj_with_enum (2)" }
-re "$gdb_prompt $" { fail "print obj_with_enum (2)" }
timeout { fail "(timeout) print obj_with_enum (2)" }
}
# print out the enum member
send_gdb "print obj_with_enum.priv_enum\n"
gdb_expect {
-re "\\$\[0-9\]* = green.*$gdb_prompt $" { pass "print obj_with_enum.priv_enum" }
-re "$gdb_prompt $" { fail "print obj_with_enum.priv_enum" }
timeout { fail "(timeout) print obj_with_enum.priv_enum" }
}
# ptype on the enum member
send_gdb "ptype obj_with_enum.priv_enum\n"
gdb_expect {
-re "type = enum ClassWithEnum::PrivEnum \\{red, green, blue, yellow = 42\\}.*$gdb_prompt $" { pass "ptype obj_with_enum.priv_enum" }
-re "$gdb_prompt $" { fail "ptype obj_with_enum.priv_enum" }
timeout { fail "(timeout) ptype obj_with_enum.priv_enum" }
}
# ptype on the object
send_gdb "ptype obj_with_enum\n"
gdb_expect {
-re "type = class ClassWithEnum \\{\r\n\[ \t\]*public:\r\n\[ \t\]*enum ClassWithEnum::PrivEnum priv_enum;\r\n\[ \t\]*int x;\r\n\\}\r\n$gdb_prompt $" { pass "ptype obj_with_enum" }
-re "$gdb_prompt $" { fail "ptype obj_with_enum" }
timeout { fail "(timeout) ptype obj_with_enum" }
}
send_gdb "print (ClassWithEnum::PrivEnum) 42\n"
gdb_expect {
-re "\\$\[0-9\]* = yellow.*$gdb_prompt $" { pass "print (ClassWithEnum::PrivEnum) 42" }
-re "$gdb_prompt $" { fail "print (ClassWithEnum::PrivEnum) 42" }
timeout { fail "(timeout) print (ClassWithEnum::PrivEnum) 42" }
}
send_gdb "maint demangle inheritance1__Fv\n"
gdb_expect {
-re "inheritance1\\(void\\).*$gdb_prompt $" { pass "demangle" }
-re ".*$gdb_prompt $" { fail "demangle" }
timeout { fail "(timeout) demangle" }
}

View File

@ -0,0 +1,29 @@
template<class T> T add(T v1, T v2)
{
T v3;
v3 = v1;
v3 += v2;
return v3;
}
int main()
{
char c;
int i;
float f;
extern void add1();
extern void subr2();
extern void subr3();
c = 'a';
i = 2;
f = 4.5;
c = add(c, c);
i = add(i, i);
f = add(f, f);
add1();
subr2();
subr3();
}

View File

@ -0,0 +1,16 @@
template<class T> T add(T v1, T v2);
void add1()
{
char c;
int i;
float f;
c = 'b';
i = 3;
f = 6.5;
c = add(c, c);
i = add(i, i);
f = add(f, f);
}

View File

@ -0,0 +1,22 @@
template<class T> T add2(T v1, T v2)
{
T v3;
v3 = v1;
v3 += v2;
return v3;
}
void subr2()
{
char c;
int i;
float f;
c = 'b';
i = 3;
f = 6.5;
c = add2(c, c);
i = add2(i, i);
f = add2(f, f);
}

View File

@ -0,0 +1,33 @@
template<class T> T add3(T v1, T v2)
{
T v3;
v3 = v1;
v3 += v2;
return v3;
}
template<class T> T add4(T v1, T v2)
{
T v3;
v3 = v1;
v3 += v2;
return v3;
}
void subr3()
{
char c;
int i;
float f;
c = 'b';
i = 3;
f = 6.5;
c = add3(c, c);
i = add3(i, i);
f = add3(f, f);
c = add4(c, c);
i = add4(i, i);
f = add4(f, f);
}

View File

@ -0,0 +1,269 @@
# 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
# This file is part of the gdb testsuite
# file written by Elena Zannoni (ezannoni@cygnus.com)
#
# source files ctti-add.cc, ctti-add1.cc, ctti-add2.cc, ctti-add3.cc
#
if $tracelevel then {
strace $tracelevel
}
# Check to see if we have an executable to test. If not, then either we
# haven't tried to compile one, or the compilation failed for some reason.
# In either case, just notify the user and skip the tests in this file.
set testfile "ctti-add"
set srcfile ${testfile}.cc
set srcfile1 ${testfile}1.cc
set srcfile2 ${testfile}2.cc
set srcfile3 ${testfile}3.cc
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile} "c++"] {
return -1;
}
if {[skip_hp_tests $gcc_compiled]} then { continue }
#if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${srcdir}/${subdir}/${srcfile1} ${srcdir}/${subdir}/${srcfile2} ${srcdir}/${subdir}/${srcfile3}" "${binfile}" executable {debug c++}] != "" } {
# gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
#}
set cmdline "$CXX ${srcdir}/${subdir}/${srcfile} ${srcdir}/${subdir}/${srcfile1} ${srcdir}/${subdir}/${srcfile2} ${srcdir}/${subdir}/${srcfile3} -g -o ${binfile}"
remote_exec build $cmdline
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
if ![runto_main] then {
perror "couldn't run to breakpoint"
continue
}
send_gdb "n\n"
gdb_expect {
-re "$decimal.*i = 2;.*$gdb_prompt $" {
pass "next "
}
-re ".*$gdb_prompt $" { fail "next " }
timeout { fail "next " }
}
send_gdb "n\n"
gdb_expect {
-re "$decimal.*f = 4.5;.*$gdb_prompt $" {
pass "next "
}
-re ".*$gdb_prompt $" { fail "next " }
timeout { fail "next " }
}
send_gdb "n\n"
gdb_expect {
-re "$decimal.*c = add\\(c, c\\);.*$gdb_prompt $" {
pass "next "
}
-re ".*$gdb_prompt $" { fail "next " }
timeout { fail "next " }
}
send_gdb "n\n"
gdb_expect {
-re "$decimal.*i = add\\(i, i\\);.*$gdb_prompt $" {
pass "next "
}
-re ".*$gdb_prompt $" { fail "next " }
timeout { fail "next " }
}
send_gdb "n\n"
gdb_expect {
-re "$decimal.*f = add\\(f, f\\);.*$gdb_prompt $" {
pass "next "
}
-re ".*$gdb_prompt $" { fail "next " }
timeout { fail "next " }
}
send_gdb "n\n"
gdb_expect {
-re "$decimal.*add1\\(\\);.*$gdb_prompt $" {
pass "next "
}
-re ".*$gdb_prompt $" { fail "next " }
timeout { fail "next " }
}
send_gdb "print c\n"
gdb_expect {
-re ".$decimal = -62.*\r\n$gdb_prompt $" {
pass "print value of c"
}
-re ".*$gdb_prompt $" { fail "print value of c" }
timeout { fail "(timeout) print value of c" }
}
send_gdb "print f\n"
gdb_expect {
-re ".$decimal = 9\r\n$gdb_prompt $" {
pass "print value of f"
}
-re ".*$gdb_prompt $" { fail "print value of f" }
timeout { fail "(timeout) print value of f" }
}
send_gdb "print i\n"
gdb_expect {
-re ".$decimal = 4\r\n$gdb_prompt $" {
pass "print value of i"
}
-re ".*$gdb_prompt $" { fail "print value of i" }
timeout { fail "(timeout) print value of i" }
}
send_gdb "print add<int>(2,2)\n"
gdb_expect {
-re ".$decimal = 4\r\n$gdb_prompt $" {
pass "print value of add<int>(2,2)"
}
-re ".*$gdb_prompt $" { fail "print value of add<int>(2,2)" }
timeout { fail "(timeout) print value of add<int>(2,2)" }
}
send_gdb "print add<float>(2.3,2.3)\n"
gdb_expect {
-re ".$decimal = 4\\.5\[0-9\]+\r\n$gdb_prompt $" {
pass "print value of add<float>(2.3,2.3)"
}
-re ".*$gdb_prompt $" { fail "print value of add<float>(2.3,2.3)" }
timeout { fail "(timeout) print value of add<float>(2.3,2.3)" }
}
send_gdb "print add<char>('A','A')\n"
gdb_expect {
-re ".$decimal = -126.*202.\r\n$gdb_prompt $" {
pass "print value of add<char>('A','A')"
}
-re ".*$gdb_prompt $" { fail "print value of add<char>('A','A')" }
timeout { fail "(timeout) print value of add<char>('A','A')" }
}
send_gdb "print add2<int>(2,2)\n"
gdb_expect {
-re ".$decimal = 4\r\n$gdb_prompt $" {
pass "print value of add2<int>(2,2)"
}
-re ".*$gdb_prompt $" { fail "print value of add2<int>(2,2)" }
timeout { fail "(timeout) print value of add2<int>(2,2)" }
}
send_gdb "print add2<float>(2.3,2.3)\n"
gdb_expect {
-re ".$decimal = 4\\.5\[0-9\]+\r\n$gdb_prompt $" {
pass "print value of add2<float>(2.3,2.3)"
}
-re ".*$gdb_prompt $" { fail "print value of add2<float>(2.3,2.3)" }
timeout { fail "(timeout) print value of add2<float>(2.3,2.3)" }
}
send_gdb "print add2<char>('A','A')\n"
gdb_expect {
-re ".$decimal = -126.*202.\r\n$gdb_prompt $" {
pass "print value of add2<char>('A','A')"
}
-re ".*$gdb_prompt $" { fail "print value of add2<char>('A','A')" }
timeout { fail "(timeout) print value of add2<char>('A','A')" }
}
send_gdb "print add3<int>(2,2)\n"
gdb_expect {
-re ".$decimal = 4\r\n$gdb_prompt $" {
pass "print value of add3<int>(2,2)"
}
-re ".*$gdb_prompt $" { fail "print value of add3<int>(2,2)" }
timeout { fail "(timeout) print value of add3<int>(2,2)" }
}
send_gdb "print add3<float>(2.3,2.3)\n"
gdb_expect {
-re ".$decimal = 4\\.5\[0-9\]+\r\n$gdb_prompt $" {
pass "print value of add3<float>(2.3,2.3)"
}
-re ".*$gdb_prompt $" { fail "print value of add3<float>(2.3,2.3)" }
timeout { fail "(timeout) print value of add3<float>(2.3,2.3)" }
}
send_gdb "print add3<char>('A','A')\n"
gdb_expect {
-re ".$decimal = -126.*202.\r\n$gdb_prompt $" {
pass "print value of add3<char>('A','A')"
}
-re ".*$gdb_prompt $" { fail "print value of add3<char>('A','A')" }
timeout { fail "(timeout) print value of add3<char>('A','A')" }
}
send_gdb "print add4<int>(2,2)\n"
gdb_expect {
-re ".$decimal = 4\r\n$gdb_prompt $" {
pass "print value of add4<int>(2,2)"
}
-re ".*$gdb_prompt $" { fail "print value of add4<int>(2,2)" }
timeout { fail "(timeout) print value of add4<int>(2,2)" }
}
send_gdb "print add4<float>(2.3,2.3)\n"
gdb_expect {
-re ".$decimal = 4\\.5\[0-9\]+\r\n$gdb_prompt $" {
pass "print value of add4<float>(2.3,2.3)"
}
-re ".*$gdb_prompt $" { fail "print value of add4<float>(2.3,2.3)" }
timeout { fail "(timeout) print value of add4<float>(2.3,2.3)" }
}
send_gdb "print add4<char>('A','A')\n"
gdb_expect {
-re ".$decimal = -126.*202.\r\n$gdb_prompt $" {
pass "print value of add4<char>('A','A')"
}
-re ".*$gdb_prompt $" { fail "print value of add4<char>('A','A')" }
timeout { fail "(timeout) print value of add4<char>('A','A')" }
}
gdb_exit
return 0

View File

@ -0,0 +1,217 @@
# 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."
}
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").
#
#
proc 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 "Reading symbols from.*done.*$gdb_prompt $" {
verbose "\t\tLoaded $arg into the $GDB"
send_gdb "exec-file $arg\n"
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
}
}
}
#
#test_breakpoints
#
proc test_breakpoints { } {
gdb_test "stop in main" "Breakpoint.*at.*: file.*average\.c, line 31\."
gdb_test "status" "Num.*Type.*Disp.*Enb.*Address.*What\r\n1\[ \r\]+breakpoint\[ \r\]+keep y.*in main at.*average\.c:31.*"
gdb_test "stop at 36" "Breakpoint.*at.*: file.*average\.c, line 36.*"
gdb_test "stop in 36" "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:17\r\n17\[ \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
gdb_load ${binfile}
send_gdb "set width 0\n"
gdb_expect -re "$gdb_prompt $"
test_breakpoints
test_assign
test_whereis
gdb_test "file average.c:1" "1\[ \t\]+/. This is a sample program.*"
test_func
gdb_exit
set GDBFLAGS $saved_gdbflags
return 0

View File

@ -0,0 +1,48 @@
// Test file for exception handling support.
#include <iostream.h>
int foo (int i)
{
if (i < 32)
throw (int) 13;
else
return i * 2;
}
extern "C" int bar (int k, unsigned long eharg, int flag);
int bar (int k, unsigned long eharg, int flag)
{
cout << "k is " << k << " eharg is " << eharg << " flag is " << flag << endl;
return 1;
}
int main()
{
int j;
try {
j = foo (20);
}
catch (int x) {
cout << "Got an except " << x << endl;
}
try {
try {
j = foo (20);
}
catch (int x) {
cout << "Got an except " << x << endl;
throw;
}
}
catch (int y) {
cout << "Got an except (rethrown) " << y << endl;
}
// Not caught
foo (20);
}

View File

@ -0,0 +1,408 @@
# Copyright (C) 1997, 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
#
# tests for exception-handling support
# Written by Satish Pai <pai@apollo.hp.com> 1997-07-23
# This file is part of the gdb testsuite
# Note: These tests are geared to the HP aCC compiler,
# which has an idiosyncratic way of emitting debug info
# for exceptions -- it uses a callback mechanism, which
# is different from the way g++ records exception info
# for debugging
# The tests are in two parts; the first part deals with
# statically linked (archive-bound) executables, and the
# second part repeats those tests with dynamically linked
# (shared bound) executables. (In the latter case we use
# a different mechanism to get the address of the notification
# hook in the C++ support library.) The tests themselves are
# the same in both parts.
#
# IMPORTANT:
# ---------
# IF YOU CHANGE A TEST IN ONE PART MAKE SURE YOU CHANGE IT
# --------------------------------------------------------
# IN THE OTHER PART TOO!
# ----------------------
if $tracelevel then {
strace $tracelevel
}
#
# test running programs
#
# Part I : Archive-bound executables
# ----------------------------------
set testfile "exception"
set srcfile ${testfile}.cc
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile} "c++"] {
return -1;
}
if {[skip_hp_tests $gcc_compiled]} then { continue }
set cmdline "$CXX ${srcdir}/${subdir}/${srcfile} +A -Wl,-a,archive -g -o ${binfile}"
remote_exec build $cmdline
# Start with a fresh gdb
set prms_id 0
set bug_id 0
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
if ![runto_main] then {
perror "couldn't run to breakpoint"
continue
}
# Set a catch catchpoint
send_gdb "catch catch\n"
gdb_expect {
-re "Catchpoint \[0-9\]* \\(catch\\)\r\n$gdb_prompt $" {
pass "catch catch (static executable)"
}
-re ".*$gdb_prompt $" { fail "catch catch (static executable)" }
timeout { fail "(timeout) catch catch (static executable)" }
}
# Set a throw catchpoint
send_gdb "catch throw\n"
gdb_expect {
-re "Catchpoint \[0-9\]* \\(throw\\)\r\n$gdb_prompt $" {
pass "catch throw (static executable)"
}
-re ".*$gdb_prompt $" { fail "catch throw (static executable)" }
timeout { fail "(timeout) catch throw (static executable)" }
}
# The catchpoints should be listed in the list of breakpoints.
send_gdb "info break\n"
gdb_expect {
-re ".*\[0-9\]*\[ \]*catch catch\[ \]*keep y\[ \]*exception catch\[ \]*\r\n\[0-9\]*\[ \]*catch throw\[ \]*keep y\[ \]*exception throw\[ \]*\r\n$gdb_prompt $" {
pass "info break with catchpoints (static executable)"
}
-re ".*$gdb_prompt $" { fail "info break (static executable)" }
timeout { fail "(timeout) info break (static executable)" }
}
# Info catch currently does not work with HP aCC. No easy way to
# list the active handlers on the stack.
send_gdb "info catch\n"
gdb_expect {
-re "Info catch not supported with this target/compiler combination.\r\n$gdb_prompt $" {
pass "info catch (static executable)"
}
-re ".*$gdb_prompt $" { fail "info catch (static executable)" }
timeout { fail "(timeout) info catch (static executable)" }
}
# Get the first exception thrown
send_gdb "continue\n"
gdb_expect {
-re "Continuing.*Catchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:28\r\n.*$gdb_prompt $" {
pass "caught a throw (static executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch a throw (static executable)" }
timeout { fail "(timeout) after continue -- didn't catch a throw? (static executable)" }
}
send_gdb "backtrace\n"
gdb_expect {
-re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=__EH_NOTIFY_THROW.*\r\n#2\[ \]*$hex in __eh_notify_throw.*\r\n#3\[ \]*$hex in foo \\(i=20\\) at .*exception\\.cc:8\r\n#4\[ \]*$hex in main.* at .*exception\\.cc:26\r\n$gdb_prompt $" {
pass "backtrace after throw (static executable)"
}
-re ".*$gdb_prompt $" { fail "backtrace after throw (static executable)" }
timeout { fail "(timeout) backtrace after throw (static executable)" }
}
# Now intercept it when it is caught.
send_gdb "continue\n"
gdb_expect {
-re "Continuing.*Catchpoint \[0-9\]* \\(exception caught\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:28\r\n.*$gdb_prompt $" {
pass "caught a catch (static executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch a catch (static executable)" }
timeout { fail "(timeout) after continue -- didn't catch a catch? (static executable)" }
}
send_gdb "backtrace\n"
gdb_expect {
-re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=__EH_NOTIFY_CATCH.*\r\n.*\r\n#3\[ \]*$hex in __throw__.*\r\n#4\[ \]*$hex in foo \\(i=20\\) at .*exception.cc:8\r\n#5\[ \]*$hex in main.* at .*exception.cc:26\r\n$gdb_prompt $" {
pass "backtrace after catch (static executable)"
}
-re ".*$gdb_prompt $" { fail "backtrace after catch (static executable)" }
timeout { fail "(timeout) backtrace after catch (static executable)" }
}
send_gdb "continue\n"
gdb_expect {
-re "Continuing\\.\r\nGot.*\r\nCatchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:36\r\n.*$gdb_prompt $" {
pass "caught a throw (2) (static executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch a throw (2) (static executable)" }
timeout { fail "(timeout) after continue -- didn't catch a throw (2)? (static executable)" }
}
send_gdb "continue\n"
gdb_expect {
-re "Continuing.*Catchpoint \[0-9\]* \\(exception caught\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:36\r\n.*$gdb_prompt $" {
pass "caught a catch (2) (static executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch a catch (2) (static executable)" }
timeout { fail "(timeout) after continue -- didn't catch a catch (2)? (static executable)" }
}
# Now the exception will be rethrown.
send_gdb "continue\n"
gdb_expect {
-re "Continuing\\.\r\nGot.*\r\nCatchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:38, catch location .*exception\\.cc:41\r\n.*$gdb_prompt $" {
pass "caught a rethrow (static executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch a rethrow (static executable)" }
timeout { fail "(timeout) after continue -- didn't catch a rethrow? (static executable)" }
}
send_gdb "continue\n"
gdb_expect {
-re "Continuing.*Catchpoint \[0-9\]* \\(exception caught\\), throw location.*exception\\.cc:38, catch location .*exception\\.cc:41\r\n.*$gdb_prompt $" {
pass "caught a catch (3) (static executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch a catch (3) (static executable)" }
timeout { fail "(timeout) after continue -- didn't catch a catch (3)? (static executable)" }
}
send_gdb "backtrace\n"
gdb_expect {
-re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=__EH_NOTIFY_CATCH.*\r\n.*\r\n#3\[ \]*$hex in __rethrow.*\r\n#4\[ \]*$hex in main.* at .*exception\\.cc:38\r\n#5\[ \]*$hex in foo \\(i=20\\) at .*exception.cc:8\r\n#6\[ \]*$hex in main.* at .*exception.cc:34\r\n$gdb_prompt $" {
pass "backtrace after catch (3) (static executable)"
}
-re ".*$gdb_prompt $" { fail "backtrace after catch (3) (static executable)" }
timeout { fail "(timeout) backtrace after catch (3) (static executable)" }
}
# Now the exception will be thrown, but not catch-able anywhere.
send_gdb "continue\n"
gdb_expect {
-re "Continuing\\.\r\nGot.*\r\nCatchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:8, catch location unknown\r\n.*$gdb_prompt $" {
pass "caught an uncatchable throw (static executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch an uncatchable throw (static executable)" }
timeout { fail "(timeout) after continue -- didn't catch an uncatchable throw? (static executable)" }
}
# Part II : Shared-bound executables
# ----------------------------------
# Start with a fresh gdb
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
set prms_id 0
set bug_id 0
set testfile "exception"
set srcfile ${testfile}.cc
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will a
utomatically fail."
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
if ![runto_main] then {
perror "couldn't run to breakpoint"
continue
}
# Set a catch catchpoint
send_gdb "catch catch\n"
gdb_expect {
-re "Catchpoint \[0-9\]* \\(catch\\)\r\n$gdb_prompt $" {
pass "catch catch (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "catch catch (dynamic executable)" }
timeout { fail "(timeout) catch catch (dynamic executable)" }
}
# Set a throw catchpoint
send_gdb "catch throw\n"
gdb_expect {
-re "Catchpoint \[0-9\]* \\(throw\\)\r\n$gdb_prompt $" {
pass "catch throw (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "catch throw (dynamic executable)" }
timeout { fail "(timeout) catch throw (dynamic executable)" }
}
# The catchpoints should be listed in the list of breakpoints.
send_gdb "info break\n"
gdb_expect {
-re ".*\[0-9\]*\[ \]*catch catch\[ \]*keep y\[ \]*exception catch\[ \]*\r\n\[0-9\]*\[ \]*catch throw\[ \]*keep y\[ \]*exception throw\[ \]*\r\n$gdb_prompt $" {
pass "info break with catchpoints (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "info break (dynamic executable)" }
timeout { fail "(timeout) info break (dynamic executable)" }
}
# Info catch currently does not work with HP aCC. No easy way to
# list the active handlers on the stack.
send_gdb "info catch\n"
gdb_expect {
-re "Info catch not supported with this target/compiler combination.\r\n$gdb_prompt $" {
pass "info catch (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "info catch (dynamic executable)" }
timeout { fail "(timeout) info catch (dynamic executable)" }
}
# Get the first exception thrown
send_gdb "continue\n"
gdb_expect {
-re "Continuing.*Catchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:28\r\n.*$gdb_prompt $" {
pass "caught a throw (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch a throw (dynamic executable)" }
timeout { fail "(timeout) after continue -- didn't catch a throw? (dynamic executable)" }
}
send_gdb "backtrace\n"
gdb_expect {
-re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=__EH_NOTIFY_THROW.*\r\n#2\[ \]*$hex in __eh_notify_throw.*\r\n#3\[ \]*$hex in foo \\(i=20\\) at .*exception\\.cc:8\r\n#4\[ \]*$hex in main.* at .*exception\\.cc:26\r\n$gdb_prompt $" {
pass "backtrace after throw (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "backtrace after throw (dynamic executable)" }
timeout { fail "(timeout) backtrace after throw (dynamic executable)" }
}
# Now intercept it when it is caught.
send_gdb "continue\n"
gdb_expect {
-re "Continuing.*Catchpoint \[0-9\]* \\(exception caught\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:28\r\n.*$gdb_prompt $" {
pass "caught a catch (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch a catch (dynamic executable)" }
timeout { fail "(timeout) after continue -- didn't catch a catch? (dynamic executable)" }
}
send_gdb "backtrace\n"
gdb_expect {
-re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=__EH_NOTIFY_CATCH.*\r\n.*\r\n#3\[ \]*$hex in __throw__.*\r\n#4\[ \]*$hex in foo \\(i=20\\) at .*exception.cc:8\r\n#5\[ \]*$hex in main.* at .*exception.cc:26\r\n$gdb_prompt $" {
pass "backtrace after catch (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "backtrace after catch (dynamic executable)" }
timeout { fail "(timeout) backtrace after catch (dynamic executable)" }
}
send_gdb "continue\n"
gdb_expect {
-re "Continuing\\.\r\nGot.*\r\nCatchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:36\r\n.*$gdb_prompt $" {
pass "caught a throw (2) (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch a throw (2) (dynamic executable)" }
timeout { fail "(timeout) after continue -- didn't catch a throw (2)? (dynamic executable)" }
}
send_gdb "continue\n"
gdb_expect {
-re "Continuing.*Catchpoint \[0-9\]* \\(exception caught\\), throw location.*exception\\.cc:8, catch location .*exception\\.cc:36\r\n.*$gdb_prompt $" {
pass "caught a catch (2) (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch a catch (2) (dynamic executable)" }
timeout { fail "(timeout) after continue -- didn't catch a catch (2)? (dynamic executable)" }
}
# Now the exception will be rethrown.
send_gdb "continue\n"
gdb_expect {
-re "Continuing\\.\r\nGot.*\r\nCatchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:38, catch location .*exception\\.cc:41\r\n.*$gdb_prompt $" {
pass "caught a rethrow (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch a rethrow (dynamic executable)" }
timeout { fail "(timeout) after continue -- didn't catch a rethrow? (dynamic executable)" }
}
send_gdb "continue\n"
gdb_expect {
-re "Continuing.*Catchpoint \[0-9\]* \\(exception caught\\), throw location.*exception\\.cc:38, catch location .*exception\\.cc:41\r\n.*$gdb_prompt $" {
pass "caught a catch (3) (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch a catch (3) (dynamic executable)" }
timeout { fail "(timeout) after continue -- didn't catch a catch (3)? (dynamic executable)" }
}
send_gdb "backtrace\n"
gdb_expect {
-re "#0\[ \]*__d_eh_break.*\r\n#1\[ \]*$hex in __d_eh_notify_callback \\(eh_type=__EH_NOTIFY_CATCH.*\r\n.*\r\n#3\[ \]*$hex in __rethrow.*\r\n#4\[ \]*$hex in main.* at .*exception\\.cc:38\r\n#5\[ \]*$hex in foo \\(i=20\\) at .*exception.cc:8\r\n#6\[ \]*$hex in main.* at .*exception.cc:34\r\n$gdb_prompt $" {
pass "backtrace after catch (3) (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "backtrace after catch (3) (dynamic executable)" }
timeout { fail "(timeout) backtrace after catch (3) (dynamic executable)" }
}
# Now the exception will be thrown, but not catch-able anywhere.
send_gdb "continue\n"
gdb_expect {
-re "Continuing\\.\r\nGot.*\r\nCatchpoint \[0-9\]* \\(exception thrown\\), throw location.*exception\\.cc:8, catch location unknown\r\n.*$gdb_prompt $" {
pass "caught an uncatchable throw (dynamic executable)"
}
-re ".*$gdb_prompt $" { fail "didn't catch an uncatchable throw (dynamic executable)" }
timeout { fail "(timeout) after continue -- didn't catch an uncatchable throw? (dynamic executable)" }
}

View File

@ -0,0 +1,35 @@
#include <stdio.h>
int global_i = 100;
main ()
{
int local_j = global_i+1;
int local_k = local_j+1;
printf ("follow-exec is about to execlp(execd-program)...\n");
execlp ("gdb.hp/execd-program",
"gdb.hp/execd-program",
"execlp arg1 from follow-exec",
(char *)0);
printf ("follow-exec is about to execl(execd-program)...\n");
execl ("gdb.hp/execd-program",
"gdb.hp/execd-program",
"execl arg1 from follow-exec",
"execl arg2 from follow-exec",
(char *)0);
{
static char * argv[] = {
"gdb.hp/execd-program",
"execv arg1 from follow-exec",
0};
printf ("follow-exec is about to execv(execd-program)...\n");
execv ("gdb.hp/execd-program", argv);
}
}

View File

@ -0,0 +1,412 @@
# 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
# are we on a target board
if ![isnative] then {
return
}
if {![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"]} {
#setup_xfail "*-*.*"
return 0
}
set testfile "foll-exec"
set testfile2 "execd-program"
set srcfile ${testfile}.c
set srcfile2 ${testfile2}.c
set binfile ${objdir}/${subdir}/${testfile}
set binfile2 ${objdir}/${subdir}/${testfile2}
# build the first test case
#if { [compile "-g -DNO_PROTOTYPES ${srcdir}/${subdir}/${srcfile2} -o ${binfile2} "] != "" } {
# perror "Couldn't compile ${srcfile2}"
# return -1
#}
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 { [compile "-g ${srcdir}/${subdir}/${srcfile} -o ${binfile} "] != "" } {
# execute_anywhere "rm -f ${objdir}/${subdir}/${testfile}.tmp"
# built the second test case since we can't use prototypes
# warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES"
# execute_anywhere "echo set prototypes 0 > ${objdir}/${subdir}/${testfile}.tmp"
# if { [compile "-g -DNO_PROTOTYPES ${srcdir}/${subdir}/${srcfile} -o ${binfile} "] != "" } {
# perror "Couldn't compile ${testfile}.c"
# return -1
# }
#}
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 {
setup_xfail "*-*-*"
}
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 "12.*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}:17.*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 "20.*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"}
}
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"}
}
# 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}:17.*$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 19\n"
gdb_expect {
-re "Breakpoint .*file .*${srcfile}, line 19.*$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 19\n"
gdb_expect {
-re "main.* at .*${srcfile}:19.*$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}:17.*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 "20.*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 33\n"
gdb_expect {
-re "Breakpoint .*file .*${srcfile}, line 33.*$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 33\n"
gdb_expect {
-re "main.* at .*${srcfile}:33.*$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}:17.*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 "20.*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} (4th 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}:17.*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

View File

@ -0,0 +1,25 @@
#include <stdio.h>
void callee (i)
int i;
{
printf("callee: %d\n", i);
}
main ()
{
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); */
}
}

View File

@ -0,0 +1,385 @@
# 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
# are we on a target board
if ![isnative] then {
return
}
if {![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"]} {
#setup_xfail "*-*.*"
return 0
}
set testfile "foll-fork"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
# build the first test case
#if { [compile "-g ${srcdir}/${subdir}/${srcfile} -o ${binfile} "] != "" } {
# execute_anywhere "rm -f ${objdir}/${subdir}/${testfile}.tmp"
# built the second test case since we can't use prototypes
# warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES"
# execute_anywhere "echo set prototypes 0 > ${objdir}/${subdir}/${testfile}.tmp"
# if { [compile "-g -DNO_PROTOTYPES ${srcdir}/${subdir}/${srcfile} -o ${binfile} "] != "" } {
# perror "Couldn't compile ${testfile}.c"
# return -1
# }
#}
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 {
setup_xfail "*-*-*"
}
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 15\n"
gdb_expect {
-re "Breakpoint.*, line 15.*$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 .*15.*$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 15\n"
gdb_expect {
-re "Breakpoint.*, line 15.*$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 .*15.*$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

View File

@ -0,0 +1,15 @@
#include <stdio.h>
main ()
{
int pid;
pid = vfork ();
if (pid == 0) {
printf ("I'm the child!\n");
execlp ("gdb.hp/vforked-program", "gdb.hp/vforked-program", (char *)0);
}
else {
printf ("I'm the proud parent of child #%d!\n", pid);
}
}

View File

@ -0,0 +1,381 @@
# 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
# are we on a target board
if ![isnative] then {
return
}
if {![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"]} {
#setup_xfail "*-*.*"
return 0
}
set testfile "foll-vfork"
set testfile2 "vforked-program"
set srcfile ${testfile}.c
set srcfile2 ${testfile2}.c
set binfile ${objdir}/${subdir}/${testfile}
set binfile2 ${objdir}/${subdir}/${testfile2}
# build the first test case
#execute_anywhere "echo set prototypes 1 > ${objdir}/${subdir}/${testfile}.tmp"
#if { [compile "-g -DNO_PROTOTYPES ${srcdir}/${subdir}/${srcfile2} -o ${binfile2} "] != "" } {
# perror "Couldn't compile ${srcfile2}"
# return -1
#}
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 { [compile "-g ${srcdir}/${subdir}/${srcfile} -o ${binfile} "] != "" } {
# execute_anywhere "rm -f ${objdir}/${subdir}/${testfile}.tmp"
# built the second test case since we can't use prototypes
# warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES"
# execute_anywhere "echo set prototypes 0 > ${objdir}/${subdir}/${testfile}.tmp"
# if { [compile "-g -DNO_PROTOTYPES ${srcdir}/${subdir}/${srcfile} -o ${binfile} "] != "" } {
# perror "Couldn't compile ${testfile}.c"
# return -1
# }
#}
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 {
setup_xfail "*-*-*"
}
# 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.*8.*$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 13\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.*13.*$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-program.c:5.*$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_program.c:5.*$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}:7.*$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}:5.*$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

View File

@ -0,0 +1,849 @@
# Copyright (C) 1992, 1993, 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 Fred Fish. (fnf@cygnus.com)
set ws "\[\r\n\t \]+"
if $tracelevel then {
strace $tracelevel
}
# Check to see if we have an executable to test. If not, then either we
# haven't tried to compile one, or the compilation failed for some reason.
# In either case, just notify the user and skip the tests in this file.
# Note - create separate "inherit" executable from misc.cc
set testfile "inherit-hp"
set srcfile misc-hp.cc
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile} "c++"] {
return -1;
}
if {[skip_hp_tests $gcc_compiled]} then { continue }
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
#
# Single inheritance, print individual members.
#
proc test_print_si_members {} {
# Print all members of g_A using fully qualified form.
gdb_test "print g_A.A::a" ".* = 1" "print g_A.A::a"
gdb_test "print g_A.A::x" ".* = 2" "print g_A.A::x"
# Print members of g_A using nonambiguous compact form.
gdb_test "print g_A.a" ".* = 1" "print g_A.a"
gdb_test "print g_A.x" ".* = 2" "print g_A.x"
# Print all members of g_B using fully qualified form.
gdb_test "print g_B.A::a" ".* = 3" "print g_B.A::a"
gdb_test "print g_B.A::x" ".* = 4" "print g_B.A::x"
gdb_test "print g_B.B::b" ".* = 5" "print g_B.B::b"
gdb_test "print g_B.B::x" ".* = 6" "print g_B.B::x"
# Print members of g_B using nonambiguous compact form.
setup_xfail_format "DWARF 1"
gdb_test "print g_B.a" ".* = 3" "print g_B.a"
gdb_test "print g_B.b" ".* = 5" "print g_B.b"
gdb_test "print g_B.x" ".* = 6" "print g_B.x"
# Print all members of g_C using fully qualified form.
gdb_test "print g_C.A::a" ".* = 7" "print g_C.A::a"
gdb_test "print g_C.A::x" ".* = 8" "print g_C.A::x"
gdb_test "print g_C.C::c" ".* = 9" "print g_C.C::c"
gdb_test "print g_C.C::x" ".* = 10" "print g_C.C::x"
# Print members of g_C using nonambiguous compact form.
setup_xfail_format "DWARF 1"
gdb_test "print g_C.a" ".* = 7" "print g_C.a"
gdb_test "print g_C.c" ".* = 9" "print g_C.c"
gdb_test "print g_C.x" ".* = 10" "print g_C.x"
}
#
# Single inheritance, print type definitions.
#
proc test_ptype_si {} {
global gdb_prompt
global ws
# Print class A as a type.
send_gdb "ptype A\n"
gdb_expect {
-re "type = class A \{\r\n.*\[ \]*int a;\r\n\[ \]*int x;\r\n.*\[ \]*\}\r\n$gdb_prompt $" {
pass "ptype A (FIXME)"
}
-re "type = struct A \{\r\n\[ \]*int a;\r\n\[ \]*int x;\r\n\[ \]*\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype A (FIXME)"
}
-re ".*$gdb_prompt $" { fail "ptype A" }
timeout { fail "ptype A (timeout)" ; return }
}
# Print class A as an explicit class.
send_gdb "ptype class A\n"
gdb_expect {
-re "type = class A \{\r\n.*\[ \]*int a;\r\n\[ \]*int x;\r\n.*\[ \]*\}\r\n$gdb_prompt $" {
pass "ptype class A (FIXME)"
}
-re "type = struct A \{\r\n\[ \]*int a;\r\n\[ \]*int x;\r\n\[ \]*\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype class A (FIXME)"
}
-re ".*$gdb_prompt $" { fail "ptype class A" }
timeout { fail "ptype class A (timeout)" ; return }
}
# Print type of an object of type A.
send_gdb "ptype g_A\n"
gdb_expect {
-re "type = class A \{\r\n.*\[ \]*int a;\r\n\[ \]*int x;\r\n.*\[ \]*\}\r\n$gdb_prompt $" {
pass "ptype g_A (FIXME)"
}
-re "type = struct A \{\r\n\[ \]*int a;\r\n\[ \]*int x;\r\n\[ \]*\}\r\n$gdb_prompt $" {
setup_xfail "*-*-*"
fail "ptype g_A (FIXME)"
}
-re ".*$gdb_prompt $" { fail "ptype g_A" }
timeout { fail "ptype g_A (timeout)" ; return }
}
# Print class B as a type.
setup_xfail_format "DWARF 1"
gdb_test "ptype B" "type = class B : public A \{\r\n\[ \]*public:\r\n\[ \]*int b;\r\n\[ \]*int x;\r\n.*\}" "ptype B"
# Print class B as an explicit class.
setup_xfail_format "DWARF 1"
gdb_test "ptype class B" "type = class B : public A \{\r\n\[ \]*public:\r\n\[ \]*int b;\r\n\[ \]*int x;\r\n.*\}" "ptype class B"
# Print type of an object of type B.
setup_xfail_format "DWARF 1"
gdb_test "ptype g_B" "type = class B : public A \{\r\n\[ \]*public:\r\n\[ \]*int b;\r\n\[ \]*int x;\r\n.*\}" "ptype g_B"
# Print class C as a type.
setup_xfail_format "DWARF 1"
gdb_test "ptype C" "type = class C : public A \{\r\n\[ \]*public:\r\n\[ \]*int c;\r\n\[ \]*int x;\r\n.*\}" "ptype C"
# Print class C as an explicit class.
setup_xfail_format "DWARF 1"
gdb_test "ptype class C" "type = class C : public A \{\r\n\[ \]*public:\r\n\[ \]*int c;\r\n\[ \]*int x;\r\n.*\}" "ptype class C"
# Print type of an object of type g_C.
setup_xfail_format "DWARF 1"
gdb_test "ptype g_C" "type = class C : public A \{\r\n\[ \]*public:\r\n\[ \]*int c;\r\n\[ \]*int x;\r\n.*\}" "ptype g_C"
# gcc cygnus-2.3.3 (Q1) has this bug, but it was fixed as of
# cygnus-2.3.3-930417. PR 2819.
send_gdb "ptype tagless_struct\n"
gdb_expect {
-re "type = class \{${ws}public:${ws}int one;${ws}int two;${ws}tagless_struct & operator=\\(tagless_struct &\\);${ws}\\\$_1 \\(tagless_struct &\\);${ws}\\\$_1 \\(\\);${ws}\}\r\n$gdb_prompt $" {
pass "ptype tagless struct"
}
-re "type = (struct|class).*\{.*int one;.*int two;.*\}\r\n$gdb_prompt $" {
pass "ptype tagless struct (obsolete gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype tagless struct"
}
timeout {
fail "ptype tagless struct (timeout)"
}
}
send_gdb "ptype v_tagless\n"
gdb_expect {
-re "type = class \{${ws}public:${ws}int one;${ws}int two;${ws}tagless_struct & operator=\\(tagless_struct &\\);${ws}\\\$_1 \\(tagless_struct &\\);${ws}\\\$_1 \\(\\);${ws}\}\r\n$gdb_prompt $" {
pass "ptype variable of type tagless struct"
}
-re "type = (struct|class).*\{.*int one;.*int two;.*\}\r\n$gdb_prompt $" {
pass "ptype variable of type tagless struct (obsolete gcc or gdb)"
}
-re ".*$gdb_prompt $" {
fail "ptype variable of type tagless struct"
}
timeout {
fail "ptype variable of type tagless struct (timeout)"
}
}
}
#
# Single inheritance, print complete classes.
#
proc test_print_si_classes {} {
# Print all members of g_A.
gdb_test "print g_A" ".* = \{a = 1, x = 2\}" "print g_A"
# Print all members of g_B.
setup_xfail_format "DWARF 1"
gdb_test "print g_B" ".* = \{\<class A\> = \{a = 3, x = 4\}, b = 5, x = 6\}" "print g_B"
# Print all members of g_C.
setup_xfail_format "DWARF 1"
gdb_test "print g_C" ".* = \{\<class A\> = \{a = 7, x = 8\}, c = 9, x = 10\}" "print g_C"
}
#
# Single inheritance, print anonymous unions.
# GDB versions prior to 4.14 entered an infinite loop when printing
# the type of a class containing an anonymous union, and they were also
# incapable of printing the member of an anonymous union.
# We test the printing of the member first, and perform the other tests
# only if the test succeeds, to avoid the infinite loop.
#
proc test_print_anon_union {} {
global gdb_prompt
global ws
setup_xfail_format "DWARF 1"
gdb_test "print g_anon_union.a" ".* = 2" "print anonymous union member"
setup_xfail_format "DWARF 1"
send_gdb "print g_anon_union\n"
gdb_expect {
-re ".* = \{one = 1, \{a = 2, b = 2\}\}\r\n$gdb_prompt $" {
pass "print variable of type anonymous union"
}
-re ".* = .*\{one = 1, = \{a = 2, b = .*\}\}\r\n$gdb_prompt $" {
pass "print variable of type anonymous union (obsolete gcc or gdb)"
}
-re ".*\r\n$gdb_prompt $" {
fail "print variable of type anonymous union"
}
timeout {
fail "print variableof type anonymous union (timeout)"
}
}
setup_xfail_format "DWARF 1"
send_gdb "ptype g_anon_union\n"
gdb_expect {
-re "type = class class_with_anon_union \{${ws}public:${ws}int one;${ws}union \{${ws}public:${ws}int a;${ws}long int b;${ws}union \{\.\.\.\} & operator=\\(union \{\.\.\.\} &\\);${ws}\\\$_0 \\(union \{\.\.\.\} &\\);${ws}\\\$_0 \\(\\);${ws}\};${ws}class_with_anon_union & operator=\\(class_with_anon_union const &\\);${ws}class_with_anon_union\\(class_with_anon_union const &\\);${ws}class_with_anon_union\\(void\\);${ws}\}\r\n$gdb_prompt $" {
pass "print type of anonymous union"
}
-re "type = (struct|class).*\{.*int one;.*union \{.*int a;.*(long|long int|int) b;.*\};.*\}\r\n$gdb_prompt $" {
pass "print type of anonymous union (obsolete gcc or gdb)"
}
-re ".*\r\n$gdb_prompt $" {
fail "print type of anonymous union"
}
timeout {
fail "print type of anonymous union (timeout)"
}
}
}
#
# Multiple inheritance, print individual members.
#
proc test_print_mi_members {} {
global gdb_prompt
# Print all members of g_A.
gdb_test "print g_A.A::a" ".* = 1" "print g_A.A::a"
gdb_test "print g_A.A::x" ".* = 2" "print g_A.A::x"
# Print all members of g_B.
gdb_test "print g_B.A::a" ".* = 3" "print g_B.A::a"
gdb_test "print g_B.A::x" ".* = 4" "print g_B.A::x"
gdb_test "print g_B.B::b" ".* = 5" "print g_B.B::b"
gdb_test "print g_B.B::x" ".* = 6" "print g_B.B::x"
# Print all members of g_C.
gdb_test "print g_C.A::a" ".* = 7" "print g_C.A::a"
gdb_test "print g_C.A::x" ".* = 8" "print g_C.A::x"
gdb_test "print g_C.C::c" ".* = 9" "print g_C.C::c"
gdb_test "print g_C.C::x" ".* = 10" "print g_C.C::x"
# Print all members of g_D.
# The following is ambiguous, and gdb should detect this.
# For now, accept gdb's behavior as an expected failure if it
# simply prints either member correctly.
# setup_xfail "*-*-*"
send_gdb "print g_D.A::a\n"
gdb_expect {
-re "warning: A ambiguous; using D::B::A. Use a cast to disambiguate.\r\n\\$\[0-9\]* = 11\r\n$gdb_prompt $" {
pass "print g_D.A::a"
}
-re ".* = 15\r\n$gdb_prompt $" {
fail "print g_D.A::a (did GDB's algorithm change?)"
}
-re ".* = 11\r\n$gdb_prompt $" {
fail "print g_D.A::a (ambiguity not reported)"
}
-re ".*$gdb_prompt $" { fail "print g_D.A::a" }
timeout { fail "print g_D.A::a (timeout)" ; return }
}
# The following is ambiguous, and gdb should detect this.
# For now, accept gdb's behavior as an expected failure if it
# simply prints either member correctly.
# setup_xfail "*-*-*"
send_gdb "print g_D.A::x\n"
gdb_expect {
-re "warning: A ambiguous; using D::B::A. Use a cast to disambiguate.\r\n\\$\[0-9\]* = 12\r\n$gdb_prompt $" {
pass "print g_D.A::x"
}
-re ".* = 16\r\n$gdb_prompt $" {
fail "print g_D.A::x (did GDB's algorithm change?)"
}
-re ".* = 12\r\n$gdb_prompt $" {
fail "print g_D.A::x (ambiguity not reported)"
}
-re ".*$gdb_prompt $" { fail "print g_D.A::x" }
timeout { fail "print g_D.A::x (timeout)" ; return }
}
gdb_test "print g_D.B::b" ".* = 13" "print g_D.B::b"
gdb_test "print g_D.B::x" ".* = 14" "print g_D.B::x"
setup_xfail_format "DWARF 1"
gdb_test "print g_D.C::c" ".* = 17" "print g_D.C::c"
setup_xfail_format "DWARF 1"
gdb_test "print g_D.C::x" ".* = 18" "print g_D.C::x"
gdb_test "print g_D.D::d" ".* = 19" "print g_D.D::d"
gdb_test "print g_D.D::x" ".* = 20" "print g_D.D::x"
# Print all members of g_E.
# The following is ambiguous, and gdb should detect this.
# For now, accept gdb's behavior as an expected failure if it
# simply prints either member correctly.
#setup_xfail "*-*-*"
send_gdb "print g_E.A::a\n"
gdb_expect {
-re "warning: A ambiguous; using E::D::B::A. Use a cast to disambiguate.\r\n\\$\[0-9\]* = 21\r\n$gdb_prompt $" {
pass "print g_E.A::a"
}
-re ".* = 25\r\n$gdb_prompt $" {
fail "print g_E.A::a (did GDB's algorithm change?)"
}
-re ".* = 21\r\n$gdb_prompt $" {
fail "print g_E.A::a (ambiguity not reported)"
}
-re ".*$gdb_prompt $" { fail "print g_E.A::a" }
timeout { fail "print g_E.A::a (timeout)" ; return }
}
# The following is ambiguous, and gdb should detect this.
# For now, accept gdb's behavior as an expected failure if it
# simply prints either member correctly.
# setup_xfail "*-*-*"
send_gdb "print g_E.A::x\n"
gdb_expect {
-re "warning: A ambiguous; using E::D::B::A. Use a cast to disambiguate.\r\n\\$\[0-9\]* = 22\r\n$gdb_prompt $" {
pass "print g_E.A::x"
}
-re ".* = 26\r\n$gdb_prompt $" {
fail "print g_E.A::x (did GDB's algorithm change?)"
}
-re ".* = 22\r\n$gdb_prompt $" {
fail "print g_E.A::x (ambiguity not reported)"
}
-re ".*$gdb_prompt $" { fail "print g_E.A::x" }
timeout { fail "print g_E.A::x (timeout)" ; return }
}
gdb_test "print g_E.B::b" ".* = 23" "print g_E.B::b"
gdb_test "print g_E.B::x" ".* = 24" "print g_E.B::x"
setup_xfail_format "DWARF 1"
gdb_test "print g_E.C::c" ".* = 27" "print g_E.C::c"
setup_xfail_format "DWARF 1"
gdb_test "print g_E.C::x" ".* = 28" "print g_E.C::x"
gdb_test "print g_E.D::d" ".* = 29" "print g_E.D::d"
gdb_test "print g_E.D::x" ".* = 30" "print g_E.D::x"
gdb_test "print g_E.E::e" ".* = 31" "print g_E.E::e"
gdb_test "print g_E.E::x" ".* = 32" "print g_E.E::x"
}
#
# Multiple inheritance, print type definitions.
#
proc test_ptype_mi {} {
setup_xfail_format "DWARF 1"
gdb_test "ptype D" "type = class D : public B, public C \{\r\n\[ \]*public:\r\n\[ \]*int d;\r\n\[ \]*int x;\r\n.*\}" "ptype D"
setup_xfail_format "DWARF 1"
gdb_test "ptype class D" "type = class D : public B, public C \{\r\n\[ \]*public:\r\n\[ \]*int d;\r\n\[ \]*int x;\r\n.*\}" "ptype class D"
setup_xfail_format "DWARF 1"
gdb_test "ptype g_D" "type = class D : public B, public C \{\r\n\[ \]*public:\r\n\[ \]*int d;\r\n\[ \]*int x;\r\n.*\}" "ptype g_D"
setup_xfail_format "DWARF 1"
gdb_test "ptype E" "type = class E : public D \{\r\n\[ \]*public:\r\n\[ \]*int e;\r\n\[ \]*int x;\r\n.*\}" "ptype E"
setup_xfail_format "DWARF 1"
gdb_test "ptype class E" "type = class E : public D \{\r\n\[ \]*public:\r\n\[ \]*int e;\r\n\[ \]*int x;\r\n.*\}" "ptype class E"
setup_xfail_format "DWARF 1"
gdb_test "ptype g_E" "type = class E : public D \{\r\n\[ \]*public:\r\n\[ \]*int e;\r\n\[ \]*int x;\r\n.*\}" "ptype g_E"
}
#
# Multiple inheritance, print complete classes.
#
proc test_print_mi_classes {} {
# Print all members of g_D.
setup_xfail_format "DWARF 1"
gdb_test "print g_D" ".* = \{\<class B\> = \{\<class A\> = \{a = 11, x = 12\}, b = 13, x = 14\}, \<class C\> = \{\<class A\> = \{a = 15, x = 16\}, c = 17, x = 18\}, d = 19, x = 20\}" "print g_D"
# Print all members of g_E.
setup_xfail_format "DWARF 1"
gdb_test "print g_E" ".* = \{\<class D\> = \{\<class B\> = \{\<class A\> = \{a = 21, x = 22\}, b = 23, x = 24\}, \<class C\> = \{\<class A\> = \{a = 25, x = 26\}, c = 27, x = 28\}, d = 29, x = 30\}, e = 31, x = 32\}" "print g_E"
}
#
# Single virtual inheritance, print individual members.
#
proc test_print_svi_members {} {
global gdb_prompt
global decimal
# Print all members of g_vA.
gdb_test "print g_vA.vA::va" ".* = 1" "print g_vA.vA::va"
gdb_test "print g_vA.vA::vx" ".* = 2" "print g_vA.vA::vx"
# Print members of g_vA using compact form.
gdb_test "print g_vA.va" ".* = 1" "print g_vA.va"
gdb_test "print g_vA.vx" ".* = 2" "print g_vA.vx"
# Print all members of g_vB.
setup_xfail_format "DWARF 1"
send_gdb "print g_vB.vA::va\n"
gdb_expect {
-re ".* = 3\r\n$gdb_prompt $" { pass "print g_vB.vA::va" }
-re ".*virtual baseclass botch.*$gdb_prompt $" {
# Does not happen with gcc cygnus-2.4.5-930828
fail "print g_vB.vA::va (known bug with gcc cygnus-2.4.5-930417)"
# Many of the rest of these tests have the same problem.
return 0
}
-re ".*$gdb_prompt $" { fail "print g_vB.vA::va" }
timeout { fail "print g_vB.vA::va (timeout)" ; return }
}
setup_xfail_format "DWARF 1"
gdb_test "print g_vB.vA::vx" ".* = 4" "print g_vB.vA::vx"
gdb_test "print g_vB.vB::vb" ".* = 5" "print g_vB.vB::vb"
gdb_test "print g_vB.vB::vx" ".* = 6" "print g_vB.vB::vx"
# Print members of g_vB using compact form.
setup_xfail_format "DWARF 1"
gdb_test "print g_vB.va" ".* = 3" "print g_vB.va"
gdb_test "print g_vB.vb" ".* = 5" "print g_vB.vb"
gdb_test "print g_vB.vx" ".* = 6" "print g_vB.vx"
# Print all members of g_vC.
setup_xfail_format "DWARF 1"
gdb_test "print g_vC.vA::va" ".* = 7" "print g_vC.vA::va"
setup_xfail_format "DWARF 1"
gdb_test "print g_vC.vA::vx" ".* = 8" "print g_vC.vA::vx"
gdb_test "print g_vC.vC::vc" ".* = 9" "print g_vC.vC::vc"
gdb_test "print g_vC.vC::vx" ".* = 10" "print g_vC.vC::vx"
# Print members of g_vC using compact form.
setup_xfail_format "DWARF 1"
gdb_test "print g_vC.va" ".* = 7" "print g_vC.va"
gdb_test "print g_vC.vc" ".* = 9" "print g_vC.vc"
gdb_test "print g_vC.vx" ".* = 10" "print g_vC.vx"
}
#
# Single virtual inheritance, print type definitions.
#
proc test_ptype_vi {} {
global gdb_prompt
# This class does not use any C++-specific features, so it's fine for
# it to print as "struct".
send_gdb "ptype vA\n"
gdb_expect {
-re "type = class vA \{\[\r\n\]+\[ \]*public:\[\r\n\]+\[ \]*int va;\[\r\n\]+\[ \]*int vx;\[\r\n\]+.*\}\[\r\n\]+$gdb_prompt $" {
pass "ptype vA"
}
-re "type = struct vA \{\[\r\n\]+\[ \]*int va;\[\r\n\]+\[ \]*int vx;\[\r\n\]+\}\[\r\n\]+$gdb_prompt $" {
pass "ptype vA"
}
-re ".*$gdb_prompt $" { fail "ptype vA" }
timeout { fail "ptype vA (timeout)" ; return }
}
# This class does not use any C++-specific features, so it's fine for
# it to print as "struct".
send_gdb "ptype class vA\n"
gdb_expect {
-re "type = class vA \{\[\r\n\]+\[ \]*public:\[\r\n\]+\[ \]*int va;\[\r\n\]+\[ \]*int vx;\[\r\n\]+.*\}\[\r\n\]+$gdb_prompt $" {
pass "ptype class vA"
}
-re "type = struct vA \{\[\r\n\]+\[ \]*int va;\[\r\n\]+\[ \]*int vx;\[\r\n\]+\}\[\r\n\]+$gdb_prompt $" {
pass "ptype class vA"
}
-re ".*$gdb_prompt $" { fail "ptype class vA" }
timeout { fail "ptype class vA (timeout)" ; return }
}
# This class does not use any C++-specific features, so it's fine for
# it to print as "struct".
send_gdb "ptype g_vA\n"
gdb_expect {
-re "type = class vA \{\[\r\n\]+\[ \]*public:\[\r\n\]+\[ \]*int va;\[\r\n\]+\[ \]*int vx;\[\r\n\]+.*\}\[\r\n\]+$gdb_prompt $" {
pass "ptype g_vA"
}
-re "type = struct vA \{\[\r\n\]+\[ \]*int va;\[\r\n\]+\[ \]*int vx;\[\r\n\]+\}\[\r\n\]+$gdb_prompt $" {
pass "ptype g_vA"
}
-re ".*$gdb_prompt $" { fail "ptype g_vA" }
timeout { fail "ptype g_vA (timeout)" ; return }
}
setup_xfail_format "DWARF 1"
gdb_test "ptype vB" "ptype vB\[\r\n\]+type = class vB : public virtual vA \{\[\r\n\]+ public:\r\n\[ \]+int vb;\r\n\[ \]+int vx;\r\n.*\}" "ptype vB (aCC)"
setup_xfail_format "DWARF 1"
gdb_test "ptype class vB" "type = class vB : public virtual vA \{\r\n\[ \]*public:\r\n\[ \]*int vb;\r\n\[ \]*int vx;\r\n.*\}" "ptype class vB (aCC)"
setup_xfail_format "DWARF 1"
gdb_test "ptype g_vB" "type = class vB : public virtual vA \{\r\n\[ \]*public:\r\n\[ \]*int vb;\r\n\[ \]*int vx;\r\n.*\}" "ptype g_vB (aCC)"
setup_xfail_format "DWARF 1"
gdb_test "ptype vC" "type = class vC : public virtual vA \{\r\n\[ \]*public:\r\n\[ \]*int vc;\r\n\[ \]*int vx;\r\n.*\}" "ptype vC (aCC)"
setup_xfail_format "DWARF 1"
gdb_test "ptype class vC" "type = class vC : public virtual vA \{\r\n\[ \]*public:\r\n\[ \]*int vc;\r\n\[ \]*int vx;\r\n.*\}" "ptype class vC (aCC)"
setup_xfail_format "DWARF 1"
gdb_test "ptype g_vC" "type = class vC : public virtual vA \{\r\n\[ \]*public:\r\n\[ \]*int vc;\r\n\[ \]*int vx;\r\n.*\}" "ptype g_vC (aCC)"
}
#
# Single virtual inheritance, print complete classes.
#
proc test_print_svi_classes {} {
global gdb_prompt
global hex
global decimal
# Print all members of g_vA.
gdb_test "print g_vA" ".* = \{va = 1, vx = 2\}" "print g_vA"
# Print all members of g_vB.
setup_xfail_format "DWARF 1"
send_gdb "print g_vB\n"
gdb_expect {
-re ".* = \{\<class vA\> = \{va = 3, vx = 4\}, vb = 5, vx = 6, Virtual table at $hex\}\r\n$gdb_prompt $" {
pass "print g_vB"
}
-re ".*invalid address 0x0.*$gdb_prompt $" {
# Does not happen with gcc cygnus-2.4.5-930828
fail "print g_vB (known bug with gcc cygnus-2.4.5-930417)"
# Many of the rest of these tests have the same problem.
return 0
}
-re ".*$gdb_prompt $" { fail "print g_vB" }
timeout { fail "print g_vB (timeout)" ; return }
}
# Print all members of g_vC.
setup_xfail_format "DWARF 1"
gdb_test "print g_vC" ".* = \{\<class vA\> = \{va = 7, vx = 8\}, vc = 9, vx = 10, Virtual table at $hex\}" "print g_vC"
}
#
# Multiple virtual inheritance, print individual members.
#
proc test_print_mvi_members {} {
global gdb_prompt
global decimal
# Print all members of g_vD.
setup_xfail_format "DWARF 1"
send_gdb "print g_vD.vA::va\n"
gdb_expect {
-re ".* = 19\r\n$gdb_prompt $" { pass "print g_vD.vA::va" }
-re ".*virtual baseclass botch.*$gdb_prompt $" {
# Does not happen with gcc cygnus-2.4.5-930828
fail "print g_vD.vA::va (known bug with gcc cygnus-2.4.5-930417)"
# Many of the rest of these tests have the same problem.
return 0
}
-re ".*$gdb_prompt $" { fail "print g_vD.vA::va" }
timeout { fail "print g_vD.vA::va (timeout)" ; return }
}
setup_xfail_format "DWARF 1"
gdb_test "print g_vD.vA::vx" ".* = 20" "print g_vD.vA::vx"
setup_xfail_format "DWARF 1"
gdb_test "print g_vD.vB::vb" ".* = 21" "print g_vD.vB::vb"
setup_xfail_format "DWARF 1"
gdb_test "print g_vD.vB::vx" ".* = 22" "print g_vD.vB::vx"
setup_xfail_format "DWARF 1"
gdb_test "print g_vD.vC::vc" ".* = 23" "print g_vD.vC::vc"
setup_xfail_format "DWARF 1"
gdb_test "print g_vD.vC::vx" ".* = 24" "print g_vD.vC::vx"
gdb_test "print g_vD.vD::vd" ".* = 25" "print g_vD.vD::vd"
gdb_test "print g_vD.vD::vx" ".* = 26" "print g_vD.vD::vx"
# Print all members of g_vE.
setup_xfail_format "DWARF 1"
gdb_test "print g_vE.vA::va" ".* = 0" "print g_vE.vA::va"
setup_xfail_format "DWARF 1"
gdb_test "print g_vE.vA::vx" ".* = 0" "print g_vE.vA::vx"
setup_xfail_format "DWARF 1"
gdb_test "print g_vE.vB::vb" ".* = 0" "print g_vE.vB::vb"
setup_xfail_format "DWARF 1"
gdb_test "print g_vE.vB::vx" ".* = 0" "print g_vE.vB::vx"
setup_xfail_format "DWARF 1"
gdb_test "print g_vE.vC::vc" ".* = 0" "print g_vE.vC::vc"
setup_xfail_format "DWARF 1"
gdb_test "print g_vE.vC::vx" ".* = 0" "print g_vE.vC::vx"
setup_xfail_format "DWARF 1"
gdb_test "print g_vE.vD::vd" ".* = 0" "print g_vE.vD::vd"
gdb_test "print g_vE.vD::vx" ".* = 0" "print g_vE.vD::vx"
gdb_test "print g_vE.vE::ve" ".* = 27" "print g_vE.vE::ve"
gdb_test "print g_vE.vE::vx" ".* = 28" "print g_vE.vE::vx"
}
#
# Multiple virtual inheritance, print type definitions.
#
proc test_ptype_mvi {} {
setup_xfail_format "DWARF 1"
gdb_test "ptype vD" "type = class vD : public virtual vB, public virtual vC \{\r\n\[ \]*public:\r\n\[ \]*int vd;\r\n\[ \]*int vx;\r\n.*\}" "ptype vD (aCC)"
setup_xfail_format "DWARF 1"
gdb_test "ptype class vD" "type = class vD : public virtual vB, public virtual vC \{\r\n\[ \]*public:\r\n\[ \]*int vd;\r\n\[ \]*int vx;\r\n.*\}" "ptype class vD (aCC)"
setup_xfail_format "DWARF 1"
gdb_test "ptype g_vD" "type = class vD : public virtual vB, public virtual vC \{\r\n\[ \]*public:\r\n\[ \]*int vd;\r\n\[ \]*int vx;\r\n.*\}" "ptype g_vD (aCC)"
setup_xfail_format "DWARF 1"
gdb_test "ptype vE" "type = class vE : public virtual vD \{\r\n\[ \]*public:\r\n\[ \]*int ve;\r\n\[ \]*int vx;\r\n.*\}" "ptype vE (aCC)"
setup_xfail_format "DWARF 1"
gdb_test "ptype class vE" "type = class vE : public virtual vD \{\r\n\[ \]*public:\r\n\[ \]*int ve;\r\n\[ \]*int vx;\r\n.*\}" "ptype class vE (aCC)"
setup_xfail_format "DWARF 1"
gdb_test "ptype g_vE" "type = class vE : public virtual vD \{\r\n\[ \]*public:\r\n\[ \]*int ve;\r\n\[ \]*int vx;\r\n.*\}" "ptype g_vE (aCC)"
}
#
# Multiple virtual inheritance, print complete classes.
#
proc test_print_mvi_classes {} {
global gdb_prompt
global hex
global decimal
# Print all members of g_vD.
setup_xfail_format "DWARF 1"
send_gdb "print g_vD\n"
gdb_expect {
-re ".* = \{\<class vB\> = \{\<class vA\> = \{va = 19, vx = 20\}, vb = 21, vx = 22, Virtual table at $hex\}, \<class vC\> = \{vc = 23, vx = 24, Virtual table at $hex\}, vd = 25, vx = 26, Virtual table at $hex\}\r\n$gdb_prompt $" {
pass "print g_vD"
}
-re ".*invalid address 0x0.*$gdb_prompt $" {
# Does not happen with gcc cygnus-2.4.5-930828
fail "print g_vD (known bug with gcc cygnus-2.4.5-930417)"
# Many of the rest of these tests have the same problem.
return 0
}
-re ".*$gdb_prompt $" { fail "print g_vD" }
timeout { fail "print g_vD (timeout)" ; return }
}
# Print all members of g_vE.
setup_xfail_format "DWARF 1"
gdb_test "print g_vE" ".* = \{\<class vD\> = \{\<class vB\> = \{\<class vA\> = \{va = 0, vx = 0\}, vb = 0, vx = 0, Virtual table at $hex\}, \<class vC\> = \{vc = 0, vx = 0, Virtual table at $hex\}, vd = 0, vx = 0, Virtual table at $hex\}, ve = 27, vx = 28, Virtual table at $hex\}" "print g_vE"
}
proc do_tests {} {
global prms_id
global bug_id
global subdir
global objdir
global srcdir
global binfile
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 c++" ""
gdb_test "set width 0" ""
# Get the debug format for the compiled test case.
if { ![ runto_main] } {
gdb_suppress_tests;
} else {
get_debug_format
}
test_ptype_si
test_ptype_mi
test_ptype_vi
test_ptype_mvi
gdb_stop_suppressing_tests;
if { ![ runto 'inheritance2(void)' ] } {
gdb_suppress_tests;
}
test_print_si_members
test_print_si_classes
test_print_mi_members
test_print_mi_classes
test_print_anon_union
gdb_stop_suppressing_tests;
if { ![ runto 'inheritance4(void)' ] } {
gdb_suppress_tests;
}
test_print_svi_members
test_print_svi_classes
test_print_mvi_members
test_print_mvi_classes
}
do_tests

View File

@ -0,0 +1,152 @@
# more-steps.exp -- Expect script to test gdb's ability to step threaded pgms
# Copyright (C) 1992 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
# use this to debug:
#
#log_user 1
if $tracelevel then {
strace $tracelevel
}
#if { ![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"] } {
# verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
# return 0
#}
set testfile more-steps
set srcfile ${srcdir}/${subdir}/${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile}] {
return -1
}
# To build the executable we need to link against the thread library.
#
# cc -Ae -g -o more-steps -lpthread more-steps.c
#
#compile "${srcfile} -Ae -g -lpthread -o ${binfile}"
if {$gcc_compiled == 0} {
set additional_flags "additional_flags=-Ae"
} else {
set additional_flags ""
}
if { [gdb_compile "${srcdir}/${subdir}/${testfile}.c" "${binfile}.o" object [list debug $additional_flags]] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
if { ![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"] } {
if { [gdb_compile "${binfile}.o" "${binfile}" executable {debug "additional_flags=-lpthread"}] != ""} {
gdb_suppress_entire_file "Testcase link failed, so all tests in this file will automatically fail."
}
} else {
remote_exec build "ld /usr/ccs/lib/crt0.o ${binfile}.o -lcl -lpthread -lc /opt/langtools/lib/end.o -o ${binfile}"
}
#remote_exec build "ld /usr/ccs/lib/crt0.o ${binfile}.o -lcl -lpthread -lc /opt/langtools/lib/end.o -o ${binfile}"
# Thread stuff is _slow_; prepare for long waits.
#
set oldtimeout $timeout
set timeout [expr "$timeout + 300"]
set oldverbose $verbose
#set verbose 40
# Further, this test has some "null" lines designed
# to consume output from gdb that was too late to be
# matched (sequence is "gdb_test" sends; timeout and
# on to next send; result finally comes in; mismatch).
#
# The null command is 'gdb_test "p \$pc" ".*" ""'
#
# NOTE: to pass a literal "$", "/" or "*" (etc.) to gdb_test,
# remember that the pattern will be escaped once and
# $-evaluated twice:
#
# "\\\*" matches "\*"
# "\$" matches "$"
#
proc fix_timeout {} {
gdb_test "p \$pc" ".*" ""
}
#=========================
#
# Simple sanity test first.
#
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
# First, step in the main thread.
#
gdb_test "b do_pass" ".*Breakpoint 1.*" ""
gdb_test "r" ".*Breakpoint 1.*do_pass.*" ""
# Breaks as well as nexts to make
# sure we can handle simultaneous hit
# of bpt and step, as well as stepping
# past bpts.
#
gdb_test "tb 87" ".*Breakpoint 2.*" ""
gdb_test "tb 91" ".*Breakpoint 3.*" ""
gdb_test "tb 96" ".*Breakpoint 4.*" ""
gdb_test "tb 113" ".*Breakpoint 5.*" ""
gdb_test "c" ".*do_pass.*87.*" "87"
gdb_test "n" ".*do_pass.*91.*" "n"
# This only gets a number, as it doesn't
# hit a bpt.
#
gdb_test "n" ".*95.*" "n"
gdb_test "n" ".*do_pass.*96.*" "n"
gdb_test "c" ".*do_pass.*113.*" "c"
gdb_test "c" ".*Program exited normally.*" "c"
# Now step in a thread
#
gdb_test "r" ".*Breakpoint.*do_pass.*" "do_pass"
gdb_test "until 87" ".*do_pass.*87.*" "until"
gdb_test "thr 4" ".*Switching to thread 4.*spin.*56.*" "switch"
gdb_test "tb 60 thr 4" ".*Breakpoint.*" ""
# If we do "next" now, all the other threads
# can finish!
#
gdb_test "n" ".*spin.*60.*" ""
gdb_test "i th" ".*\\\* 4 sys.*spin.*1 sys.*do_pass.*" "still in 4"
# Done!
#
gdb_exit
set timeout $oldtimeout
set verbose $oldverbose
# execute_anywhere "rm -f ${binfile}"
#
return 0

View File

@ -0,0 +1,103 @@
namespace AAA {
char c;
int i;
int A_foo (int);
char foo (char);
class inA {
public:
int xx;
int fum (int);
};
};
int AAA::inA::fum (int i)
{
return 10 + i;
}
namespace BBB {
char c;
int i;
int B_foo (int);
char foo (char);
namespace CCC {
char foo (char);
};
class Class {
public:
char foo (char);
int dummy;
};
};
int AAA::A_foo (int x)
{
return 2 * x;
}
char AAA::foo (char c)
{
return 'a';
}
int BBB::B_foo (int x)
{
return 3 * x;
}
char BBB::foo (char c)
{
return 'b';
}
char BBB::CCC::foo (char c)
{
return 'z';
}
char BBB::Class::foo (char c)
{
return 'o';
}
void marker1(void)
{
return;
}
int main ()
{
using AAA::inA;
char c1;
using namespace BBB;
c1 = foo ('x');
c1 = AAA::foo ('x');
c1 = BBB::CCC::foo ('m');
inA ina;
ina.xx = 33;
int y;
y = AAA::A_foo (33);
y += B_foo (44);
BBB::Class cl;
c1 = cl.foo('e');
marker1();
}

View File

@ -0,0 +1,195 @@
# Copyright (C) 1997, 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
# tests for namespaces
# Written by Satish Pai <pai@apollo.hp.com> 1997-07-23
# This file is part of the gdb testsuite
# Note: These tests are geared to the HP aCC compiler,
# which has an idiosyncratic way of emitting debug info
# for namespaces.
if $tracelevel then {
strace $tracelevel
}
#
# test running programs
#
set prms_id 0
set bug_id 0
set testfile "namespace"
set srcfile ${testfile}.cc
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile}] {
return -1;
}
if {[skip_hp_tests $gcc_compiled]} then { continue }
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will a
utomatically fail."
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
#
# set it up at a breakpoint so we can play with the variable values
#
if ![runto_main] then {
perror "couldn't run to breakpoint"
continue
}
send_gdb "break marker1\n" ; gdb_expect -re ".*$gdb_prompt $"
send_gdb "cont\n"
gdb_expect {
-re "Break.* marker1 \\(\\) at .*:$decimal.*$gdb_prompt $" {
send_gdb "up\n"
gdb_expect {
-re ".*$gdb_prompt $" { pass "up from marker1" }
timeout { fail "up from marker1" }
}
}
-re "$gdb_prompt $" { fail "continue to marker1" }
timeout { fail "(timeout) continue to marker1" }
}
# Access a data item inside a namespace using colons and
# single quotes :-(
send_gdb "print 'AAA::c'\n"
gdb_expect {
-re "\\$\[0-9\]* = 0 '\\\\000'\r\n$gdb_prompt $" { pass "print 'AAA::c'" }
-re ".*$gdb_prompt $" { fail "print 'AAA::c'" }
timeout { fail "(timeout) print 'AAA::c'" }
}
# An object declared using "using".
send_gdb "print ina\n"
gdb_expect {
-re "\\$\[0-9\]+ = {xx = 33}.*$gdb_prompt $" {
pass "print ina"
}
-re ".*$gdb_prompt $" { fail "print ina" }
timeout { fail "(timeout) print ina" }
}
send_gdb "ptype ina\n"
gdb_expect {
-re "type = class AAA::inA \{\r\n\[ \]*public:\r\n\[ \]*int xx;\r\n\[ \]*\r\n\[ \]*int fum\\(int\\);\r\n\}\r\n$gdb_prompt $" {
pass "ptype ina"
}
-re ".*$gdb_prompt $" { fail "ptype ina" }
timeout { fail "(timeout) ptype ina" }
}
# Check all functions are known to GDB
send_gdb "info func foo\n"
gdb_expect {
-re "All functions.*File.*namespace.cc:\r\nint AAA::A_foo\\(int\\);\r\nint BBB::B_foo\\(int\\);\r\nchar AAA::foo\\(char\\);\r\nchar BBB::foo\\(char\\);\r\nchar BBB::CCC::foo\\(char\\);\r\nchar BBB::Class::foo\\(char\\);\r\n$gdb_prompt $" {
pass "info func foo"
}
-re ".*$gdb_prompt $" { fail "info func foo" }
timeout { fail "(timeout) info func foo" }
}
# Call a function in a namespace
send_gdb "print 'AAA::foo'('x')\n"
gdb_expect {
-re "\\$\[0-9\]* = 97 'a'\r\n$gdb_prompt $" {
pass "print 'AAA::foo'('x')"
}
-re ".*$gdb_prompt $" { fail "print 'AAA::foo'('x')" }
timeout { fail "(timeout) print 'AAA::foo'('x')" }
}
# Break on a function in a namespace
send_gdb "break AAA::foo\n"
gdb_expect {
-re "Breakpoint.*at $hex: file.*namespace.cc, line 42\\.\r\n$gdb_prompt $" {
pass "break AAA::foo"
}
-re ".*$gdb_prompt $" { fail "break AAA::foo" }
timeout { fail "(timeout) break AAA::foo" }
}
# Call a function in a nested namespace
send_gdb "print 'BBB::CCC::foo'('x')\n"
gdb_expect {
-re "\\$\[0-9\]* = 122 'z'\r\n$gdb_prompt $" {
pass "print 'BBB::CCC::foo'('x')"
}
-re ".*$gdb_prompt $" { fail "print 'BBB::CCC::foo'('x')" }
timeout { fail "(timeout) print 'BBB::CCC::foo'('x')" }
}
# Break on a function in a nested namespace
send_gdb "break BBB::CCC::foo\n"
gdb_expect {
-re "Breakpoint.*at $hex: file.*namespace.cc, line 58\\.\r\n$gdb_prompt $" {
pass "break BBB::CCC::foo"
}
-re ".*$gdb_prompt $" { fail "break BBB::CCC::foo" }
timeout { fail "(timeout) break BBB::CCC::foo" }
}
# Print address of a function in a class in a namespace
send_gdb "print 'BBB::Class'::foo\n"
gdb_expect {
-re "\\$\[0-9\]* = \{char \\(BBB::Class \\*, char\\)\} $hex <BBB::Class::foo\\(char\\)>\r\n$gdb_prompt $" {
pass "print 'BBB::Class'::foo"
}
-re ".*$gdb_prompt $" { fail "print 'BBB::Class'::foo" }
timeout { fail "(timeout) print 'BBB::Class'::foo" }
}
# Break on a function in a class in a namespace
send_gdb "break BBB::Class::foo\n"
gdb_expect {
-re "Breakpoint.*at $hex: file.*namespace.cc, line 63\\.\r\n$gdb_prompt $" {
pass "break BBB::Class::foo"
}
-re ".*$gdb_prompt $" { fail "break BBB::Class::foo" }
timeout { fail "(timeout) break BBB::Class::foo" }
}

View File

@ -0,0 +1,144 @@
# 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
# optimize.exp -- Expect script for testing apps compiled with -O
global timeout
# use this to debug:
#
#log_user 1
if $tracelevel then {
strace $tracelevel
}
set testfile optimize
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile}] {
return -1;
}
if {[skip_hp_tests $gcc_compiled]} then { continue }
# Vanilla -O, which is the same as +O2
#
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug optimize=+O2}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
send_gdb "file $binfile\n"
gdb_expect {
-re ".*no debugging symbols found.*$gdb_prompt $" {
fail "Didn't find debug symbols; CHFts23488"
}
-re ".*No header section (PXDB data).*$gdb_prompt $" {
fail "pointless warning"
}
-re ".*done.*$gdb_prompt $" {
pass "load debug symbols"
}
timeout { fail "timeout on file" }
}
# Two lines at the same place after opt.
#
gdb_test "b 28" ".*" ""
gdb_test "b 26" ".*also set at.*" "same line"
gdb_test "b 47" ".*" ""
gdb_test "b 48" ".*also set at.*" "same line"
gdb_test "tb main" ".*" ""
set old_timeout $timeout
set timeout [expr "$timeout + 200"]
send_gdb "r\n"
gdb_expect {
-re ".*No header section (PXDB data).*$gdb_prompt $" {
fail "pointless warning"
}
-re ".*main.*2\[12].*$gdb_prompt $" {
# All the lines before line 21 or 22 are
# evaporated by the compiler.
#
pass "hit main"
}
-re ".*$gdb_prompt $" {
fail "didn't hit main"
}
timeout { fail "timeout on run" }
}
set timeout $old_timeout
gdb_test "c" ".*Breakpoint 1.*33.*" ""
gdb_test "c" ".*51.*" ""
gdb_test "cle" ".*Deleted breakpoints.*" "set 2, so del 2"
gdb_test "b callee" ".*" ""
gdb_test "c" ".*callee.*" "hit called rtn"
gdb_exit
# +O4, don't use -g
#
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {optimize=+O4}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
send_gdb "file $binfile\n"
gdb_expect {
-re ".*no debugging symbols found.*$gdb_prompt $" {
pass "Didn't find debug symbols, as expected"
}
-re ".*No header section (PXDB data).*$gdb_prompt $" {
fail "pointless warning"
}
-re ".*done.*$gdb_prompt $" {
fail "Somehow found debug symbols--make this a pass?"
}
timeout { fail "timeout on file" }
}
gdb_test "b main" ".*" ""
gdb_test "b callee" ".*" ""
gdb_test "r" ".*Breakpoint 1.*main.*" ""
gdb_test "si 3" ".*main.*" "steps"
gdb_test "x/4i \$pc" ".*main.*main+4.*main+8.*" ""
gdb_test "c" ".*callee.*" "hit bp"
gdb_test "disas" ".*callee.*callee+4.*callee+12.*" ""
gdb_test "si" ".*callee.*" ""
gdb_test "fin" ".*Run till exit.*main.*" "finish"
gdb_test "x/i \$pc" ".*main+.*" "back in main"
gdb_exit
#remote_exec build "rm -f ${binfile}"
return 0

View File

@ -0,0 +1,20 @@
#include <stdio.h>
int callee( x )
int x;
{
int y = x * x;
return (y - 2);
}
main()
{
int i;
for (i = 1; i < 10; i++)
{
printf( "%d ", callee( i ));
}
printf( " Goodbye!\n" );
}

View File

@ -0,0 +1,114 @@
# 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
# This file is part of the gdb testsuite
# pxdb.exp Test that gdb calls pxdb on an application
# built without it.
#
if $tracelevel then {
strace $tracelevel
}
set prms_id 0
set bug_id 0
set testfile pxdb
set srcfile ${testfile}.c
set objfile ${objdir}/${subdir}/${testfile}.o
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile} "c++"] {
return -1;
}
if {[skip_hp_tests $gcc_compiled]} then { continue }
# To build a non-pxdb-ed file, use
#
# <compile to .o file>
# export LD_PXDB /dev/null
# ld -o hello_no_pxdb hello.o /opt/langtools/lib/end.o /usr/ccs/lib/crt0.o -lc
#
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
#
# use this to debug:
#log_user 1
# Following should get the error message:
#
# ld: (Warning) Can't exec pxdb using path: /dev/null
#
set cmdline "ksh -c \"LD_PXDB=/dev/null ld -o ${binfile} ${objfile} /usr/ccs/lib/crt0.o /opt/langtools/lib/end.o -lc\""
remote_exec build "rm ${binfile}"
remote_exec build $cmdline
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
# We expect to see this:
#
# "warning: File not processed by pxdb--about to process now.
# "
# ".
# "Procedures: 7
# "Files: 2
# "Reading symbols from ~/c_code.dir/hello_no_pxdb...done.
# "(gdb)
#
send_gdb "file ${binfile}\n"
gdb_expect {
-re ".*warning: File not processed by pxdb.*Procedures: \[0-9\]+.*done.*$gdb_prompt $"\
{ pass "PXDB call" }
-re "$gdb_prompt $" { fail "Didn't call pxdb" }
timeout { fail "call pxdb (timeout)" }
}
# Make sure the new data makes sense
#
if { ![runto callee] } then { return }
send_gdb "print x\n"
gdb_expect {
-re ".*= 1.*$gdb_prompt $" { pass "Good data after pxdb call" }
-re ".*$gdb_prompt $" { fail "No data after pxdb call" }
timeout { fail "(timeout)" }
}
gdb_exit
return 0

View File

@ -0,0 +1,809 @@
# quicksort.exp -- Expect script to test gdb with quicksort.c
# Copyright (C) 1992 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
# use this to debug:
#
#log_user 1
if $tracelevel then {
strace $tracelevel
}
if { ![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"] } {
verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
return 0
}
set testfile quicksort
set srcfile ${srcdir}/${subdir}/${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile}] {
return -1
}
# To build the executable we need to link against the thread library.
#
# cc -Ae -g -o quicksort -lpthread quicksort.c
#
#compile "${srcfile} -Ae -g -lpthread -o ${binfile}"
if {$gcc_compiled == 0} {
set additional_flags "additional_flags=-Ae"
} else {
set additional_flags ""
}
if { [gdb_compile "${srcdir}/${subdir}/${testfile}.c" "${binfile}.o" object [list debug $additional_flags]] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
remote_exec build "ld /usr/ccs/lib/crt0.o ${binfile}.o -lcl -lpthread -lc /opt/langtools/lib/end.o -o ${binfile}"
# Thread stuff is _slow_; prepare for long waits.
#
set oldtimeout $timeout
set timeout [expr "$timeout + 300"]
set oldverbose $verbose
#set verbose 40
# Further, this test has some "null" lines designed
# to consume output from gdb that was too late to be
# matched (sequence is "gdb_test" sends; timeout and
# on to next send; result finally comes in; mismatch).
#
# The null command is 'gdb_test "p \$pc" ".*" ""'
#
# NOTE: to pass a literal "$", "/" or "*" (etc.) to gdb_test,
# remember that the pattern will be escaped once and
# $-evaluated twice:
#
# "\\\*" matches "\*"
# "\$" matches "$"
#
proc fix_timeout {} {
gdb_test "p \$pc" ".*" ""
}
#=========================
#
# Simple sanity test first.
#
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
gdb_test "tb 122" ".*Breakpoint.*" ""
gdb_test "r" ".*122.*" ""
gdb_test "thr 99" ".*Thread ID 99 not known.*" "Check too-big thread number"
gdb_test "tb 145 thr 3" ".*Breakpoint.*" "set thread-specific bp 145"
gdb_test "tb 146 thr 4" ".*Breakpoint.*" "set thread-specific bp 146"
gdb_test "c" ".*Switched to thread.*145.*" "auto switch"
gdb_test "c" ".*Switched to thread.*146.*" "auto switch 2"
gdb_test "c" ".*Program exited normally.*" ""
#=========================
#
# Test that you can't do a thread select after a program runs.
#
gdb_test "thread" ".*No stack.*" "No live thread after run"
gdb_test "thr 2" ".*No stack.*" "Can't set thread after run"
#=========================
#
# Test thread command changes, look for frame level reset bug.
#
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
gdb_test "b 122" ".*" ""
gdb_test "r" ".*122.*" ""
# Prep for frame level test--go up/info thread/check frame
#
gdb_test "up" ".*quick_sort.*" ""
gdb_test "up" ".*main.*" ""
send_gdb "i th\n"
gdb_expect {
-re ".*7 thread.* in .* from .* in .* from .* 6 thread.*$gdb_prompt $" {
fail "old thread command, says things twice"
}
-re ".*7 system thread.*6 system th.*5 sys.*4.*3.*2.*1.*work_init.*$gdb_prompt $" {
pass "info threads"
}
-re ".*$gdb_prompt $" { fail "no info thread command" }
timeout { fail "timeout" }
}
# We should have been restored two frames up--check.
#
send_gdb "up\n"
gdb_expect {
-re ".*Initial frame selected.*$gdb_prompt $" {
pass "Frame correctly reset after 'info threads'"
}
-re ".*quick_sort.*$gdb_prompt $" {
fail "Old gdb bug; should be fixed someday"
}
-re ".*$gdb_prompt $" {
fail "real bug--FIX!"
}
timeout { fail "timeout" }
}
# Do it again, only just go to a middle frame, and use another thread.
#
gdb_test "thr 5" ".*" ""
gdb_test "bt" ".* ___ksleep.*_lwp_cond_timedwait.*pthread_cond_wait.*worker.*__pthread_create_system.*" ""
gdb_test "up" ".*1.*_lwp_cond_timedwait.*" ""
gdb_test "up" ".*2.*pthread_cond_wait.*" ""
gdb_test "up" ".*3.*worker.*" ""
gdb_test "i th" ".*7.*6.*work_init.*" ""
gdb_test "f" ".*3.*worker.*" "Frame restored"
gdb_test "p wp->max_pile" ".*= 128.*" "can see vars in frame"
# Thread command changes
#
gdb_test "thr" ".*Current thread is 5.*" "threads-no-num"
gdb_test "thr 6" ".*Switching to thread 6.*" "new switch"
gdb_test "thr" ".*Current thread is 6.*" "check switch"
#gdb_test "thr 6" ".*Current thread is already 6.*" "dup, no switch"
gdb_test "thr app all p x" ".*No symbol.*" ""
gdb_test "thr" ".*Current thread is 6.*" "restore current thread"
#=========================
#
# Test new stepping
#
proc get_hit { } {
global hit2
global hit3
global hit4
global hit5
global hit6
global hit7
global gdb_prompt
send_gdb "cont\n"
gdb_expect {
-re ".*Breakpoint.*145.*$gdb_prompt $" {
send_gdb "thr\n"
gdb_expect {
-re ".*is 7.*$gdb_prompt $" {
set hit7 [expr "$hit7 + 1"]
}
-re ".*is 6.*$gdb_prompt $" {
set hit6 [expr "$hit6 + 1"]
}
-re ".*is 5.*$gdb_prompt $" {
set hit5 [expr "$hit5 + 1"]
}
-re ".*is 4.*$gdb_prompt $" {
set hit4 [expr "$hit4 + 1"]
}
-re ".*is 3.*$gdb_prompt $" {
set hit3 [expr "$hit3 + 1"]
}
-re ".*is 2.*$gdb_prompt $" {
set hit2 [expr "$hit2 + 1"]
}
-re ".*$gdb_prompt $" {
fail "can't see which thread"
}
timeout { fail "timeout" }
}
}
-re ".*$gdb_prompt $" {
fail "thread command"
}
timeout { fail "timeout" }
}
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
gdb_test "break 122" ".*" ""
gdb_test "run" ".*122.*" ""
# Make sure we hit a bp on every thread.
#
# Try one, via thread-specific bps
#
gdb_test "break 145 thr 2" ".*" "set thread-specific bp thr 2"
gdb_test "break 145 thr 3" ".*" "set thread-specific bp thr 3"
gdb_test "break 145 thr 4" ".*" "set thread-specific bp thr 4"
gdb_test "break 145 thr 5" ".*" "set thread-specific bp thr 5"
gdb_test "break 145 thr 6" ".*" "set thread-specific bp thr 6"
gdb_test "break 145 thr 7" ".*" "set thread-specific bp thr 7"
set hit2 0
set hit3 0
set hit4 0
set hit5 0
set hit6 0
set hit7 0
get_hit
get_hit
get_hit
get_hit
get_hit
get_hit
if { [expr "$hit2 == 1"]
&& [expr "$hit3 == 1"]
&& [expr "$hit4 == 1"]
&& [expr "$hit5 == 1"]
&& [expr "$hit6 == 1"]
&& [expr "$hit7 == 1"] } {
pass "thread-specific bps 1"
} else {
fail "thread-specific bps 1"
}
#====================
#
# Now use generic bps
#
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
gdb_test "b 122" ".*" ""
gdb_test "r" ".*122.*" ""
# Make sure we hit a bp on every thread.
#
# Try two, via non-thread-specific bp
#
gdb_test "b 145" ".*" "b 145"
set hit2 0
set hit3 0
set hit4 0
set hit5 0
set hit6 0
set hit7 0
get_hit
get_hit
get_hit
get_hit
get_hit
get_hit
if { [expr "$hit2 == 1"]
&& [expr "$hit3 == 1"]
&& [expr "$hit4 == 1"]
&& [expr "$hit5 == 1"]
&& [expr "$hit6 == 1"]
&& [expr "$hit7 == 1"] } {
pass "thread-specific bps 2"
} else {
fail "thread-specific bps 2"
}
#====================
#
# Complicated (original) test next.
#
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
if ![runto_main] then {
fail "Can't run to main"
return 0
}
# OK, we're at "main", there should be one thread.
#
gdb_test "info thread" ".*\\\* 1 system thread .*main.*" "initial thread"
# Try to see the threads being created: set a breakpoint
# after the creation and go around the loop a few times.
#
gdb_test "break 109" "Breakpoint.*109.*" "set bpt"
gdb_test "c" ".*New thread.*Breakpoint.*109.*" "first continue"
fix_timeout
# Make sure we don't wait (waiting is for attach test)
#
gdb_test "set wait_here = 0" ".*" ""
send_gdb "info thr\n"
gdb_expect {
-re ".*2 system th.*1 sy.*109.*$gdb_prompt $" { pass "saw thread create" }
-re ".*1 system thread.*87.*$gdb_prompt $" { fail "didn't see thread create" }
-re ".*$gdb_prompt $" { fail "no info thread command" }
timeout { fail "timeout" }
}
gdb_test "c" ".*New thread.*Breakpoint.*109.*" "continue"
fix_timeout
send_gdb "info thr\n"
gdb_expect {
-re ".*3 system thread.*2 sys.*\\\* 1 system thread.*109.*$gdb_prompt $" {
pass "saw thread create" }
-re ".*2 system thread.*1 sys.*109.*$gdb_prompt $" {
fail "didn't see thread create"
}
-re ".*1 system thread.*109.*$gdb_prompt $" {
fail "didn't see thread create"
}
-re ".*$gdb_prompt $" {
fail "no info thread command"
}
timeout { fail "timeout" }
}
fix_timeout
gdb_test "clear" ".*Deleted breakpoint.*" ""
# Now go on to the end of thread creation.
#
gdb_test "b 122" ".*" "set bpt 122"
gdb_test "c" ".*New thread.*New thread.*New thread.*122.*" ""
gdb_test "p \$pc" ".*" ""
gdb_test "clear" ".*Deleted breakpoint.*" ""
send_gdb "info thr\n"
gdb_expect {
-re ".*7 system thread.*6 sys.*5.*1 system thread.*122.*$gdb_prompt $"
{ pass "saw thread creates" }
-re ".*$gdb_prompt $"
{ fail "no info thread command" }
timeout { fail "timeout" }
}
# Try a thread-specific breakpoint; we expect the other threads to
# be waiting at this point.
#
gdb_test "thr 3" ".*Switching to thread.*ksleep.*" "thread switch"
gdb_test "i th" ".*\\\* 3 system thread.*" "show new current thread"
gdb_test "up" ".*lwp_cond_timedwait.*" ""
gdb_test "up" ".*pthread_cond_wait.*" ""
gdb_test "up" ".*worker.*144.*" ""
gdb_test "b 145 th 3" ".*Breakpoint.*145.*" "set thread-specific bp"
gdb_test "i b" ".*breakpoint.*breakpoint.*145 thread 3.*" "show thread-specific bp"
gdb_test "c" ".*Breakpoint.*145.*145.*" "hit thread-specific bp"
gdb_test "p \$pc" ".*" ""
# Test thread apply command on thread specific data.
#
gdb_test "thre app all p \$pc" ".*Thread 7.*Thread 6.*Thread 5.*Thread 4.*Thread 3.*Thread 2.*Thread 1.*" "thread apply all"
gdb_test "thr ap 1 3 5 p \$pc" ".*Thread 1.*Thread 3.*Thread 5.*" "thr app 1 3 5"
# Switch again, and test that others continue on a "next"
# This test _could_ fail due to timing issues, but that's
# unlikely.
#
gdb_test "thr 7" ".*Switching to thread.*" ""
# Make sure that "up" stops at __pthread_exit, or
# __pthread_create, the pseudo-roots, and that we
# only see that pseudo-root once.
#
send_gdb "bt\n"
gdb_expect {
-re ".*Error accessing memory address.*" { fail "bt" }
-re ".*pthread_create.*pthread_create.*" { fail "bt" }
-re ".*worker.*pthread_create.*" { pass "bt" }
-re ".*pthread_exit.*" { pass "bt" }
timeout { fail "timeout on bt" }
}
gdb_test "up" ".*" ""
gdb_test "up" ".*" ""
gdb_test "up" ".*144.*" "Up 3"
gdb_test "up" ".*pthread_.*" "Up 4"
gdb_test "up" ".*Initial frame selected; you cannot go up.*" "catch end of thread stack"
#=====================
#
# Things get iffy here; when we step, sometimes the step
# completes, sometimes it doesn't. When it doesn't, we
# hit a bp somewhere else and the step never completes
# (wait_for_inferior just evaporates it).
#
# I think the right answer is that any failures here
# should stick around to trigger later fixing.
#
# Here's the plan:
#
# Bps at 148 (5) and 154 (6) on thread 7 (two bps so we
# see the difference between going around the loop and
# reporting the same bp hit twice).
#
# Bp at 144 on thread 3.
#
# Step out of a library routine.
#
# Either the step will finish or a bp will hit. Try to
# handle all the cases.
#
gdb_test "b 148 thr 7" ".*Breakpoint.*148.*" ""
gdb_test "b 154 thr 7" ".*Breakpoint.*154.*" "set bpt 2"
set hit_154_bp 0
set hit_148_bp 0
set hit_145_bp 0
set step_completed 0
# Expect zero hits
#
gdb_test "i b" ".*" ""
send_gdb "n\n"
gdb_expect {
-re ".*Single stepping.*_lwp_cond_timedwait.*$gdb_prompt $" {
send_gdb "thr\n"
gdb_expect {
-re ".*is 7.*$gdb_prompt $" {
set step_completed 1
pass "completed step in library code"
}
-re ".*$gdb_prompt $" {
fail "completed step in library code, but in wrong thread"
}
timeout { fail "timeout" }
}
}
-re ".*Single stepping.*Switched to thread 3.*Breakpoint.*$gdb_prompt $" {
pass "step cancelled; hit bp due to thread parallelism"
set hit_145_bp 1
}
-re ".*Single stepping.*Switched to thread 7.*Breakpoint.*148.*$gdb_prompt $" {
pass "step cancelled; hit bp due to thread parallelism"
set hit_148_bp 1
}
-re ".*Single stepping.*Switched to thread 7.*Breakpoint.*154.*$gdb_prompt $" {
pass "step cancelled; hit bp due to thread parallelism"
set hit_154_bp 1
}
-re ".*$gdb_prompt $" {
send_gdb "thr\n"
gdb_expect {
-re ".*is 7.*$gdb_prompt $" {
fail "No event?"
}
-re ".*$gdb_prompt $" {
fail "No event"
}
timeout { fail "timeout" }
}
}
timeout { fail "timeout" }
}
# Sometimes used to get SIGTRAP here; that should be fixed
#
# Expect appropriate hits of bpt; too much work to parse
# result and check...
#
gdb_test "i b" ".*" ""
send_gdb "c\n"
gdb_expect {
-re ".*SIGTRAP.*$gdb_prompt $" {
fail "got SIGTRAP"
}
-re ".*Switched to thread 7.*Breakpoint.*154.*$gdb_prompt $" {
if { $hit_154_bp == 1 } {
fail "re-hit old bp"
} else {
pass "continue; hit parallel event after continue"
}
set hit_154_bp 1
}
-re ".*Switched to thread 7.*Breakpoint.*148.*$gdb_prompt $" {
if { $hit_148_bp == 1 } {
fail "re-hit old bp"
} else {
pass "continue; hit parallel event after continue"
}
set hit_148_bp 1
}
-re ".*Breakpoint.*154.*$gdb_prompt $" {
if { $hit_154_bp == 1 } {
fail "re-hit old bp"
} else {
send_gdb "thr\n"
gdb_expect {
-re ".*is 7.*$gdb_prompt $" {
pass "continue; hit parallel event after continue"
}
-re ".*$gdb_prompt $" {
fail "hit bp in wrong thread"
}
timeout { fail "timeout" }
}
}
set hit_154_bp 1
}
-re ".*Breakpoint.*148.*$gdb_prompt $" {
if { $hit_148_bp == 1 } {
fail "re-hit old bp"
} else {
send_gdb "thr\n"
gdb_expect {
-re ".*is 7.*$gdb_prompt $" {
pass "continue; hit parallel event after continue"
}
-re ".*$gdb_prompt $" {
fail "hit bp in wrong thread"
}
timeout { fail "timeout" }
}
}
set hit_148_bp 1
}
-re ".*Breakpoint.*145.*$gdb_prompt $" {
if { $hit_145_bp == 1 } {
fail "re-hit old bp"
} else {
send_gdb "thr\n"
gdb_expect {
-re ".*is 3.*$gdb_prompt $" {
pass "continue; hit parallel event after continue"
}
-re ".*$gdb_prompt $" {
fail "hit bp in wrong thread"
}
timeout { fail "timeout" }
}
}
set hit_145_bp 1
}
-re ".*_lwp_cond_timedwait.*$gdb_prompt $" {
pass "continue; hit step completion after continue"
}
-re ".*Program exited normally.*" {
fail "Program ended? HOW?"
}
-re ".*$gdb_prompt $" {
fail "Unexpected event"
}
timeout { fail "timeout" }
}
# There are a number of places we _could_ be now;
# this is the price of really running in parallel.
#
send_gdb "n\n"
gdb_expect {
-re ".*Switched to thread 7.*pthread_cond_wait.*$gdb_prompt $" {
if { $step_completed } {
fail "step already completed"
} else {
pass "finish step"
}
}
-re ".*pthread_cond_wait.*$gdb_prompt $" {
#
# Unlikely, but we might finish the range step from inside
# ksleep, before anything else.
#
if { $step_completed } {
fail "step already completed"
} else {
send_gdb "thr\n"
gdb_expect {
-re ".*is 7.*$gdb_prompt $" {
pass "finish step"
}
-re ".*$gdb_prompt $" {
fail "step in wrong thread"
}
timeout { fail "timeout" }
}
}
}
-re ".*Switched to thread.*Breakpoint.*145.*$gdb_prompt $" {
pass "auto-switch thread"
}
-re ".*Breakpoint.*145.*$gdb_prompt $" {
pass "auto-switch not needed, ok"
}
-re ".*140.*while.*n_pile.*$gdb_prompt $" {
#
# This is just going around the loop from the 154 bp.
#
send_gdb "thr\n"
gdb_expect {
-re ".*is 7.*$gdb_prompt $" {
pass "finish step"
}
-re ".*$gdb_prompt $" {
fail "step in wrong thread"
}
timeout { fail "timeout" }
}
}
-re ".*149.*ptr = wp.*pile.*$gdb_prompt $" {
#
# This is just going around the loop from the 148 bp.
#
if { $hit_154_bp } {
send_gdb "thr\n"
gdb_expect {
-re ".*is 7.*$gdb_prompt $" {
pass "finish step"
}
-re ".*$gdb_prompt $" {
fail "step in wrong thread"
}
timeout { fail "timeout" }
}
} else {
pass "step from 149 but didn't hit it first"
}
}
-re ".*Breakpoint 5.*154.*$gdb_prompt $" {
gdb_test "i b" ".*" ""
if { $hit_154_bp } {
fail "hit bp again?"
} else {
pass "hit bp"
}
}
-re ".*Breakpoint 5.*148.*$gdb_prompt $" {
gdb_test "i b" ".*" ""
if { $hit_148_bp } {
fail "hit bp again?"
} else {
pass "hit bp"
}
}
-re ".*$gdb_prompt $" {
fail "no step finished"
}
timeout { fail "timeout on 'next'" }
}
# Let's get into some kind of known state again.
#
gdb_test "thr 7" ".*" ""
gdb_test "info thread" ".*" ""
#gdb_test "i b" ".*" ""
# Leave breakpoint "154 thr 7" as only live bp.
#
gdb_test "d 1" ".*" "del main bp"
gdb_test "d 4" ".*" "thread-specific bpt delete"
gdb_test "d 5" ".*" "other bp delete"
send_gdb "i b\n"
gdb_expect {
-re ".*breakpoint.*breakpoint.*$gdb_prompt $" {
fail "more than one bp left"
}
-re ".*breakpoint.*154.*thread.*7.*$gdb_prompt $" {
pass "Only one bp left"
}
-re ".*$gdb_prompt $" {
fail "Wrong or no bp left"
}
timeout { fail "timeout on info b" }
}
send_gdb "c\n"
gdb_expect {
-re ".*SIGTRAP.*Switched to thread.*$gdb_prompt $" {
fail "SIGTRAP error; lost thread-specific bpt"
}
-re ".*SIGTRAP.*Switched to thread.*154.*$gdb_prompt $" {
fail "SIGTRAP, but hit right thread-specific bpt"
}
-re ".*Switched to thread.*Breakpoint.*154.*$gdb_prompt $" {
pass "auto-switch back"
}
-re ".*Breakpoint.*154.*$gdb_prompt $" {
pass "step to bp"
}
-re ".*$gdb_prompt $" {
fail "auto-switch back"
}
-re ".*Program exited normally.*$gdb_prompt $" {
fail "step lost"
}
timeout {
fail "timeout"
}
}
fix_timeout
gdb_test "cle" ".*Deleted breakpoint.*" "delete last breakpoint"
# Sometimes get SIGTRAP here. Continue sometimes gets another...
#
send_gdb "c\n"
gdb_expect {
-re ".*SIGTRAP.*154.*154.*$gdb_prompt $" {
fail "SIGTRAP on deleted bp 154 "
send_gdb "c\n"
gdb_expect {
-re ".*$gdb_prompt $" { pass "fixup"}
timeout { fail "fixup" }
}
}
-re ".*SIGTRAP.*144.*145.*$gdb_prompt $" {
fail "SIGTRAP on deleted bp 145 "
send_gdb "c\n"
gdb_expect {
-re ".*$gdb_prompt $" { pass "fixup"}
timeout { fail "fixup" }
}
}
-re ".*SIGTRAP.*148.*148.*$gdb_prompt $" {
fail "SIGTRAP on deleted bp 148 "
send_gdb "c\n"
gdb_expect {
-re ".*$gdb_prompt $" { pass "fixup"}
timeout { fail "fixup" }
}
}
-re ".*SIGTRAP.*$gdb_prompt $" {
fail "unknown SIGTRAP"
send_gdb "c\n"
gdb_expect {
-re ".*$gdb_prompt $" { pass "fixup"}
timeout { fail "fixup" }
}
}
-re ".*Program exited.*$gdb_prompt $" {
pass "run to end"
}
-re ".*$gdb_prompt $" {
fail "run to end"
send_gdb "c\n"
gdb_expect {
-re ".*$gdb_prompt $" { pass "fixup"}
timeout { fail "fixup" }
}
}
timeout { fail "timeout" }
}
gdb_test "p \$pc" ".*No registers.*" "program done"
# Done!
#
gdb_exit
set timeout $oldtimeout
set verbose $oldverbose
# execute_anywhere "rm -f ${binfile}"
#
return 0

View File

@ -0,0 +1,190 @@
# 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
# Tests of wide register displays for GDB on HPPA 2.0 machines
# use this to debug:
#log_user 1
if $tracelevel then {
strace $tracelevel
}
if ![istarget "hppa*-*-*"] {
verbose "Wide register test ignored for non-hppa targets."
return
}
set testfile "reg_test"
set srcfile ${testfile}.s
set binfile ${objdir}/${subdir}/${testfile}
# To build a pa 2.0 executable
#
# as -o reg_test reg_test.s
# or
# cc -g -o reg_test reg_test.s
#
# The +DA2.0N flag doesn't seem to be needed.
#
# Don't reject if there are warnings, as we expect this warning:
#
# (Warning) At least one PA 2.0 object file (pa2.0_test2.o) was detected.
# The linked output may not run on a PA 1.x system.
#
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."
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
# test machine--there's no 2.0n architecture, so we have
# to try to run the app.
#
send_gdb "break main\n"
gdb_expect {
-re "Breakpoint.*$gdb_prompt $" {
pass "initial set-up"
}
-re ".*$gdb_prompt $" {
fail "initial set-up"
}
timeout {
fail "initial set-up (timeout)"
}
}
send_gdb "run\n"
gdb_expect {
-re ".*Executable file incompatible with hardware.*$gdb_prompt $" {
# Not hppa2.0 machine
#
return 0
}
-re "Cannot exec.*$gdb_prompt $" {
# Not hppa2.0 machine
#
return 0
}
-re ".*Starting program:.*$gdb_prompt $" {
pass "Ready to start test"
}
timeout {
fail "initial set-up, part 2 (timeout)"
return 0
}
}
# Let the program set known values. This secretly deletes
# the breakpoint at main and re-runs to mainend.
#
runto mainend
# Look for known values
#
gdb_test "info reg r1" "r1 1"
gdb_test "info reg r4" "r4 2"
gdb_test "info reg r5" "r5 4"
gdb_test "info reg r6" "r6 8"
gdb_test "info reg r7" "r7 10"
gdb_test "info reg r8" "r8 20"
gdb_test "info reg r9" "r9 40"
gdb_test "info reg r10" "r10 80"
gdb_test "info reg r11" "r11 100"
gdb_test "info reg r12" "r12 200"
gdb_test "info reg r13" "r13 400"
gdb_test "info reg r14" "r14 800"
gdb_test "info reg r15" "r15 1000"
gdb_test "info reg r16" "r16 2000"
# Two odd variants that GDB supports are:
# "1" means "r1", and
# "$1" means "r1"
#
gdb_test "info reg 1 4" "r1 1.*r4 2"
gdb_test "info reg \$1" "r1 1"
# Verify that GDB responds gracefully to a register ID number that
# is out of range.
#
gdb_test "info reg 999" "999: invalid register"
# Make sure the floating point status and error registers
# don't show up as floating point numbers!
#
gdb_test "info reg fpsr" ".*fpsr 0.*" "fpsr"
gdb_test "info reg fpe1" ".*fpe1 0.*" "fpe1"
gdb_test "info reg fpe2" ".*fpe2 0.*" "fpe2"
gdb_test "info reg fpe3" ".*fpe3 0.*" "fpe3"
gdb_test "info reg fpe4" ".*fpe4 0.*" "fpe4"
gdb_test "info reg fpe5" ".*fpe5 0.*" "fpe5"
gdb_test "info reg fpe6" ".*fpe6 0.*" "fpe6"
gdb_test "info reg fpe7" ".*fpe7 0.*" "fpe7"
gdb_test "info reg fr4" ".*fr4.*(double precision).* 1"
gdb_test "info reg fr5" ".*fr5.*(double precision).* 2"
gdb_test "info reg fr6" ".*fr6.*(double precision).* 2"
gdb_test "info reg fr7" ".*fr7.*(double precision).* 4"
gdb_test "info reg fr8" ".*fr8.*(double precision).* 8"
gdb_test "info reg fr9" ".*fr9.*(double precision).* 32"
gdb_test "info reg fr10" ".*fr10.*(double precision).* 256"
gdb_test "info reg r19" "r19 deadbeefbadcadee"
# Need to add test of use of $<register-name>
#
# Q: How do you say a literal "$" in expect?
# A: You say "\$". A literal "\" is "\\".
#
# Please note that this test will fail as long as we are running
# in 32-bit mode: it will produce "$1 = 0xbadcadee". To fix it
# would require building a real 64-bit gdb (expression evaluation,
# in particular).
#
send_gdb "p/x \$r19\n"
gdb_expect {
-re ".*= 0xdeadbeefbadcadee.*$gdb_prompt $" {
pass "64-bit works"
}
-re ".*= 0xbadcadee.*$gdb_prompt $" {
pass "32-bit extract when using PRINT; expected but not good"
}
-re ".*$gdb_prompt $" {
fail "didn't print any part of right value"
}
timeout {
fail "timeout on print"
}
}
# Need to add tests of setting wide regs too. E.g.
#
# set $r4 = 0x1234567890123456
# p/x $r4
#
# done
#
gdb_exit
remote_exec build "rm -f ${binfile}"
return 0

View File

@ -0,0 +1,96 @@
; assemble as "as -o reg_test.exe reg_test.s"
; or
; cc -g -o +DA2.0N
;
; PA-RISC 2.0 register contents test.
;
.level 2.0
.code
.export main,ENTRY
.export mainend,CODE
.export lab1,CODE
.space $TEXT$
.subspa $CODE$
main
.proc
.callinfo NO_CALLS,FRAME=0
.entry
;; Test we have right register numbers
;;
ADD %r0,%r0,%r1 ; 0
LDI 1,%r1 ; 1
;;
;; Don't put anything into r2 or r3--they are special registers.
;;
ADD %r1,%r1,%r4 ; 2
ADD %r4,%r4,%r5 ; 4
ADD %r5,%r5,%r6 ; 8
ADD %r6,%r6,%r7 ; 16
ADD %r7,%r7,%r8 ; 32
ADD %r8,%r8,%r9 ; 64
ADD %r9,%r9,%r10 ; 128
ADD %r10,%r10,%r11 ; 256
ADD %r11,%r11,%r12 ; 512
ADD %r12,%r12,%r13 ; 1024
ADD %r13,%r13,%r14 ; 2048
ADD %r14,%r14,%r15 ; 4096
ADD %r15,%r15,%r16 ; 9192
;; Test high bits, to be sure we show them.
;;
LDI 0xde,%r19 ; "de"
DEPD,Z %r19,55,56,%r19 ; "de00"
LDI 0xad,%r18 ; "ad"
ADD %r18,%r19,%r19 ; "dead"
DEPD,Z %r19,55,56,%r19 ; "dead00"
LDI 0xbe,%r18 ; "be"
ADD %r18,%r19,%r19 ; "deadbe"
DEPD,Z %r19,55,56,%r19 ; "deadbe00"
LDI 0xef,%r18 ; "ef"
ADD %r18,%r19,%r19 ; "deadbeef"
;
DEPD,Z %r19,55,56,%r19 ; "deadbeef00"
LDI 0xba,%r18 ; "ba"
ADD %r18,%r19,%r19 ; "deadbeefba"
DEPD,Z %r19,55,56,%r19 ; "deadbeefba00"
LDI 0xdc,%r18 ; "dc"
ADD %r18,%r19,%r19 ; "deadbeefbadc"
DEPD,Z %r19,55,56,%r19 ; "deadbeefbadc00"
LDI 0xad,%r18 ; "ad"
ADD %r18,%r19,%r19 ; "deadbeefbadcad"
DEPD,Z %r19,55,56,%r19 ; "deadbeefbadcad00"
LDI 0xee,%r18 ; "ee"
ADD %r18,%r19,%r19 ; "deadbeefbadcadee"
lab1 ;; Test floating point registers
;;
LDIL LR'one,%r22 ;
FLDD RR'one(%r22),%fr4 ; 1.0
FLDD RR'one+8(%r22),%fr5 ; 2.0
FLDD RR'one+8(%r22),%fr6 ; 2.0
FMPY,DBL %fr5,%fr6,%fr7 ; 4.0
FMPY,DBL %fr6,%fr7,%fr8 ; 8.0
FMPY,DBL %fr7,%fr8,%fr9 ; 32.0
FMPY,DBL %fr8,%fr9,%fr10 ; 256.0
;; The NOP prevents anything from end.o or crt0.o from
;; being appended immediately after "mainend". If that
;; happens, then we may have other labels that have the
;; same address as "mainend", and thus the debugger
;; may symbolize this PC to something other than "mainend".
mainend
NOP
.exit
.procend
.space $TEXT$
.subspa $CODE$
.subspa $LIT$ ;; <don't use> ,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=16
one
.align 8
.stringz "?\xF0\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00"
.end

View File

@ -0,0 +1,43 @@
enum Normal {
red,
blue,
green
};
short enum Small {
pink,
cyan,
grey
};
char enum Tiny {
orange,
yellow,
brown
};
main()
{
enum Normal normal[3];
short enum Small small[3];
char enum Tiny tiny[3];
int i;
for (i=0; i < 3; i++)
{
normal[i] = (enum Normal) i;
small[i] = (short enum Small) i;
tiny[i] = (char enum Tiny) i;
}
normal[0] = 0; /* place to hang a breakpoint */
}

View File

@ -0,0 +1,162 @@
# Copyright (C) 1997, 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
# GDB tests for sized enumerations
# This is aimed at HP-UX systems. The HP C compiler
# allows specifying "char" or "short" for an enum, to
# indicate that it is 1 or 2 bytes long.
# This file was written by Satish Pai <pai@apollo.hp.com>
# 1997-09-24
if $tracelevel then {
strace $tracelevel
}
#
# test running programs
#
set prms_id 0
set bug_id 0
set testfile "sized-enum"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile}] {
return -1
}
if {[skip_hp_tests $gcc_compiled]} then { continue }
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."
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
#
# set it up at a breakpoint so we can play with the variable values
#
if ![runto_main] then {
perror "couldn't run to breakpoint"
continue
}
# set a breakpoint and go there
send_gdb "break 34\n"
gdb_expect {
-re "Breakpoint \[0-9\] at.*$gdb_prompt $" { pass "set break 34" }
-re "$gdb_prompt $" { fail "set break 34" }
timeout { fail "(timeout) set break 34" }
}
send_gdb "continue\n"
gdb_expect {
-re "Continuing\\.\r\n\r\nBreakpoint \[0-9\]*, main....at.*sized-enum\\.c:34\r\n34.*\r\n$gdb_prompt $" { pass "continue" }
-re "$gdb_prompt $" { fail "continue" }
timeout { fail "(timeout) continue" }
}
# print stuff
send_gdb "print normal\n"
gdb_expect {
-re "\\$\[0-9\]* = \\{red, blue, green\\}.*$gdb_prompt $" { pass "print normal" }
-re "$gdb_prompt $" { fail "print normal" }
timeout { fail "(timeout) print normal" }
}
send_gdb "print small\n"
gdb_expect {
-re "\\$\[0-9\]* = \\{pink, cyan, grey\\}.*$gdb_prompt $" { pass "print small" }
-re "$gdb_prompt $" { fail "print small" }
timeout { fail "(timeout) print small" }
}
send_gdb "print tiny\n"
gdb_expect {
-re "\\$\[0-9\]* = \\{orange, yellow, brown\\}.*$gdb_prompt $" { pass "print tiny" }
-re "$gdb_prompt $" { fail "print tiny" }
timeout { fail "(timeout) print tiny" }
}
# print type sizes
send_gdb "print sizeof (Normal)\n"
gdb_expect {
-re "\\$\[0-9\]* = 4.*$gdb_prompt $" { pass "print sizeof (Normal)" }
-re "$gdb_prompt $" { fail "print sizeof (Normal)" }
timeout { fail "(timeout) print sizeof (Normal)" }
}
send_gdb "print sizeof (Small)\n"
gdb_expect {
-re "\\$\[0-9\]* = 2.*$gdb_prompt $" { pass "print sizeof (Small)" }
-re "$gdb_prompt $" { fail "print sizeof (Small)" }
timeout { fail "(timeout) print sizeof (Small)" }
}
send_gdb "print sizeof (Tiny)\n"
gdb_expect {
-re "\\$\[0-9\]* = 1.*$gdb_prompt $" { pass "print sizeof (Tiny)" }
-re "$gdb_prompt $" { fail "print sizeof (Tiny)" }
timeout { fail "(timeout) print sizeof (Tiny)" }
}
# print types
send_gdb "ptype normal\n"
gdb_expect {
-re "type = enum Normal \\{red, blue, green\\} \\\[3\\\].*$gdb_prompt $" { pass "ptype normal" }
-re "$gdb_prompt $" { fail "ptype normal" }
timeout { fail "(timeout) ptype normal" }
}
send_gdb "ptype small\n"
gdb_expect {
-re "type = short enum Small \\{pink, cyan, grey\\} \\\[3\\\].*$gdb_prompt $" { pass "ptype small" }
-re "$gdb_prompt $" { fail "ptype small" }
timeout { fail "(timeout) ptype small" }
}
send_gdb "ptype tiny\n"
gdb_expect {
-re "type = char enum Tiny \\{orange, yellow, brown\\} \\\[3\\\].*$gdb_prompt $" { pass "ptype tiny" }
-re "$gdb_prompt $" { fail "ptype tiny" }
timeout { fail "(timeout) ptype tiny" }
}
# convert to int
send_gdb "print (int) blue\n"
gdb_expect {
-re "\\$\[0-9\]* = 1.*$gdb_prompt $" { pass "print (int) blue" }
-re "$gdb_prompt $" { fail "print (int) blue" }
timeout { fail "(timeout) print (int) blue" }
}
send_gdb "print (int) cyan\n"
gdb_expect {
-re "\\$\[0-9\]* = 1.*$gdb_prompt $" { pass "print (int) cyan" }
-re "$gdb_prompt $" { fail "print (int) cyan" }
timeout { fail "(timeout) print (int) cyan" }
}
send_gdb "print (int) yellow\n"
gdb_expect {
-re "\\$\[0-9\]* = 1.*$gdb_prompt $" { pass "print (int) yellow" }
-re "$gdb_prompt $" { fail "print (int) yellow" }
timeout { fail "(timeout) print (int) yellow" }
}

View File

@ -0,0 +1,360 @@
# start_stop.exp -- Expect script to test a threaded pgm which has terminating threads
# Copyright (C) 1992 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
# Comment out for now, since this test is (sometimes?) hanging on 11.0
#
# return 0
# use this to debug:
#
#log_user 1
# Thread stuff is _slow_; prepare for long waits.
#
# Further, this test has some "null" lines designed
# to consume output from gdb that was too late to be
# matched (sequence is "gdb_test" sends; timeout and
# on to next send; result finally comes in; mismatch).
#
# The null command is 'gdb_test "p \$pc" ".*" ""'
# NOTE: this command undoes any up/down stuff!
#
proc pre_timeout {} {
global timeout
set timeout [expr "$timeout + 100"]
}
proc post_timeout {} {
global timeout
global oldtimeout
set timeout $oldtimeout
gdb_test "p \$pc" ".*" ""
}
if $tracelevel then {
strace $tracelevel
}
if { ![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"] } {
verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
return 0
}
set testfile start-stop
set srcfile ${srcdir}/${subdir}/${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile}] {
return -1
}
# To build the executable we need to link against the thread library.
#
# cc -Ae -g -o start-stop -lpthread start-stop.c
#
#compile "${srcfile} -Ae -g -lpthread -o ${binfile}"
if {$gcc_compiled == 0} {
set additional_flags "additional_flags=-Ae"
} else {
set additional_flags ""
}
if { [gdb_compile "${srcdir}/${subdir}/${testfile}.c" "${binfile}.o" object [list debug $additional_flags]] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
remote_exec build "ld /usr/ccs/lib/crt0.o ${binfile}.o -lcl -lpthread -lc /opt/langtools/lib/end.o -o ${binfile}"
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
if ![runto_main] then {
fail "Can't run to main"
return 0
}
set oldtimeout $timeout
#set timeout [expr "$timeout + 200"]
set oldverbose $verbose
#set verbose 40
gdb_test "b do_pass" ".*" "set do_pass bp"
gdb_test "c" ".*Breakpoint.*do_pass.*" "run to do_pass"
# Should be only one thread.
#
pre_timeout
send_gdb "info thread\n"
gdb_expect {
-re ".*2 process.*$gdb_prompt $" { fail "Old code for 'thread.c'" }
-re ".*2 system thread.*1 sys.*$gdb_prompt $" { fail "Too many threads" }
-re ".*1 system thread.*$gdb_prompt $" { pass "Just one thread" }
-re ".*$gdb_prompt $" { fail "no thread info" }
timeout { fail "timeout on info thread 1" }
}
post_timeout
# Run to a point after the thread creates (105 is just
# before the first join).
#
# The "== Thread" stuff is output from the computing threads.
#
gdb_test "b 105" ".*Breakpoint.*" "set 105 bp"
pre_timeout
send_gdb "c\n"
gdb_expect {
-re ".*== Thread.*== Thread.*== Thread.*105.*$gdb_prompt $" {
pass "new threads created and ended"
set threads_exist 0
}
-re ".*== Thread.*== Thread.*105.*$gdb_prompt $" {
pass "new threads created and ended"
set threads_exist 1
}
-re ".*== Thread.*.*105.*$gdb_prompt $" {
pass "new threads created and ended"
set threads_exist 2
}
-re ".*New thread.*New th.*New th.*105.*$gdb_prompt $" {
pass "new threads created"
set threads_exist 3
}
-re ".*Breakpoint.*105.*$gdb_prompt $" {
set threads_exist 0
fail "didn't see any threads"
}
-re ".*$gdb_prompt $" {
set threads_exist 0
fail "didn't even hit bp"
}
timeout {
set threads_exist -1
fail "timeout on continue"
}
}
# Look at the threads again. We expect that some of
# the threads may have already finished execution.
#
send_gdb "info thread\n"
gdb_expect {
-re ".*4.*3.*2.* 1.*thread.*$gdb_prompt $" { set seen_threads 3 }
-re ".*3.*2.* 1.*thread.*$gdb_prompt $" { set seen_threads 2 }
-re ".*2.* 1.*thread.*$gdb_prompt $" { set seen_threads 1 }
-re ".* 1.*thread.*$gdb_prompt $" { set seen_threads 0 }
-re ".*$gdb_prompt $" { set seen_threads 0 }
timeout {
set seen_threads -10
fail "timeout on second info thread"
}
}
post_timeout
if { $seen_threads == $threads_exist } {
pass "saw all threads that existed"
} else {
if { $seen_threads > $threads_exist } {
fail "may have seen threads that didn't finish exiting yet"
} else {
fail "didn't see live threads"
}
}
gdb_test "cle" ".*Deleted.*" "del bp at 105"
# Check that threads are being consumed at the join call.
# We expect to join three times. If we ever see the bp at
# 111, we've gone too far.
#
gdb_test "b 106" ".*Breakpoint.*106.*" "set bp at 106"
gdb_test "b 111" ".*Breakpoint.*111.*" "set bp at 111"
# This one is sure: we're already in the loop.
#
gdb_test "c" ".*Breakpoint.*106.*" "hit bp at 106 1st time, 2 left"
# Did we go around the loop again?
#
send_gdb "c\n"
gdb_expect {
-re ".*Breakpoint.*111.*" {
fail "didn't join right 1"
gdb_test "cle" ".*" ""
}
-re ".*Breakpoint.*106.*" {
pass "hit bp at 106 2nd time, 1 left"
send_gdb "c\n"
gdb_expect {
-re ".*Breakpoint.*111.*" {
fail "didn't join right 2"
gdb_test "cle" ".*" ""
}
-re ".*Breakpoint.*106.*" {
pass "hit bp at 106 3rd time, 0 left"
gdb_test "cle" ".*" ""
gdb_test "c" ".*Breakpoint.*111.*" ""
gdb_test "cle" ".*" ""
}
timeout { fail "timeout going around the loop"}
}
}
timeout { fail "timeout getting to 106"}
}
# Should only be one thread now.
#
pre_timeout
send_gdb "info thread\n"
gdb_expect {
-re ".*2 system thread.*1 sys.*$gdb_prompt $" { fail "Too many threads" }
-re ".*1 system th.*$gdb_prompt $" { pass "Just one thread" }
-re ".*$gdb_prompt $" { pass "One thread shown as no threads, ok" }
timeout { fail "timeout third info thread" }
}
post_timeout
#============================= Begin pass 2 ===========
#
# Ok, go around again
#
gdb_test "c" ".*Breakpoint.*do_pass.*" "hit do_pass bp again 2"
gdb_test "b 105" ".*Breakpoint.*" "set 105 bp 2"
pre_timeout
send_gdb "c\n"
gdb_expect {
-re ".*== Thread.*== Thread.*== Thread.*$gdb_prompt $" {
pass "new threads created and ended 2"
set threads_exist 0
}
-re ".*== Thread.*== Thread.*$gdb_prompt $" {
pass "new threads created and ended 2"
set threads_exist 1
}
-re ".*== Thread.*$gdb_prompt $" {
pass "new threads created and ended 2"
set threads_exist 2
}
-re ".*New system thread.*New sys.*New.*105.*$gdb_prompt $" {
pass "new threads created 2"
set threads_exist 3
}
timeout {
set threads_exist -1
fail "timeout on continue 2"
}
}
# Look at the threads again. We expect that some of
# the threads may have already finished execution.
#
send_gdb "info thread\n"
gdb_expect {
-re ".*4.*3.*2.* 1.*thread.*$gdb_prompt $" { set seen_threads 3 }
-re ".*3.*2.* 1.*thread.*$gdb_prompt $" { set seen_threads 2 }
-re ".*2.* 1.*thread.*$gdb_prompt $" { set seen_threads 1 }
-re ".* 1.*thread.*$gdb_prompt $" { set seen_threads 0 }
-re ".*$gdb_prompt $" { set seen_threads 0 }
timeout {
set seen_threads -10
fail "timeout on second info thread 2"
}
}
post_timeout
if { $seen_threads == $threads_exist } {
pass "saw all threads that existed"
} else {
if { $seen_threads > $threads_exist } {
fail "may have seen threads that didn't finish exiting yet 2"
} else {
fail "didn't see live threads 2"
}
}
gdb_test "cle" ".*Deleted.*" "del bp at 105 2"
# Check that threads are being consumed at the join call.
# We expect to join three times. If we ever see the bp at
# 111, we've gone too far.
#
gdb_test "b 106" ".*Breakpoint.*106.*" "set bp at 106 2"
gdb_test "b 111" ".*Breakpoint.*111.*" "set bp at 111 2"
# This one is sure: we're already in the loop.
#
gdb_test "c" ".*Breakpoint.*106.*" "hit bp at 106 1st time, 2 left 2"
# Did we go around the loop again?
#
send_gdb "c\n"
gdb_expect {
-re ".*Breakpoint.*111.*" {
fail "didn't join right 1, pass 2"
gdb_test "cle" ".*" ""
}
-re ".*Breakpoint.*106.*" {
pass "hit bp at 106 2nd time, 1 left, pass 2"
send_gdb "c\n"
gdb_expect {
-re ".*Breakpoint.*111.*" {
fail "didn't join right 2, pass 2"
gdb_test "cle" ".*" ""
}
-re ".*Breakpoint.*106.*" {
pass "hit bp at 106 3rd time, 0 left, pass 2"
gdb_test "cle" ".*" ""
gdb_test "c" ".*Breakpoint.*111.*" ""
gdb_test "cle" ".*" ""
}
timeout { fail "timeout going around loop, pass 2"}
}
}
timeout { fail "timeout continue to 106, pass 2"}
}
# Should only be one thread now.
#
pre_timeout
send_gdb "info thread\n"
gdb_expect {
-re ".*2 system thread.*1 sys.*$gdb_prompt $" { fail "Too many threads, pass 2" }
-re ".*1 system thread.*$gdb_prompt $" { pass "Just one thread, pass 2" }
-re ".*$gdb_prompt $" { pass "One thread shown as no threads, ok, pass 2" }
timeout { fail "timeout last info thread, pass 2" }
}
post_timeout
# Done!
#
gdb_exit
set timeout $oldtimeout
set verbose $oldverbose
# execute_anywhere "rm -f ${binfile}"
#
return 0

View File

@ -0,0 +1,785 @@
/* This test code is from Wendell Baker (wbaker@comet.berkeley.edu) */
#include <stddef.h>
int a_i;
char a_c;
double a_d;
typedef void *Pix;
int
f(int i)
{ return 0; }
int
f(int i, char c)
{ return 0; }
int
f(int i, char c, double d)
{ return 0; }
int
f(int i, char c, double d, char *cs)
{ return 0; }
int
f(int i, char c, double d, char *cs, void (*fig)(int, char))
{ return 0; }
int
f(int i, char c, double d, char *cs, void (*fig)(char, int))
{ return 0; }
class R {
public:
int i;
};
class S {
public:
int i;
};
class T {
public:
int i;
};
char g(char, const char, volatile char)
{ return 'c'; }
char g(R, char&, const char&, volatile char&)
{ return 'c'; }
char g(char*, const char*, volatile char*)
{ return 'c'; }
char g(S, char*&, const char*&, volatile char*&)
{ return 'c'; }
signed char g(T,signed char, const signed char, volatile signed char)
{ return 'c'; }
signed char g(T, R, signed char&, const signed char&, volatile signed char&)
{ return 'c'; }
signed char g(T, signed char*, const signed char*, volatile signed char*)
{ return 'c'; }
signed char g(T, S, signed char*&, const signed char*&, volatile signed char*&)
{ return 'c'; }
unsigned char g(unsigned char, const unsigned char, volatile unsigned char)
{ return 'c'; }
unsigned char g(R, unsigned char&, const unsigned char&, volatile unsigned char&)
{ return 'c'; }
unsigned char g(unsigned char*, const unsigned char*, volatile unsigned char*)
{ return 'c'; }
unsigned char g(S, unsigned char*&, const unsigned char*&, volatile unsigned char*&)
{ return 'c'; }
short g(short, const short, volatile short)
{ return 0; }
short g(R, short&, const short&, volatile short&)
{ return 0; }
short g(short*, const short*, volatile short*)
{ return 0; }
short g(S, short*&, const short*&, volatile short*&)
{ return 0; }
signed short g(T, signed short, const signed short, volatile signed short)
{ return 0; }
signed short g(T, R, signed short&, const signed short&, volatile signed short&)
{ return 0; }
signed short g(T, signed short*, const signed short*, volatile signed short*)
{ return 0; }
signed short g(T, S, double, signed short*&, const signed short*&, volatile signed short*&)
{ return 0; }
unsigned short g(unsigned short, const unsigned short, volatile unsigned short)
{ return 0; }
unsigned short g(R, unsigned short&, const unsigned short&, volatile unsigned short&)
{ return 0; }
unsigned short g(unsigned short*, const unsigned short*, volatile unsigned short*)
{ return 0; }
unsigned short g(S, unsigned short*&, const unsigned short*&, volatile unsigned short*&)
{ return 0; }
int g(int, const int, volatile int)
{ return 0; }
int g(R, int&, const int&, volatile int&)
{ return 0; }
int g(int*, const int*, volatile int*)
{ return 0; }
int g(S, int*&, const int*&, volatile int*&)
{ return 0; }
signed int g(T, signed int, const signed int, volatile signed int)
{ return 0; }
signed int g(T, R, signed int&, const signed int&, volatile signed int&)
{ return 0; }
signed int g(T, signed int*, const signed int*, volatile signed int*)
{ return 0; }
signed int g(T, S, signed int*&, const signed int*&, volatile signed int*&)
{ return 0; }
unsigned int g(unsigned int, const unsigned int, volatile unsigned int)
{ return 0; }
unsigned int g(R, unsigned int&, const unsigned int&, volatile unsigned int&)
{ return 0; }
unsigned int g(unsigned int*, const unsigned int*, volatile unsigned int*)
{ return 0; }
unsigned int g(S, unsigned int*&, const unsigned int*&, volatile unsigned int*&)
{ return 0; }
long g(long, const long, volatile long)
{ return 0; }
long g(R, long&, const long&, volatile long&)
{ return 0; }
long g(long*, const long*, volatile long*)
{ return 0; }
long g(S, long*&, const long*&, volatile long*&)
{ return 0; }
signed long g(T, signed long, const signed long, volatile signed long)
{ return 0; }
signed long g(T, R, signed long&, const signed long&, volatile signed long&)
{ return 0; }
signed long g(T, signed long*, const signed long*, volatile signed long*)
{ return 0; }
signed long g(T, S, signed long*&, const signed long*&, volatile signed long*&)
{ return 0; }
unsigned long g(unsigned long, const unsigned long, volatile unsigned long)
{ return 0; }
unsigned long g(S, unsigned long&, const unsigned long&, volatile unsigned long&)
{ return 0; }
unsigned long g(unsigned long*, const unsigned long*, volatile unsigned long*)
{ return 0; }
unsigned long g(S, unsigned long*&, const unsigned long*&, volatile unsigned long*&)
{ return 0; }
#ifdef __GNUC__
long long g(long long, const long long, volatile long long)
{ return 0; }
long long g(S, long long&, const long long&, volatile long long&)
{ return 0; }
long long g(long long*, const long long*, volatile long long*)
{ return 0; }
long long g(R, long long*&, const long long*&, volatile long long*&)
{ return 0; }
signed long long g(T, signed long long, const signed long long, volatile signed long long)
{ return 0; }
signed long long g(T, R, signed long long&, const signed long long&, volatile signed long long&)
{ return 0; }
signed long long g(T, signed long long*, const signed long long*, volatile signed long long*)
{ return 0; }
signed long long g(T, S, signed long long*&, const signed long long*&, volatile signed long long*&)
{ return 0; }
unsigned long long g(unsigned long long, const unsigned long long, volatile unsigned long long)
{ return 0; }
unsigned long long g(R, unsigned long long*, const unsigned long long*, volatile unsigned long long*)
{ return 0; }
unsigned long long g(unsigned long long&, const unsigned long long&, volatile unsigned long long&)
{ return 0; }
unsigned long long g(S, unsigned long long*&, const unsigned long long*&, volatile unsigned long long*&)
{ return 0; }
#endif
float g(float, const float, volatile float)
{ return 0; }
float g(char, float&, const float&, volatile float&)
{ return 0; }
float g(float*, const float*, volatile float*)
{ return 0; }
float g(char, float*&, const float*&, volatile float*&)
{ return 0; }
double g(double, const double, volatile double)
{ return 0; }
double g(char, double&, const double&, volatile double&)
{ return 0; }
double g(double*, const double*, volatile double*)
{ return 0; }
double g(char, double*&, const double*&, volatile double*&)
{ return 0; }
#ifdef __GNUC__
long double g(long double, const long double, volatile long double)
{ return 0; }
long double g(char, long double&, const long double&, volatile long double&)
{ return 0; }
long double g(long double*, const long double*, volatile long double*)
{ return 0; }
long double g(char, long double*&, const long double*&, volatile long double*&)
{ return 0; }
#endif
class c {
public:
c(int) {};
int i;
};
class c g(c, const c, volatile c)
{ return 0; }
c g(char, c&, const c&, volatile c&)
{ return 0; }
c g(c*, const c*, volatile c*)
{ return 0; }
c g(char, c*&, const c*&, volatile c*&)
{ return 0; }
/*
void h(char = 'a')
{ }
void h(char, signed char = 'a')
{ }
void h(unsigned char = 'a')
{ }
*/
/*
void h(char = (char)'a')
{ }
void h(char, signed char = (signed char)'a')
{ }
void h(unsigned char = (unsigned char)'a')
{ }
void h(short = (short)43)
{ }
void h(char, signed short = (signed short)43)
{ }
void h(unsigned short = (unsigned short)43)
{ }
void h(int = (int)43)
{ }
void h(char, signed int = (signed int)43)
{ }
void h(unsigned int = (unsigned int)43)
{ }
void h(long = (long)43)
{ }
void h(char, signed long = (signed long)43)
{ }
void h(unsigned long = (unsigned long)43)
{ }
#ifdef __GNUC__
void h(long long = 43)
{ }
void h(char, signed long long = 43)
{ }
void h(unsigned long long = 43)
{ }
#endif
void h(float = 4.3e-10)
{ }
void h(double = 4.3)
{ }
#ifdef __GNUC__
void h(long double = 4.33e33)
{ }
#endif
*/
void printf(const char *format, ... )
{
// elipsis
}
class T1 {
public:
static void* operator new(size_t);
static void operator delete(void *pointer);
void operator=(const T1&);
T1& operator=(int);
int operator==(int) const;
int operator==(const T1&) const;
int operator!=(int) const;
int operator!=(const T1&) const;
int operator<=(int) const;
int operator<=(const T1&) const;
int operator<(int) const;
int operator<(const T1&) const;
int operator>=(int) const;
int operator>=(const T1&) const;
int operator>(int) const;
int operator>(const T1&) const;
void operator+(int) const;
T1& operator+(const T1&) const;
void operator+=(int) const;
T1& operator+=(const T1&) const;
T1& operator++() const;
void operator-(int) const;
T1& operator-(const T1&) const;
void operator-=(int) const;
T1& operator-=(const T1&) const;
T1& operator--() const;
void operator*(int) const;
T1& operator*(const T1&) const;
void operator*=(int) const;
T1& operator*=(const T1&) const;
void operator/(int) const;
T1& operator/(const T1&) const;
void operator/=(int) const;
T1& operator/=(const T1&) const;
void operator%(int) const;
T1& operator%(const T1&) const;
void operator%=(int) const;
T1& operator%=(const T1&) const;
void operator&&(int) const;
T1& operator&&(const T1&) const;
void operator||(int) const;
T1& operator||(const T1&) const;
void operator&(int) const;
T1& operator&(const T1&) const;
void operator&=(int) const;
T1& operator&=(const T1&) const;
void operator|(int) const;
T1& operator|(const T1&) const;
void operator|=(int) const;
T1& operator|=(const T1&) const;
void operator^(int) const;
T1& operator^(const T1&) const;
void operator^=(int) const;
T1& operator^=(const T1&) const;
T1& operator!() const;
T1& operator~() const;
};
void*
T1::operator new(size_t)
{ return 0; }
void
T1::operator delete(void *pointer)
{ }
class T2 {
public:
T2(int i): integer(i)
{ }
int integer;
};
int operator==(const T2&, const T2&)
{ return 0; }
int operator==(const T2&, char)
{ return 0; }
int operator!=(const T2&, const T2&)
{ return 0; }
int operator!=(const T2&, char)
{ return 0; }
int operator<=(const T2&, const T2&)
{ return 0; }
int operator<=(const T2&, char)
{ return 0; }
int operator<(const T2&, const T2&)
{ return 0; }
int operator<(const T2&, char)
{ return 0; }
int operator>=(const T2&, const T2&)
{ return 0; }
int operator>=(const T2&, char)
{ return 0; }
int operator>(const T2&, const T2&)
{ return 0; }
int operator>(const T2&, char)
{ return 0; }
T2 operator+(const T2 t, int i)
{ return t.integer + i; }
T2 operator+(const T2 a, const T2& b)
{ return a.integer + b.integer; }
T2& operator+=(T2& t, int i)
{ t.integer += i; return t; }
T2& operator+=(T2& a, const T2& b)
{ a.integer += b.integer; return a; }
T2 operator-(const T2 t, int i)
{ return t.integer - i; }
T2 operator-(const T2 a, const T2& b)
{ return a.integer - b.integer; }
T2& operator-=(T2& t, int i)
{ t.integer -= i; return t; }
T2& operator-=(T2& a, const T2& b)
{ a.integer -= b.integer; return a; }
T2 operator*(const T2 t, int i)
{ return t.integer * i; }
T2 operator*(const T2 a, const T2& b)
{ return a.integer * b.integer; }
T2& operator*=(T2& t, int i)
{ t.integer *= i; return t; }
T2& operator*=(T2& a, const T2& b)
{ a.integer *= b.integer; return a; }
T2 operator/(const T2 t, int i)
{ return t.integer / i; }
T2 operator/(const T2 a, const T2& b)
{ return a.integer / b.integer; }
T2& operator/=(T2& t, int i)
{ t.integer /= i; return t; }
T2& operator/=(T2& a, const T2& b)
{ a.integer /= b.integer; return a; }
T2 operator%(const T2 t, int i)
{ return t.integer % i; }
T2 operator%(const T2 a, const T2& b)
{ return a.integer % b.integer; }
T2& operator%=(T2& t, int i)
{ t.integer %= i; return t; }
T2& operator%=(T2& a, const T2& b)
{ a.integer %= b.integer; return a; }
template<class T>
class T5 {
public:
T5(int);
T5(const T5<T>&);
~T5();
static void* operator new(size_t);
static void operator delete(void *pointer);
int value();
static T X;
T x;
int val;
};
template<class T>
T5<T>::T5(int v)
{ val = v; }
template<class T>
T5<T>::T5(const T5<T>&)
{}
template<class T>
T5<T>::~T5()
{}
template<class T>
void*
T5<T>::operator new(size_t)
{ return 0; }
template<class T>
void
T5<T>::operator delete(void *pointer)
{ }
template<class T>
int
T5<T>::value()
{ return val; }
#if ! defined(__GNUC__) || defined(GCC_BUG)
template<class T>
T T5<T>::X;
#endif
T5<char> t5c(1);
T5<int> t5i(2);
T5<int (*)(char, void *)> t5fi1(3);
T5<int (*)(int, double **, void *)> t5fi2(4);
class x {
public:
int (*manage[5])(double,
void *(*malloc)(unsigned size),
void (*free)(void *pointer));
int (*device[5])(int open(const char *, unsigned mode, unsigned perms, int extra = 0),
int *(*read)(int fd, void *place, unsigned size),
int *(*write)(int fd, void *place, unsigned size),
void (*close)(int fd));
};
T5<x> t5x(5);
#if !defined(__GNUC__) || (__GNUC__ >= 2 && __GNUC_MINOR__ >= 6)
template class T5<char>;
template class T5<int>;
template class T5<int (*)(char, void *)>;
template class T5<int (*)(int, double **, void *)>;
template class T5<x>;
#endif
class T7 {
public:
static int get();
static void put(int);
};
int
T7::get()
{ return 1; }
void
T7::put(int i)
{
// nothing
}
// More template kinds. GDB 4.16 didn't handle these, but
// Wildebeest does. Note: Assuming HP aCC is used to compile
// this file; with g++ or HP cfront or other compilers the
// demangling may not get done correctly.
// Ordinary template, to be instantiated with different types
template<class T>
class Foo {
public:
int x;
T t;
T foo (int, T);
};
template<class T> T Foo<T>::foo (int i, T tt)
{
return tt;
}
// Template with int parameter
template<class T, int sz>
class Bar {
public:
int x;
T t;
T bar (int, T);
};
template<class T, int sz> T Bar<T, sz>::bar (int i, T tt)
{
if (i < sz)
return tt;
else
return 0;
}
// function template with int parameter
template<class T> int dummy (T tt, int i)
{
return tt;
}
// Template with partial specializations
template<class T1, class T2>
class Spec {
public:
int x;
T1 spec (T2);
};
template<class T1, class T2>
T1 Spec<T1, T2>::spec (T2 t2)
{
return 0;
}
template<class T>
class Spec<T, T*> {
public:
int x;
T spec (T*);
};
template<class T>
T Spec<T, T*>::spec (T * tp)
{
return *tp;
}
// Template with char parameter
template<class T, char sz>
class Baz {
public:
int x;
T t;
T baz (int, T);
};
template<class T, char sz> T Baz<T, sz>::baz (int i, T tt)
{
if (i < sz)
return tt;
else
return 0;
}
// Template with char * parameter
template<class T, char * sz>
class Qux {
public:
int x;
T t;
T qux (int, T);
};
template<class T, char * sz> T Qux<T, sz>::qux (int i, T tt)
{
if (sz[0] == 'q')
return tt;
else
return 0;
}
// Template with a function pointer parameter
template<class T, int (*f)(int) >
class Qux1 {
public:
int x;
T t;
T qux (int, T);
};
template<class T, int (*f)(int)> T Qux1<T, f>::qux (int i, T tt)
{
if (f != 0)
return tt;
else
return 0;
}
// Some functions to provide as arguments to template
int gf1 (int a) {
return a * 2 + 13;
}
int gf2 (int a) {
return a * 2 + 26;
}
char string[3];
// Template for nested instantiations
template<class T>
class Garply {
public:
int x;
T t;
T garply (int, T);
};
template<class T> T Garply<T>::garply (int i, T tt)
{
if (i > x)
return tt;
else
{
x += i;
return tt;
}
}
int main()
{
int i;
#ifdef usestubs
set_debug_traps();
breakpoint();
#endif
i = i + 1;
// New tests added here
Foo<int> fint;
Foo<char> fchar;
Foo<volatile char *> fvpchar;
Bar<int, 33> bint;
Bar<int, (4 > 3)> bint2;
Baz<int, 's'> bazint;
Baz<char, 'a'> bazint2;
Qux<char, string> quxint2;
Qux<int, string> quxint;
Qux1<int, gf1> qux11;
int x = fint.foo(33, 47);
char c = fchar.foo(33, 'x');
volatile char * cp = fvpchar.foo(33, 0);
int y = dummy<int> (400, 600);
int z = bint.bar(55, 66);
z += bint2.bar(55, 66);
c = bazint2.baz(4, 'y');
c = quxint2.qux(4, 'z');
y = bazint.baz(4,3);
y = quxint.qux(4, 22);
y += qux11.qux(4, 22);
y *= gf1(y) - gf2(y);
Spec<int, char> sic;
Spec<int, int *> siip;
sic.spec ('c');
siip.spec (&x);
Garply<int> f;
Garply<char> fc;
f.x = 13;
Garply<Garply<char> > nf;
nf.x = 31;
x = f.garply (3, 4);
fc = nf.garply (3, fc);
y = x + fc.x;
return 0;
}

View File

@ -0,0 +1,381 @@
# Copyright (C) 1992, 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
# More tests for different kinds of template parameters,
# templates with partial specializations, nested templates, etc.
# These have been tested only with HP aCC. They probably won't
# work with other compilers because of differences in mangling
# schemes.
# Added by Satish Pai <pai@apollo.hp.com> 1997-09-25
set ws "\[\r\n\t \]+"
if $tracelevel then {
strace $tracelevel
}
set testfile "templ-hp"
set srcfile ${testfile}.cc
set binfile ${objdir}/${subdir}/${testfile}
# Create and source the file that provides information about the compiler
# used to compile the test case.
if [get_compiler_info ${binfile} "c++"] {
return -1;
}
if {[skip_hp_tests $gcc_compiled]} then { continue }
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
#
# Test printing of the types of templates.
#
proc test_ptype_of_templates {} {
global gdb_prompt
send_gdb "ptype T5<int>\n"
gdb_expect {
-re "type = class T5<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*static int X;\r\n\[ \t\]*int x;\r\n\[ \t\]*int val;\r\n\r\n\[ \t\]*T5\\(int\\);\r\n\[ \t\]*T5\\(class T5<int> const &\\);\r\n\[ \t\]*void ~T5\\(int\\);\r\n\[ \t\]*static void \\* new\\(unsigned int\\);\r\n\[ \t\]*static void delete\\(void \\*\\);\r\n\[ \t\]*int value\\(void\\);\r\n\[ \t\]*\\}\r\n$gdb_prompt $" { pass "ptype T5<int>" }
-re ".*$gdb_prompt $" { fail "ptype T5<int>" }
timeout { fail "ptype T5<int> (timeout)" }
}
send_gdb "ptype t5i\n"
gdb_expect {
-re "type = class T5<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*static int X;\r\n\[ \t\]*int x;\r\n\[ \t\]*int val;\r\n\r\n\[ \t\]*T5\\(int\\);\r\n\[ \t\]*T5\\(class T5<int> const &\\);\r\n\[ \t\]*void ~T5\\(int\\);\r\n\[ \t\]*static void \\* new\\(unsigned int\\);\r\n\[ \t\]*static void delete\\(void \\*\\);\r\n\[ \t\]*int value\\(void\\);\r\n\[ \t\]*\\}\r\n$gdb_prompt $" { pass "ptype t5i<int> 1" }
-re "type = class T5<int> \{.*public:.*static int X;.*int x;.*int val;.*.*T5 \\(int\\);.*.*void ~T5 \\(int\\).*.*.*int value \\(void\\);.*\}.*$gdb_prompt $" {
pass "ptype t5i"
}
-re ".*$gdb_prompt $" { fail "ptype t5i" }
timeout { fail "ptype t5i (timeout)" }
}
}
#
# Test breakpoint setting on template methods.
#
proc test_template_breakpoints {} {
global gdb_prompt
global testfile
global srcdir
send_gdb "break T5<int>::T5\n"
gdb_expect {
-re "0. cancel.*\r\n.1. all.*\r\n.2. *.*\r\n.3. *.*\r\n> $" {
gdb_test "0" \
"cancelled" \
"constructor breakpoint"
}
-re ".0. cancel\r\n.1. all\r\n.2. T5<int>::T5\\(T5<int> const &\\) at .*/templates.cc:.*\r\n.3. T5<int>::T5\\(int\\) at .*/templates-hp.cc:.*\r\n> $" {
gdb_test "0" \
"cancelled" \
"constructor breakpoint"
}
-re ".*$gdb_prompt $" { fail "constructor breakpoint" }
default { fail "constructor breakpoint (timeout)" }
}
gdb_test "break T5<int>::~T5" \
"Breakpoint.*at.* file .*${testfile}.cc, line.*" \
"destructor breakpoint"
gdb_test "break T5<int>::value" \
"Breakpoint.*at.* file .*${testfile}.cc, line.*" \
"value method breakpoint"
delete_breakpoints
}
#
# Test calling of template methods.
#
proc test_template_calls {} {
global gdb_prompt
send_gdb "print t5i.value()\n"
gdb_expect {
-re ".* = 2\r\n$gdb_prompt $" { pass "print t5i.value()" }
-re "Cannot invoke functions on this machine.*$gdb_prompt $" {
fail "print t5i.value()"
}
-re ".*$gdb_prompt $" { fail "print t5i.value()" }
timeout { fail "print t5i.value() (timeout)" }
}
}
proc do_tests {} {
global prms_id
global bug_id
global subdir
global objdir
global srcdir
global binfile
global prompt
global supports_template_debugging
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
source ${binfile}.ci
if { !$supports_template_debugging } {
warning "compiler lacks debugging info for templates; tests suppressed." 0
return
}
test_ptype_of_templates
test_template_breakpoints
if [ runto_main ] {
test_template_calls
}
}
do_tests
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $binfile
# set it up at a breakpoint so we can play with the variable values
#
if ![runto_main] then {
perror "couldn't run to breakpoint"
continue
}
send_gdb "print fint\n"
gdb_expect {
-re "\\$\[0-9\]* = \\{x = 0, t = 0\\}\r\n$gdb_prompt $" { pass "print fint" }
-re "$gdb_prompt $" { fail "print fint" }
timeout { fail "(timeout) print fint" }
}
send_gdb "print fvpchar\n"
gdb_expect {
-re "\\$\[0-9\]* = \\{x = 0, t = 0x0\\}\r\n$gdb_prompt $" { pass "print fvpchar" }
-re "$gdb_prompt $" { fail "print fvpchar" }
timeout { fail "(timeout) print fvpchar" }
}
# Template Foo<T>
send_gdb "ptype Foo\n"
gdb_expect {
-re "type = template <(class |)T> (class |)Foo \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Foo<volatile char \\*>\r\n\[ \t\]*(class |)Foo<char>\r\n\[ \t\]*(class |)Foo<int>\r\n$gdb_prompt $" { pass "ptype Foo" }
-re "$gdb_prompt $" { fail "ptype Foo" }
timeout { fail "(timeout) ptype Foo" }
}
# ptype Foo<int>
send_gdb "ptype fint\n"
gdb_expect {
-re "type = (class |)Foo<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int foo\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype fint" }
-re "$gdb_prompt $" { fail "ptype fint" }
timeout { fail "(timeout) ptype fint" }
}
# ptype Foo<char>
send_gdb "ptype fchar\n"
gdb_expect {
-re "type = (class |)Foo<char> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*char foo\\(int, char\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype fchar" }
-re "$gdb_prompt $" { fail "ptype fchar" }
timeout { fail "(timeout) ptype fchar" }
}
# ptype Foo<volatile char *>
send_gdb "ptype fvpchar\n"
gdb_expect {
-re "type = (class |)Foo<volatile char \\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*volatile char \\*t;\r\n\r\n\[ \t\]*volatile char \\* foo\\(int, volatile char \\*\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype fvpchar" }
-re "$gdb_prompt $" { fail "ptype fvpchar" }
timeout { fail "(timeout) ptype fvpchar" }
}
# print a function from Foo<volatile char *>
send_gdb "print Foo<volatile char *>::foo\n"
gdb_expect {
-re "\\$\[0-9\]* = \\{volatile char \\*\\((class |)Foo<volatile char \\*> \\*, int, volatile char \\*\\)\\} $hex <Foo<volatile char \\*>::foo\\(int, volatile char \\*\\)>\r\n$gdb_prompt $" { pass "print Foo<volatile char *>::foo" }
-re "$gdb_prompt $" { fail "print Foo<volatile char *>::foo" }
timeout { fail "(timeout) print Foo<volatile char *>::foo" }
}
# Template Bar<T, int>
send_gdb "ptype Bar\n"
gdb_expect {
-re "type = template <(class |)T, (class |)sz> (class |)Bar \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Bar<int,1>\r\n\[ \t\]*(class |)Bar<int,33>\r\n$gdb_prompt $" { pass "ptype Bar" }
-re "$gdb_prompt $" { fail "ptype Bar" }
timeout { fail "(timeout) ptype Bar" }
}
# ptype Bar<int,33>
send_gdb "ptype bint\n"
gdb_expect {
-re "type = (class |)Bar<int,33> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int bar\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype bint" }
-re "$gdb_prompt $" { fail "ptype bint" }
timeout { fail "(timeout) ptype bint" }
}
# ptype Bar<int, (4>3)>
send_gdb "ptype bint2\n"
gdb_expect {
-re "type = (class |)Bar<int,1> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int bar\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype bint2" }
-re "$gdb_prompt $" { fail "ptype bint2" }
timeout { fail "(timeout) ptype bint2" }
}
# Template Baz<T, char>
send_gdb "ptype Baz\n"
gdb_expect {
-re "type = template <(class |)T, (class |)sz> (class |)Baz \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Baz<char,97>\r\n\[ \t\]*(class |)Baz<int,115>\r\n$gdb_prompt $" { pass "ptype Baz" }
-re "$gdb_prompt $" { fail "ptype Baz" }
timeout { fail "(timeout) ptype Baz" }
}
# ptype Baz<int, 's'>
send_gdb "ptype bazint\n"
gdb_expect {
-re "type = (class |)Baz<int,115> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int baz\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype bazint" }
-re "$gdb_prompt $" { fail "ptype bazint" }
timeout { fail "(timeout) ptype bazint" }
}
# ptype Baz<char, 'a'>
send_gdb "ptype bazint2\n"
gdb_expect {
-re "type = (class |)Baz<char,97> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*char baz\\(int, char\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype bazint2" }
-re "$gdb_prompt $" { fail "ptype bazint2" }
timeout { fail "(timeout) ptype bazint2" }
}
# Template Qux<T, int (*f)(int) >
send_gdb "ptype Qux\n"
gdb_expect {
-re "type = template <(class |)T, (class |)sz> (class |)Qux \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Qux<int,&string>\r\n\[ \t\]*(class |)Qux<char,&string>\r\n$gdb_prompt $" { pass "ptype Qux" }
-re "$gdb_prompt $" { fail "ptype Qux" }
timeout { fail "(timeout) ptype Qux" }
}
# pt Qux<int,&string>
send_gdb "ptype quxint\n"
gdb_expect {
-re "type = class Qux<int,&string> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint" }
-re "$gdb_prompt $" { fail "ptype quxint" }
timeout { fail "(timeout) ptype quxint" }
}
# pt Qux<char,0>
send_gdb "ptype quxint2\n"
gdb_expect {
-re "type = class Qux<char,&string> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*char qux\\(int, char\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype quxint2" }
-re "$gdb_prompt $" { fail "ptype quxint2" }
timeout { fail "(timeout) ptype quxint2" }
}
# Template Spec<T1, T2>
send_gdb "ptype Spec\n"
gdb_expect {
-re "type = template <(class |)T1, (class |)T2> (class |)Spec \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Spec<int,int \\*>\r\n\[ \t\]*(class |)Spec<int,char>\r\n$gdb_prompt $" { pass "ptype Spec" }
-re "$gdb_prompt $" { fail "ptype Spec" }
timeout { fail "(timeout) ptype Spec" }
}
# pt Spec<char,0>
send_gdb "ptype siip\n"
gdb_expect {
-re "type = class Spec<int,int \\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\r\n\[ \t\]*int spec\\(int \\*\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype siip" }
-re "$gdb_prompt $" { fail "ptype siip" }
timeout { fail "(timeout) ptype siip" }
}
# pt Garply<int>
send_gdb "ptype Garply<int>\n"
gdb_expect {
-re "type = class Garply<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int garply\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype Garply<int>" }
-re "$gdb_prompt $" { fail "ptype Garply<int>" }
timeout { fail "(timeout) ptype Garply<int>" }
}
# ptype of nested template name
send_gdb "ptype Garply<Garply<char> >\n"
gdb_expect {
-re "type = (class |)Garply<Garply<char> > \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*(class |)Garply<char> t;\r\n\r\n\[ \t\]*(class |)Garply<char> garply\\(int, (class |)Garply<char>\\);\r\n\\}\r\n$gdb_prompt $" { pass "ptype Garply<Garply<char> >" }
-re "$gdb_prompt $" { fail "ptype Garply<Garply<char> >" }
timeout { fail "(timeout) ptype Garply<Garply<char> >" }
}
# print out a function from a nested template name
send_gdb "print Garply<Garply<char> >::garply\n"
gdb_expect {
-re "\\$\[0-9\]* = \\{(class |)Garply<char> \\((class |)Garply<Garply<char> > \\*, int, (class |)Garply<char>\\)\\} $hex <Garply<Garply<char>>::garply\\(int, (class |)Garply<char>\\)>\r\n$gdb_prompt $" { pass "print Garply<Garply<char> >::garply" }
-re ".*$gdb_prompt $" { fail "print Garply<Garply<char> >::garply" }
timeout { fail "print Garply<Garply<char> >::garply (timeout)" }
}
# UNFORTUNATELY, "break Garply<Garply<char> >::garply" doesn't yet work.
#send_gdb "break Garply<Garply<char> >::garply
#gdb_expect {
# -re "Breakpoint \[0-9\]* at $hex: file .*templates.cc, line.*\r\n$gdb_prompt $" { pass "break Garply<Garply<char> >::garply" }
# -re ".*$gdb_prompt $" { fail "break Garply<Garply<char> >::garply" }
# timeout { fail "break Garply<Garply<char> >::garply (timeout)" }
#}

View File

@ -0,0 +1,79 @@
/* Thread local in a library.
*/
#include "thr-lib.h"
/*
* #define NTHREADS 4
* #define NUM_ELEMS 12
*/
extern void* adder( void * );
pthread_mutex_t mutex; /* mutex for protecting global data total */
int numbers[NUM_ELEMS] = {5, 4, 3, 2, 1, 6, 7, 8, 9, 10, 12, 11};
int total = 0;
int debugger_saw[NTHREADS][ELEMS_PER_THREAD]; /* [4][3] */
int the_code_saw[NTHREADS][ELEMS_PER_THREAD];
int get_number(i)
int i;
{
/* sleep to force context switch to another thread in non-MP system
* so that TLS symbols are used by multiple threads concurrently
* in some way.
*/
sleep(1);
return numbers[i];
}
main()
{
pthread_t thread[NTHREADS];
void *status;
int i, j, ret;
printf("== Thread: Test started\n");
for( i = 0; i < NTHREADS; i++ ) {
for( j = 0; j < ELEMS_PER_THREAD; j++ ) {
debugger_saw[i][j] = 0;
the_code_saw[i][j] = 0;
}
}
ret = pthread_mutex_init(&mutex, NULL);
if (ret != 0) {
printf("== Thread: pthread_mutex_init() error: %d\n", ret);
exit(1);
}
for (i=0; i < NTHREADS; i++) {
ret = pthread_create( &thread[i],
NULL,
adder,
(void *) i);
if (ret != 0) {
printf("== Thread: pthread_create() error: %d\n", ret);
exit(1);
}
printf("== Thread: thread %d created\n", i);
}
for (i=0; i < NTHREADS; i++) {
pthread_join( thread[i], &status);
}
printf("== Thread: total = %d\n", total); /* Expect "78" */
for( i = 0; i < NTHREADS; i++ ) {
for( j = 0; j < ELEMS_PER_THREAD; j++ ) {
printf( "== Thread: the debugger saw %d, the program saw %d\n",
debugger_saw[i][j],
the_code_saw[i][j] );
}
}
printf("== Thread: Test ended\n");
exit(0);
}

View File

@ -0,0 +1,234 @@
# thr-lib.exp -- Expect script to test thread-local storage in lib
# Copyright (C) 1992 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
# use this to debug:
#
#log_user 1
# Thread stuff is _slow_; prepare for long waits.
#
# Further, this test has some "null" lines designed
# to consume output from gdb that was too late to be
# matched (sequence is "gdb_test" sends; timeout and
# on to next send; result finally comes in; mismatch).
#
# The null command is 'gdb_test "p \$pc" ".*" ""'
# NOTE: this command undoes any up/down stuff!
#
proc pre_timeout {} {
global timeout
set timeout [expr "$timeout + 100"]
}
proc post_timeout {} {
global timeout
global oldtimeout
set timeout $oldtimeout
gdb_test "p \$pc" ".*" ""
}
if $tracelevel then {
strace $tracelevel
}
if { ![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"] } {
verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
return 0
}
set testfile thr-lib
set srcfile ${srcdir}/${subdir}/${testfile}.c
set libsrc ${srcdir}/${subdir}/${testfile}lib.c
set mainobj ${objdir}/${testfile}.o
set libobj ${objdir}/${testfile}lib.o
set libsl ${objdir}/${subdir}/${testfile}lib.sl
set binfile ${objdir}/${subdir}/${testfile}
# To build the executable we need to do this:
#
# cc -c -Aa -g -D_HPUX_SOURCE -D_REENTRANT +DA1.0 ./gdb.hp/thr-lib.c
# cc -c -Aa -g -D_HPUX_SOURCE -D_REENTRANT +DA1.0 +z ./gdb.hp/thr-liblib.c
# ld -o thread_local_in_lib.lib.sl -b ./gdb.hp/thr-liblib.o
# ld -a archive /opt/langtools/lib/crt0.o /opt/langtools/lib/end.o \
# > thr-lib.o ./gdb.hp/thr-liblib.sl \
# > -o thr-lib -lpthread -lc
#
remote_exec build "$CC ${srcfile} -c -Aa -g -D_HPUX_SOURCE -D_REENTRANT +DA1.0"
remote_exec build "$CC ${libsrc} -c -Aa -g -D_HPUX_SOURCE -D_REENTRANT +DA1.0 +z"
remote_exec build "ld -o ${libsl} -b ${libobj}"
remote_exec build "ld -a archive /opt/langtools/lib/crt0.o /opt/langtools/lib/end.o ${mainobj} ${libsl} -lpthread -lc -o ${binfile}"
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
set oldtimeout $timeout
#set timeout [expr "$timeout + 200"]
set oldverbose $verbose
gdb_load ${binfile}
# Here we go: test various things.
#
gdb_test "b adder" ".*Cannot break on adder without a running program.*" "shared loc, needs to run"
gdb_test "b main" ".*" ""
gdb_test "run" ".*Breakpoint 1, main.*" ""
# Set a bp to inspect the results
#
gdb_test "b 67" ".*Breakpoint 2.*" ""
# get to a point where we can set the collection breakpoint.
#
gdb_test "tb adder" ".*Breakpoint 3.*line 47.*" "set bp in shared lib"
gdb_test "c" ".*Switched to.*adder.*" "run to shared lib rtn"
# Check locations of things
#
gdb_test "i ad sum" ".*Symbol \"sum\" is a thread-local variable.*offset.*from the thread base register mpsfu_high.*" "find sum"
gdb_test "i add x" ".*Symbol \"x\" is a thread-local variable.*" "find x"
# Set a breakpoint later on in "adder" and
# collect the thread local's value.
#
gdb_test "b 61" ".*Breakpoint 4.*61.*" "Set collection bp"
# extra check for grins, expect to hit "adder" in thread 2 first
# but could be wrong...
#
gdb_test "info thread" ".*\\\* 2.*thread.*thread.*" "two threads"
# Can't use "gdb_test", as it uses "$gdb_prompt $" in
# testing the result. Our new prompt is ">", with
# no trailing space, so we can't do this just by
# changing "prompt".
#
# Anyway, I couldn't get expect to see the ">" prompt,
# during the command addition, so I just punted.
# _You_ are welcome to try, if you want!
#
send_gdb "commands 4\n"
gdb_expect {
-re "(.*Type commands.*\"end\"\.\r\n\>)" {
pass "start commands"
}
-re ".*$gdb_prompt $" {
fail "start commands"
}
}
# Assume we're in commands-input mode. (Self-debug stuff turned off)
#
send_gdb "silent\n"
#send_gdb "p id\n"
#send_gdb "p j\n"
#send_gdb "p x\[j\]\n"
send_gdb "set debugger_saw\[id\]\[j\] = x\[j\]\n"
send_gdb "continue\n"
send_gdb "end\n"
gdb_expect {
-re ".*set.*cont.*$gdb_prompt $" {
pass "add commands"
}
-re ".*$gdb_prompt $" {
fail "add commands"
}
}
# Check out of paranoia.
#
send_gdb "info break 4\n"
gdb_expect {
-re ".*breakpoint.*set debugger_saw.*continue.*$gdb_prompt $" {
pass "Commands added"
}
-re ".*$gdb_prompt $" {
fail "Commands not added."
}
}
# We now expect to run through the whole application
# Since this'll run for while, set a generous timeout.
#
set timeout [expr "$timeout + 30"]
send_gdb "c\n"
gdb_expect {
-re ".*Program exited normally.*$gdb_prompt $" {
fail "program runaway"
}
-re ".*Breakpoint 2.*67.*$gdb_prompt $" {
pass "get to end"
}
-re ".*$gdb_prompt $" {
fail "No progress?"
}
timeout { fail "timeout" }
}
set timeout $oldtimeout
gdb_test "p debugger_saw" ".*5, 1, 9.*4, 6, 10.*3, 7, 12.*2, 8, 11.*" "check results"
# Often only one misses; let's get detailed!
#
gdb_test "p debugger_saw\[0\]\[0\]" ".*= 5.*" "1"
gdb_test "p debugger_saw\[0\]\[1\]" ".*= 1.*" "2"
gdb_test "p debugger_saw\[0\]\[2\]" ".*= 9.*" "3"
gdb_test "p debugger_saw\[1\]\[0\]" ".*= 4.*" "4"
gdb_test "p debugger_saw\[1\]\[1\]" ".*= 6.*" "5"
gdb_test "p debugger_saw\[1\]\[2\]" ".*= 10.*" "6"
gdb_test "p debugger_saw\[2\]\[0\]" ".*= 3.*" "7"
gdb_test "p debugger_saw\[2\]\[1\]" ".*= 7.*" "8"
gdb_test "p debugger_saw\[2\]\[2\]" ".*= 12.*" "9"
gdb_test "p debugger_saw\[3\]\[0\]" ".*= 2.*" "10"
gdb_test "p debugger_saw\[3\]\[1\]" ".*= 8.*" "11"
gdb_test "p debugger_saw\[3\]\[2\]" ".*= 11.*" "12"
send_gdb "i th\n"
gdb_expect {
-re ".* 1.*system thread.* 2.*system thread.*$gdb_prompt $" {
fail "Too many threads left"
}
-re ".*\\\* 1.*system thread.*main.*$gdb_prompt $" {
pass "Expect only base thread"
}
-re ".*No stack.*$gdb_prompt $" {
fail "runaway"
}
-re ".*$gdb_prompt $" {
fail "Hunh?"
}
timeout { fail "timeout" }
}
gdb_test "c" ".*exited normally.*" "run to completion"
# Done!
#
gdb_exit
set timeout $oldtimeout
set verbose $oldverbose
# execute_anywhere "rm -f ${binfile}"
#
return 0

View File

@ -0,0 +1,7 @@
#include <stdio.h>
#include <pthread.h>
#define NTHREADS 4
#define NUM_ELEMS 12
#define ELEMS_PER_THREAD (NUM_ELEMS/NTHREADS)

View File

@ -0,0 +1,92 @@
#include <stdio.h>
/* Library code for thread local in lib test.
*/
#include "thr-lib.h"
extern pthread_mutex_t mutex;
extern int get_number();
extern int total;
extern int the_code_saw[NTHREADS][ELEMS_PER_THREAD];
/* The debugger should see this without a declaration.
*
* extern int debugger_saw[NTHREADS][ELEMS_PER_THREAD];
*/
/* The actual thread locals.
*/
__thread int sum;
__thread int x[ ELEMS_PER_THREAD ]; /* [3] */
void sumup()
{
int j;
sum = 0;
for (j = 0; j < ELEMS_PER_THREAD; j++) {
sum += x[j];
}
if( sum == x[0] )
/* It won't be "==", but this lets us set a breakpoint
* and look at the thread-local storage.
*/
sum++;
x[0] = x[2]; /* Another no-op for debugger use */
}
void *adder( vid )
void * vid;
{
int id;
int i, j;
int ret;
id = (int) vid;
/* printf( "== Thread: Welcome to adder %d\n", id ); */
for (j = 0; j < ELEMS_PER_THREAD; j++) {
x[j] = 0;
}
for (i = id, j = 0; i < NUM_ELEMS; i += NTHREADS, j++ ) {
/* printf( "== Thread: id %d, i %d, j %d\n", id, i, j );
fflush( stdout ); */
x[j] = get_number(i); /* {0,1,2,3} +0, +4, +8 */
/* Record for posterity; the debugger will gather
* the same data here, using "x[j]".
*/
the_code_saw[ id ][ j ] = x[j];
/* printf( "== Thread %d, sample %d, val %d, i %d\n", id, j, x[j],i );
fflush( stdout ); */
}
sumup();
/* printf("== Thread: adder %d contributes total %d\n", id, sum); */
/* protect global data */
ret = pthread_mutex_lock(&mutex);
if (ret != 0) {
printf("== Thread: pthread_mutex_lock() error: %d\n", ret);
exit(1);
}
total += sum;
ret = pthread_mutex_unlock(&mutex);
if (ret != 0) {
printf("== Thread: pthread_mutex_unlock() error: %d\n", ret);
exit(1);
}
if( NTHREADS != 4 || ELEMS_PER_THREAD != 3 || NUM_ELEMS != 12 ) {
printf( "** ERROR in test code **\n" );
}
}

View File

@ -0,0 +1,255 @@
# thread_local_stg.exp -- Expect script to test thread-local storage
# Copyright (C) 1992 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
# use this to debug:
#
#log_user 1
# Thread stuff is _slow_; prepare for long waits.
#
# Further, this test has some "null" lines designed
# to consume output from gdb that was too late to be
# matched (sequence is "gdb_test" sends; timeout and
# on to next send; result finally comes in; mismatch).
#
# The null command is 'gdb_test "p \$pc" ".*" ""'
# NOTE: this command undoes any up/down stuff!
#
proc pre_timeout {} {
global timeout
set timeout [expr "$timeout + 100"]
}
proc post_timeout {} {
global timeout
global oldtimeout
set timeout $oldtimeout
gdb_test "p \$pc" ".*" ""
}
if $tracelevel then {
strace $tracelevel
}
if { ![istarget "hppa*-*-hpux10.30"] && ![istarget "hppa*-*-hpux11.*"] } {
verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
return 0
}
set testfile start-stop
set srcfile ${srcdir}/${subdir}/${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile}] {
return -1
}
# To build the executable we need to link against the thread library.
#
# cc -Ae -g -o start_stop -lpthread start_stop.c
#
#compile "${srcfile} -Ae -g -lpthread -o ${binfile}"
if {$gcc_compiled == 0} {
set additional_flags "additional_flags=-Ae"
} else {
set additional_flags ""
}
if { [gdb_compile "${srcdir}/${subdir}/${testfile}.c" "${binfile}.o" object [list debug $additional_flags]] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
remote_exec build "ld /usr/ccs/lib/crt0.o ${binfile}.o -lcl -lpthread -lc /opt/langtools/lib/end.o -o ${binfile}"
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
if ![runto_main] then {
fail "Can't run to main"
return 0
}
set oldtimeout $timeout
#set timeout [expr "$timeout + 200"]
set oldverbose $verbose
#set verbose 40
gdb_test "b do_pass" ".*" "set do_pass bp"
gdb_test "c" ".*do_pass.*" "run to do_pass"
gdb_test "cle" ".*" ""
# Set a breakpoint at the "spin" routine and
# collect the thread local's value.
#
gdb_test "b 67" ".*Breakpoint 3.*67.*" "Set bp"
# Can't use "gdb_test", as it uses "$gdb_prompt $" in
# testing the result. Our new prompt is ">", with
# no trailing space, so we can't do this just by
# changing "prompt".
#
# Anyway, I couldn't get expect to see the ">" prompt,
# during the command addition, so I just punted.
# _You_ are welcome to try, if you want!
#
send_gdb "commands 3\n"
gdb_expect {
-re "(.*Type commands.*\"end\"\.\r\n\>)" {
pass "start commands"
}
-re ".*$gdb_prompt $" {
fail "start commands"
}
}
# Assume we're in commands-input mode.
#
send_gdb "silent\n"
send_gdb "set val_debugger_saw\[me\] = a_thread_local\n"
send_gdb "continue\n"
send_gdb "end\n"
gdb_expect {
-re ".*set.*cont.*$gdb_prompt $" {
pass "add commands"
}
-re ".*$gdb_prompt $" {
fail "add commands"
}
}
# Check out of paranoia.
#
send_gdb "info break 3\n"
gdb_expect {
-re ".*breakpoint.*set val_debugger.*continue.*$gdb_prompt $" {
pass "Commands added"
}
-re ".*$gdb_prompt $" {
fail "Commands not added."
}
}
# Set a bp to inspect the results
#
gdb_test "b 134" ".*Breakpoint 4.*" ""
# We now expect to run through a whole pass, seeing
# specific results as noted below (actual gotten by
# running application with debugging print statements
# turned on.
#
# Since this'll run for while, set a generous timeout.
#
set timeout [expr "$timeout + 30"]
send_gdb "c\n"
gdb_expect {
-re ".*Program exited normally.*$gdb_prompt $" {
fail "program runaway"
}
-re ".*Pass 0 done.*Pass 1 done.*$gdb_prompt $" {
fail "program runaway 2"
}
-re ".*Pass 0 done.*Breakpoint 4.*134.*$gdb_prompt $" {
pass "get to end of first pass"
}
-re ".*$gdb_prompt $" {
fail "No progress?"
}
timeout { fail "timeout" }
}
gdb_test "p val_debugger_saw" ".*0, 1, 3.*" "first pass"
send_gdb "i th\n"
gdb_expect {
-re ".* 1.*system thread.* 2.*system thread.*$gdb_prompt $" {
fail "Too many threads left"
}
-re ".*\\\* 1 system thread.*$gdb_prompt $" {
pass "Expect only base thread"
}
-re ".*No stack.*$gdb_prompt $" {
fail "runaway"
}
-re ".*$gdb_prompt $" {
fail "Hunh?"
}
timeout { fail "timeout" }
}
gdb_test "i b" ".*4.*breakpoint.*134.*hit.*1 time.*" "Expect 134 bp to exist"
gdb_test "c" ".*Breakpoint 4.*134.*" "get to end of second pass"
gdb_test "p val_debugger_saw" ".*6, 10, 15.*" "second pass"
gdb_test "c" ".*Breakpoint 4.*134.*" "get to end of third pass"
gdb_test "p val_debugger_saw" ".*21, 28, 36.*" "third pass"
gdb_test "info bre 3" ".*already hit 9 times.*" "count of silent bp hits"
# Start over and do some "info address" stuff
#
send_gdb "d\n"
gdb_expect {
-re ".*Delete all breakpoints.*$" {
send_gdb "y\n"
gdb_expect {
-re ".*$gdb_prompt $" {
pass "del bps"
}
}
}
-re ".*$gdb_prompt $" { fail "no question" }
}
gdb_test "b spin" ".*Breakpoint 5.*" ""
send_gdb "r\n"
gdb_expect {
-re ".*Start it from the beginning.*$" {
send_gdb "y\n"
gdb_expect {
-re ".*$gdb_prompt $" { pass "restart" }
}
}
-re ".*Starting program.*$gdb_prompt $" {
pass "restart after previous fails"
}
-re ".*$gdb_prompt $" { fail "Can't restart" }
}
gdb_test "i ad a_global" ".*a_global.*static storage at address.*" "i ad a_global"
gdb_test "i add me" ".*me.*local variable at frame offset.*" "i ad me"
gdb_test "i ad a_thread_local" ".*a_thread_local.*a thread-local variable at offset.*" "i ad a_thread_local"
# Done!
#
gdb_exit
set timeout $oldtimeout
set verbose $oldverbose
# execute_anywhere "rm -f ${binfile}"
#
return 0

View File

@ -0,0 +1,146 @@
# 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
}
#
# test special commands
#
set prms_id 0
set bug_id 0
set testfile "run-hp"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
gdb_exit
gdb_start
delete_breakpoints
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
proc watchpoint_command_test {} {
global gdb_prompt
if [target_info exists noargs] {
verbose "Skipping watchpoint_command_test because of noargs."
return
}
if { ![runto factorial] } then { gdb_suppress_tests }
# Don't depend upon argument passing, since most simulators don't currently
# support it. Bash value variable to be what we want.
gdb_test "p value=6" "" "set value to 6 in watchpoint_command_test"
delete_breakpoints
# Verify that we can create a watchpoint, and give it a commands
# list that continues the inferior. We set the watchpoint on a
# local variable, too, so that it self-deletes when the watched
# data goes out of scope.
#
# What should happen is: Each time the watchpoint triggers, it
# continues the inferior. Eventually, the watchpoint will self-
# delete, when the watched variable is out of scope. But by that
# time, the inferior should have exited. GDB shouldn't crash or
# anything untoward as a result of this.
#
send_gdb "watch local_var\n"
gdb_expect {
-re ".*\[Ww\]atchpoint (\[0-9\]*): local_var.*$gdb_prompt $"\
{ pass "watch local_var"
set wp_id $expect_out(1,string)
send_gdb "commands $wp_id\n"
gdb_expect {
-re "Type commands for when breakpoint $wp_id is hit, one per line.*>"\
{ pass "begin commands on watch"}
-re "$gdb_prompt $"\
{fail "begin commands on watch"}
timeout {fail "(timeout) begin commands on watch"}
}
}
-re "$gdb_prompt $"\
{fail "watch local_var"}
timeout {fail "(timeout) watch local_var"}
}
# set wp_id $expect_out(1,string)
# send_gdb "commands $wp_id\n"
# gdb_expect {
# -re "Type commands for when breakpoint $wp_id is hit, one per line.*>"\
# {pass "begin commands on watch"}
# -re "$gdb_prompt $"\
# {fail "begin commands on watch"}
# timeout {fail "(timeout) begin commands on watch"}
# }
send_gdb "print value\n"
gdb_expect {
-re ">"\
{pass "add print command to watch"}
-re "$gdb_prompt $"\
{fail "add print command to watch"}
timeout {fail "(timeout) add print command to watch"}
}
send_gdb "continue\n"
gdb_expect {
-re ">"\
{pass "add continue command to watch"}
-re "$gdb_prompt $"\
{fail "add continue command to watch"}
timeout {fail "(timeout) add continue command to watch"}
}
send_gdb "end\n"
gdb_expect {
-re "$gdb_prompt $"\
{pass "begin commands on watch"}
timeout {fail "(timeout) begin commands on watch"}
}
send_gdb "continue\n"
gdb_expect {
-re "Continuing.*\[Ww\]atchpoint $wp_id deleted because the program has left the block in.*which its expression is valid.*in main.*$gdb_prompt $"\
{pass "continue with watch"}
-re "$gdb_prompt $"\
{fail "continue with watch"}
timeout {fail "(timeout) continue with watch"}
}
send_gdb "continue\n"
gdb_expect {
-re "Continuing.*$gdb_prompt $"\
{pass "continue until exit"}
-re "$gdb_prompt $"\
{fail "continue until exit"}
timeout {fail "(timeout) continue until exit"}
}
}
watchpoint_command_test

View File

@ -0,0 +1,166 @@
#include <stdio.h>
/*
* Since using watchpoints can be very slow, we have to take some pains to
* ensure that we don't run too long with them enabled or we run the risk
* of having the test timeout. To help avoid this, we insert some marker
* functions in the execution stream so we can set breakpoints at known
* locations, without worrying about invalidating line numbers by changing
* this file. We use null bodied functions are markers since gdb does
* not support breakpoints at labeled text points at this time.
*
* One place we need is a marker for when we start executing our tests
* instructions rather than any process startup code, so we insert one
* right after entering main(). Another is right before we finish, before
* we start executing any process termination code.
*
* Another problem we have to guard against, at least for the test
* suite, is that we need to ensure that the line that causes the
* watchpoint to be hit is still the current line when gdb notices
* the hit. Depending upon the specific code generated by the compiler,
* the instruction after the one that triggers the hit may be part of
* the same line or part of the next line. Thus we ensure that there
* are always some instructions to execute on the same line after the
* code that should trigger the hit.
*/
int count = -1;
int ival1 = -1;
int ival2 = -1;
int ival3 = -1;
int ival4 = -1;
int ival5 = -1;
char buf[10];
struct foo
{
int val;
};
struct foo struct1, struct2, *ptr1, *ptr2;
int doread = 0;
void marker1 ()
{
}
void marker2 ()
{
}
void marker4 ()
{
}
void marker5 ()
{
}
void marker6 ()
{
}
void recurser (x)
int x;
{
int local_x;
if (x > 0)
recurser (x-1);
local_x = x;
}
void
func2 ()
{
int local_a;
static int static_b;
ival5++;
local_a = ival5;
static_b = local_a;
}
int
func1 ()
{
/* The point of this is that we will set a breakpoint at this call.
Then, if DECR_PC_AFTER_BREAK equals the size of a function call
instruction (true on a sun3 if this is gcc-compiled--FIXME we
should use asm() to make it work for any compiler, present or
future), then we will end up branching to the location just after
the breakpoint. And we better not confuse that with hitting the
breakpoint. */
func2 ();
return 73;
}
int main ()
{
struct1.val = 1;
struct2.val = 2;
ptr1 = &struct1;
ptr2 = &struct2;
marker1 ();
func1 ();
for (count = 0; count < 4; count++) {
ival1 = count;
ival3 = count; ival4 = count;
}
ival1 = count; /* Outside loop */
ival2 = count;
ival3 = count; ival4 = count;
marker2 ();
if (doread)
{
static char msg[] = "type stuff for buf now:";
write (1, msg, sizeof (msg) - 1);
read (0, &buf[0], 5);
}
marker4 ();
/* We have a watchpoint on ptr1->val. It should be triggered if
ptr1's value changes. */
ptr1 = ptr2;
/* This should not trigger the watchpoint. If it does, then we
used the wrong value chain to re-insert the watchpoints or we
are not evaluating the watchpoint expression correctly. */
struct1.val = 5;
marker5 ();
/* We have a watchpoint on ptr1->val. It should be triggered if
ptr1's value changes. */
ptr1 = ptr2;
/* This should not trigger the watchpoint. If it does, then we
used the wrong value chain to re-insert the watchpoints or we
are not evaluating the watchpoint expression correctly. */
struct1.val = 5;
marker5 ();
/* We're going to watch locals of func2, to see that out-of-scope
watchpoints are detected and properly deleted.
*/
marker6 ();
/* This invocation is used for watches of a single
local variable. */
func2 ();
/* This invocation is used for watches of an expression
involving a local variable. */
func2 ();
/* This invocation is used for watches of a static
(non-stack-based) local variable. */
func2 ();
/* This invocation is used for watches of a local variable
when recursion happens.
*/
marker6 ();
recurser (2);
marker6 ();
return 0;
}

View File

@ -0,0 +1,779 @@
# 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 Fred Fish. (fnf@cygnus.com)
if $tracelevel then {
strace $tracelevel
}
set prms_id 0
set bug_id 0
set testfile "watch-hp"
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."
}
# Prepare for watchpoint tests by setting up two breakpoints and one
# watchpoint.
#
# We use breakpoints at marker functions to get past all the startup code,
# so we can get to the watchpoints in a reasonable amount of time from a
# known starting point.
#
# For simplicity, so we always know how to reference specific breakpoints or
# watchpoints by number, we expect a particular ordering and numbering of
# each in the combined breakpoint/watchpoint table, as follows:
#
# Number What Where
# 1 Breakpoint marker1()
# 2 Breakpoint marker2()
# 3 Watchpoint ival3
proc initialize {} {
global gdb_prompt
global hex
global decimal
global srcfile
if [gdb_test "break marker1" "Breakpoint 1 at $hex: file .*$srcfile, line $decimal.*" "set breakpoint at marker1" ] {
return 0;
}
if [gdb_test "break marker2" "Breakpoint 2 at $hex: file .*$srcfile, line $decimal.*" "set breakpoint at marker2" ] {
return 0;
}
if [gdb_test "info break" "1\[ \]*breakpoint.*marker1.*\r\n2\[ \]*breakpoint.*marker2.*" "info break in watchpoint.exp" ] {
return 0;
}
# ??rehrauer: To fix DTS #CHFts23014, in which setting a watchpoint
# before running can cause the inferior to croak on HP-UX 10.30 and
# 11.0 for reasons as yet unknown, we've disabled the ability to set
# watches without a running inferior. Verify the restriction.
#
send_gdb "watch ival3\n"
gdb_expect {
-re ".*can't do that without a running program; try \"break main\", \"run\" first.*$gdb_prompt $" {
pass "set watchpoint on ival3"
}
-re ".*$gdb_prompt $" { fail "set watchpoint on ival3" }
timeout { fail "set watchpoint on ival3 (timeout)" }
}
# if [gdb_test "watch ival3" ".*\[Ww\]atchpoint 3: ival3" "set watchpoint on ival3" ] {
# return 0;
# }
# "info watch" is the same as "info break"
# if [gdb_test "info watch" "1\[ \]*breakpoint.*marker1.*\r\n2\[ \]*breakpoint.*marker2.*\r\n3\[ \]*.*watchpoint.*ival3" "watchpoint found in watchpoint/breakpoint table" ] {
# return 0;
# }
# After installing the watchpoint, we disable it until we are ready
# to use it. This allows the test program to run at full speed until
# we get to the first marker function.
# if [gdb_test "disable 3" "disable 3\[\r\n\]+" "disable watchpoint" ] {
# return 0;
# }
return 1
}
#
# Test simple watchpoint.
#
proc test_simple_watchpoint {} {
global gdb_prompt
global hex
global decimal
# Ensure that the watchpoint is disabled when we startup.
# if [gdb_test "disable 3" "^disable 3\[\r\n\]+" "disable watchpoint in test_simple_watchpoint" ] {
# return 0;
# }
# Run until we get to the first marker function.
gdb_run_cmd
set timeout 600
gdb_expect {
-re "Breakpoint 1, marker1 .*$gdb_prompt $" {
pass "run to marker1 in test_simple_watchpoint"
}
-re ".*$gdb_prompt $" {
fail "run to marker1 in test_simple_watchpoint"
return
}
timeout {
fail "run to marker1 in test_simple_watchpoint (timeout)"
return
}
}
#************************
# ??rehrauer: To fix DTS #CHFts23014, in which setting a watchpoint
# before running can cause the inferior to croak on HP-UX 10.30 and
# 11.0 for reasons as yet unknown, we've disabled the ability to set
# watches without a running inferior. The following testpoints used
# to be in [initialize].
#
send_gdb "watch ival3\n"
gdb_expect {
-re ".*\[Ww\]atchpoint 3: ival3\r\n$gdb_prompt $" {
pass "set watchpoint on ival3"
}
-re ".*$gdb_prompt $" { fail "set watchpoint on ival3" }
timeout { fail "set watchpoint on ival3 (timeout)" }
}
# "info watch" is the same as "info break"
send_gdb "info watch\n"
gdb_expect {
-re "1\[ \]*breakpoint.*marker1.*\r\n2\[ \]*breakpoint.*marker2.*\r\n3\[ \]*.*watchpoint.*ival3\r\n$gdb_prompt $" {
pass "watchpoint found in watchpoint/breakpoint table"
}
-re ".*$gdb_prompt $" {
fail "watchpoint found in watchpoint/breakpoint table"
}
timeout {
fail "watchpoint found in watchpoint/breakpoint table"
}
}
# After installing the watchpoint, we disable it until we are ready
# to use it. This allows the test program to run at full speed until
# we get to the first marker function.
send_gdb "disable 3\n"
gdb_expect {
-re "disable 3\[\r\n\]+$gdb_prompt $" { pass "disable watchpoint" }
-re ".*$gdb_prompt $" { fail "disable watchpoint" }
timeout { fail "disable watchpoint (timeout)" }
}
#******
# After reaching the marker function, enable the watchpoint.
if [gdb_test "enable 3" "^enable 3\[\r\n\]+" "enable watchpoint" ] {
return ;
}
gdb_test "break func1" "Breakpoint.*at.*"
gdb_test "set \$func1_breakpoint_number = \$bpnum" ""
gdb_test "continue" "Continuing.*Breakpoint \[0-9\]*, func1.*" \
"continue to breakpoint at func1"
# Continue until the first change, from -1 to 0
send_gdb "cont\n"
gdb_expect {
-re "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = -1.*New value = 0.*ival3 = count; ival4 = count;.*$gdb_prompt $" {
pass "watchpoint hit, first time"
}
-re "Continuing.*Breakpoint.*func1.*$gdb_prompt $" {
setup_xfail "m68*-*-*" 2597
fail "thought it hit breakpoint at func1 twice"
gdb_test "delete \$func1_breakpoint_number" ""
gdb_test "continue" "\
Continuing.*\[Ww\]atchpoint.*ival3.*Old value = -1.*New value = 0.*ival3 = count;" \
"watchpoint hit, first time"
}
-re ".*$gdb_prompt $" { fail "watchpoint hit, first time" ; return }
timeout { fail "watchpoint hit, first time (timeout)" ; return }
eof { fail "watchpoint hit, first time (eof)" ; return }
}
gdb_test "delete \$func1_breakpoint_number" ""
# Continue until the next change, from 0 to 1.
gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 0.*New value = 1.*ival3 = count; ival4 = count;.*" "watchpoint hit, second time"
# Continue until the next change, from 1 to 2.
gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 1.*New value = 2.*ival3 = count; ival4 = count;.*" "watchpoint hit, third time"
# Continue until the next change, from 2 to 3.
gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 2.*New value = 3.*ival3 = count; ival4 = count;.*" "watchpoint hit, fourth time"
# Continue until the next change, from 3 to 4.
# Note that this one is outside the loop.
gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 3.*New value = 4.*ival3 = count; ival4 = count;.*" "watchpoint hit, fifth time"
# Continue until we hit the finishing marker function.
# Make sure we hit no more watchpoints.
gdb_test "cont" "Continuing.*Breakpoint.*marker2 \(\).*" \
"continue to marker2"
# Disable the watchpoint so we run at full speed until we exit.
if [gdb_test "disable 3" "^disable 3\[\r\n\]+" "watchpoint disabled" ] {
return ;
}
# Run until process exits.
if [target_info exists gdb,noresults] { return }
gdb_test "cont" "Continuing.*Program exited normally.*" \
"continue to exit in test_simple_watchpoint"
}
# Test disabling watchpoints.
proc test_disabling_watchpoints {} {
global gdb_prompt
global binfile
global srcfile
global decimal
global hex
# Ensure that the watchpoint is disabled when we startup.
if [gdb_test "disable 3" "^disable 3\[\r\n\]+" "disable watchpoint in test_disabling_watchpoints" ] {
return 0;
}
# Run until we get to the first marker function.
gdb_run_cmd
set timeout 600
gdb_expect {
-re "Breakpoint 1, marker1 .*$gdb_prompt $" {
pass "run to marker1 in test_disabling_watchpoints"
}
-re ".*$gdb_prompt $" {
fail "run to marker1 in test_disabling_watchpoints"
return
}
timeout {
fail "run to marker1 in test_disabling_watchpoints (timeout)"
return
}
}
# After reaching the marker function, enable the watchpoint.
if [gdb_test "enable 3" "^enable 3\[\r\n\]+" "watchpoint enabled" ] {
return ;
}
# Continue until the first change, from -1 to 0
# Don't check the old value, because on VxWorks the variable value
# will not have been reinitialized.
gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = .*New value = 0.*ival3 = count; ival4 = count;.*" "watchpoint hit in test_disabling_watchpoints, first time"
# Continue until the next change, from 0 to 1.
gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ival3.*Old value = 0.*New value = 1.*ival3 = count; ival4 = count;.*" "watchpoint hit in test_disabling_watchpoints, second time"
# Disable the watchpoint but leave breakpoints
if [gdb_test "disable 3" "^disable 3\[\r\n\]+" "disable watchpoint #2 in test_disabling_watchpoints" ] {
return 0;
}
# Check watchpoint list, looking for the entry that confirms the
# watchpoint is disabled.
gdb_test "info watchpoints" "3\[ \]*.*watchpoint\[ \]*keep\[ \]*n\[ \]*ival3\r\n.*" "watchpoint disabled in table"
# Continue until we hit the finishing marker function.
# Make sure we hit no more watchpoints.
gdb_test "cont" "Continuing.*Breakpoint.*marker2 \\(\\).*" \
"disabled watchpoint skipped"
if [target_info exists gdb,noresults] { return }
gdb_test "cont" "Continuing.*Program exited normally.*" \
"continue to exit in test_disabling_watchpoints"
}
# Test stepping and other mundane operations with watchpoints enabled
proc test_stepping {} {
global gdb_prompt
if [runto marker1] then {
gdb_test "watch ival2" ".*\[Ww\]atchpoint \[0-9\]*: ival2"
# Well, let's not be too mundane. It should be a *bit* of a challenge
gdb_test "break func2 if 0" "Breakpoint.*at.*"
gdb_test "p \$func2_breakpoint_number = \$bpnum" " = .*"
# The HPPA has a problem here if it's not using hardware watchpoints
if {[ istarget "hppa*-*-*" ] && ![ istarget "hppa*-*-*bsd*" ]} then {
# Don't actually try doing the call, if we do we can't continue.
setup_xfail "*-*-*"
fail "calling function with watchpoint enabled"
} else {
# The problem is that GDB confuses stepping through the call
# dummy with hitting the breakpoint at the end of the call dummy.
# Will be fixed once all architectures define
# CALL_DUMMY_BREAKPOINT_OFFSET.
setup_xfail "*-*-*"
# This doesn't occur if the call dummy starts with a call,
# because we are out of the dummy by the first time the inferior
# stops.
clear_xfail "d10v*-*-*"
clear_xfail "m68*-*-*"
clear_xfail "i*86*-*-*"
clear_xfail "vax-*-*"
# The following architectures define CALL_DUMMY_BREAKPOINT_OFFSET.
clear_xfail "alpha-*-*"
clear_xfail "mips*-*-*"
clear_xfail "sparc-*-*"
clear_xfail "hppa*-*-*bsd*"
# It works with the generic inferior function calling code too.
clear_xfail "mn10200*-*-*"
clear_xfail "mn10300*-*-*"
gdb_test "p func1 ()" "= 73" \
"calling function with watchpoint enabled"
}
#
# "finish" brings us back to main.
# On some targets (e.g. alpha) gdb will stop from the finish in midline
# of the marker1 call. This is due to register restoring code on
# the alpha and might be caused by stack adjustment instructions
# on other targets. In this case we will step once more.
#
send_gdb "finish\n"
gdb_expect {
-re "Run.*exit from.*marker1.* at" { }
default { fail "finish from marker1" ; return }
}
gdb_expect {
-re "marker1 \\(\\);.*$gdb_prompt $" {
send_gdb "step\n"
exp_continue
}
-re "func1 \\(\\);.*$gdb_prompt $" {
pass "finish from marker1"
}
-re ".*$gdb_prompt $" {
fail "finish from marker1"
}
default { fail "finish from marker1" ; return }
}
gdb_test "next" "for \\(count = 0.*" "next to `for' in watchpoint.exp"
# Now test that "until" works. It's a bit tricky to test
# "until", because compilers don't always arrange the code
# exactly the same way, and we might get slightly different
# sequences of statements. But the following should be true
# (if not it is a compiler or a debugger bug): The user who
# does "until" at every statement of a loop should end up
# stepping through the loop once, and the debugger should not
# stop for any of the remaining iterations.
gdb_test "until" "ival1 = count.*" "until to ival1 assignment"
gdb_test "until" "ival3 = count.*" "until to ival3 assignment"
send_gdb "until\n"
gdb_expect {
-re "(for \\(count = 0|\}).*$gdb_prompt $" {
gdb_test "until" "ival1 = count; /. Outside loop ./" \
"until out of loop"
}
-re "ival1 = count; /. Outside loop ./.*$gdb_prompt $" {
pass "until out of loop"
}
-re ".*$gdb_prompt $" {
fail "until out of loop"
}
default { fail "until out of loop" ; return }
}
gdb_test "step" "ival2 = count.*" "step to ival2 assignment"
}
}
# Test stepping and other mundane operations with watchpoints enabled
proc test_watchpoint_triggered_in_syscall {} {
global gdb_prompt
if [target_info exists gdb,noinferiorio] {
verbose "Skipping test_watchpoint_triggered_in_syscall due to noinferiorio"
return
}
# Run until we get to the first marker function.
set x 0
set y 0
set testname "Watch buffer passed to read syscall"
if [runto marker2] then {
gdb_test "watch buf\[0\]" ".*\[Ww\]atchpoint \[0-9\]*: buf\\\[0\\\]"
gdb_test "watch buf\[1\]" ".*\[Ww\]atchpoint \[0-9\]*: buf\\\[1\\\]"
gdb_test "watch buf\[2\]" ".*\[Ww\]atchpoint \[0-9\]*: buf\\\[2\\\]"
gdb_test "watch buf\[3\]" ".*\[Ww\]atchpoint \[0-9\]*: buf\\\[3\\\]"
gdb_test "watch buf\[4\]" ".*\[Ww\]atchpoint \[0-9\]*: buf\\\[4\\\]"
gdb_test "break marker4" ".*Breakpoint.*"
gdb_test "set doread = 1" ""
# If we send_gdb "123\n" before gdb has switched the tty, then it goes
# to gdb, not the inferior, and we lose. So that is why we have
# watchpoint.c prompt us, so we can wait for that prompt.
send_gdb "continue\n";
gdb_expect {
-re "Continuing\\.\r\ntype stuff for buf now:" {
pass "continue to read"
}
default {
fail "continue to read";
return ;
}
}
send_gdb "123\n"
gdb_expect {
-re ".*\[Ww\]atchpoint.*buf\\\[0\\\].*Old value = 0.*New value = 49\[^\n\]*\n" { set x [expr $x+1] ; exp_continue }
-re ".*\[Ww\]atchpoint.*buf\\\[1\\\].*Old value = 0.*New value = 50\[^\n\]*\n" { set x [expr $x+1] ; exp_continue }
-re ".*\[Ww\]atchpoint.*buf\\\[2\\\].*Old value = 0.*New value = 51\[^\n\]*\n" { set x [expr $x+1] ; exp_continue }
-re ".*\[Ww\]atchpoint.*buf\\\[3\\\].*Old value = 0.*New value = 10\[^\n\]*\n" { set x [expr $x+1] ; exp_continue }
-re ".*$gdb_prompt $" { pass "sent 123" }
timeout { fail "sent 123 (timeout)" }
}
# Examine the values in buf to see how many watchpoints we
# should have printed.
send_gdb "print buf\[0\]\n"
gdb_expect {
-re ".*= 49.*$gdb_prompt $" { set y [expr $y+1]; pass "print buf\[0\]"}
-re ".*= 0.*$gdb_prompt $" { pass "print buf\[0\]"}
-re ".*$gdb_prompt $" { fail "print buf\[0\]"}
default { fail "print buf\[0\]"}
}
send_gdb "print buf\[1\]\n"
gdb_expect {
-re ".*= 50.*$gdb_prompt $" { set y [expr $y+1]; pass "print buf\[1\]"}
-re ".*= 0.*$gdb_prompt $" { pass "print buf\[1\]"}
-re ".*$gdb_prompt $" { fail "print buf\[1\]"}
default { fail "print buf\[1\]"}
}
send_gdb "print buf\[2\]\n"
gdb_expect {
-re ".*= 51.*$gdb_prompt $" { set y [expr $y+1]; pass "print buf\[2\]"}
-re ".*= 0.*$gdb_prompt $" { pass "print buf\[2\]"}
-re ".*$gdb_prompt $" { fail "print buf\[2\]"}
default { fail "print buf\[2\]"}
}
send_gdb "print buf\[3\]\n"
gdb_expect {
-re ".*= 10.*$gdb_prompt $" { set y [expr $y+1]; pass "print buf\[3\]"}
-re ".*= 0.*$gdb_prompt $" { pass "print buf\[3\]"}
-re ".*$gdb_prompt $" { fail "print buf\[3\]" }
default { fail "print buf\[3\]" }
}
# Did we find what we were looking for? If not, flunk it.
if [expr $x==$y] then { pass $testname } else { fail "$testname (only triggered $x watchpoints, expected $y)"}
# Continue until we hit the finishing marker function.
# Make sure we hit no more watchpoints.
gdb_test "cont" "Continuing.*Breakpoint.*marker4 \\(\\).*" \
"continue to marker4"
# Disable everything so we can finish the program at full speed
gdb_test "disable" "" "disable in test_watchpoint_triggered_in_syscall"
if [target_info exists gdb,noresults] { return }
gdb_test "cont" "Continuing.*Program exited normally.*" \
"continue to exit in test_watchpoint_triggered_in_syscall"
}
}
# Do a simple test of of watching through a pointer when the pointer
# itself changes. Should add some more complicated stuff here.
proc test_complex_watchpoint {} {
global gdb_prompt
if [runto marker4] then {
gdb_test "watch ptr1->val" ".*\[Ww\]atchpoint \[0-9\]*: ptr1->val"
gdb_test "break marker5" ".*Breakpoint.*"
gdb_test "cont" "Continuing.*\[Ww\]atchpoint.*ptr1->val.*Old value = 1.*New value = 2.*" "Test complex watchpoint"
# Continue until we hit the marker5 function.
# Make sure we hit no more watchpoints.
gdb_test "cont" "Continuing.*Breakpoint.*marker5 \\(\\).*" \
"did not trigger wrong watchpoint"
#********************
# Test watches of things declared locally in a function.
# In particular, test that a watch of stack-based things
# is deleted when the stack-based things go out of scope.
#
gdb_test "disable" "" "disable in test_complex_watchpoint"
gdb_test "break marker6" ".*Breakpoint.*"
gdb_test "cont" "Continuing.*Breakpoint.*marker6 \\(\\).*" \
"continue to marker6"
gdb_test "break func2" ".*Breakpoint.*"
gdb_test "cont" "Continuing.*func2.*"
# Test a watch of a single stack-based variable, whose scope
# is the function we're now in. This should auto-delete when
# execution exits the scope of the watchpoint.
#
gdb_test "watch local_a" ".*\[Ww\]atchpoint \[0-9\]*: local_a" "set local watch"
gdb_test "cont" "\[Ww\]atchpoint.*local_a.*" "trigger local watch"
gdb_test "cont" "Continuing.*Watchpoint .* deleted because the program has left the block in.*which its expression is valid.*" "self-delete local watch"
# after func2 returned, gdb stopped and deleted the watchpoint
# we're now in main, let's get to func2
gdb_test "cont" "Continuing.*func2.*"
# We should be in "func2" again now. Test a watch of an
# expression which includes both a stack-based local and
# something whose scope is larger than this invocation
# of "func2". This should also auto-delete.
#
gdb_test "watch local_a + ival5" ".*\[Ww\]atchpoint \[0-9\]*: local_a . ival5" \
"set partially local watch"
gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: local_a . ival5.*" \
"trigger1 partially local watch"
gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: local_a . ival5.*" \
"trigger2 partially local watch"
gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" \
"self-delete partially local watch"
# after func2 returned, gdb stopped and deleted the watchpoint
# we're now in main, let's get to func2
gdb_test "cont" "Continuing.*func2.*"
# We should be in "func2" again now. Test a watch of a
# static (non-stack-based) local. Since this has scope
# across any invocations of "func2", it should not auto-
# delete.
#
gdb_test "watch static_b" ".*\[Ww\]atchpoint \[0-9\]*: static_b" \
"set static local watch"
gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: static_b.*" \
"trigger static local watch"
gdb_test "cont" "Continuing.*marker6 \\(\\).*" \
"continue after trigger static local watch"
gdb_test "info break" ".*watchpoint.*static_b.*" \
"static local watch did not self-delete"
# We should be in "recurser" now. Test a watch of a stack-
# based local. Symbols mentioned in a watchpoint are bound
# at watchpoint-creation. Thus, a watch of a stack-based
# local to a recursing function should be bound only to that
# one invocation, and should not trigger for other invocations.
#
gdb_test "tbreak recurser" ".*Breakpoint.*"
gdb_test "cont" "Continuing.*recurser.*"
gdb_test "watch local_x" ".*\[Ww\]atchpoint \[0-9\]*: local_x" \
"set local watch in recursive call"
gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: local_x.*New value = 2.*" \
"trigger local watch in recursive call"
gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" \
"self-delete local watch in recursive call"
#******************
# Disable everything so we can finish the program at full speed
gdb_test "disable" "" "disable in test_complex_watchpoint"
if [target_info exists gdb,noresults] { return }
gdb_test "cont" "Continuing.*Program exited normally.*" \
"continue to exit in test_complex_watchpoint"
}
}
# Start with a fresh gdb.
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $binfile
set timeout 600
verbose "Timeout now 600 sec.\n"
if [initialize] then {
test_simple_watchpoint
# The IDT/sim monitor only has 8 (!) open files, of which it uses
# 4 (!). So we have to make sure one program exits before
# starting another one.
if [istarget "mips-idt-*"] then {
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $binfile
initialize
}
test_disabling_watchpoints
# See above.
if [istarget "mips-idt-*"] then {
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $binfile
initialize
}
if ![target_info exists gdb,cannot_call_functions] {
test_stepping
# See above.
if [istarget "mips-idt-*"] then {
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $binfile
initialize
}
}
# Only enabled for some targets merely because it has not been tested
# elsewhere.
# On sparc-sun-sunos4.1.3, GDB was running all the way to the marker4
# breakpoint before stopping for the watchpoint. I don't know why.
if {[istarget "hppa*-*-*"]} then {
test_watchpoint_triggered_in_syscall
}
# See above.
if [istarget "mips-idt-*"] then {
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load $binfile
initialize
}
# Only enabled for some targets merely because it has not been tested
# elsewhere.
if {[istarget "hppa*-*-*"] || \
[istarget "sparc*-*-sunos*"] || \
[istarget "m32r-*-*"]} then {
test_complex_watchpoint
#***************
}
# Verify that a user can force GDB to use "slow" watchpoints.
# (This proves rather little on kernels that don't support
# fast watchpoints, but still...)
#
if ![runto_main] then { fail "watch tests suppressed" }
send_gdb "set can-use-hw-watchpoints 0\n"
gdb_expect {
-re "$gdb_prompt $"\
{pass "disable fast watches"}
timeout {fail "(timeout) disable fast watches"}
}
send_gdb "show can-use-hw-watchpoints\n"
gdb_expect {
-re "Debugger's willingness to use watchpoint hardware is 0.*$gdb_prompt $"\
{pass "show disable fast watches"}
-re "$gdb_prompt $"\
{fail "show disable fast watches"}
timeout {fail "(timeout) show disable fast watches"}
}
send_gdb "watch ival3 if count > 1\n"
gdb_expect {
-re "Watchpoint \[0-9\]*: ival3.*$gdb_prompt $"\
{pass "set slow conditional watch"}
-re "$gdb_prompt $"\
{fail "set slow conditional watch"}
timeout {fail "(timeout) set slow conditional watch"}
}
send_gdb "continue\n"
gdb_expect {
-re "Watchpoint \[0-9\]*: ival3.*Old value = 1.*New value = 2.*$gdb_prompt $"\
{pass "trigger slow conditional watch"}
-re "$gdb_prompt $"\
{fail "trigger slow conditional watch"}
timeout {fail "(timeout) trigger slow conditional watch"}
}
# We've explicitly disabled hardware watches. Verify that GDB
#
#
send_gdb "rwatch ival3\n"
gdb_expect {
-re "Expression cannot be implemented with read/access watchpoint..*$gdb_prompt $"\
{pass "rwatch disallowed when can-set-hw-watchpoints cleared"}
-re "$gdb_prompt $"\
{fail "rwatch disallowed when can-set-hw-watchpoints cleared"}
timeout {fail "(timeout) rwatch disallowed when can-use-hw-watchpoints cleared"}
}
# Read- and access watchpoints are unsupported on HP-UX. Verify
# that GDB gracefully responds to requests to create them.
#
if [istarget "hppa*-*-hpux*"] then {
send_gdb "set can-use-hw-watchpoints 1\n"
gdb_expect {
-re "$gdb_prompt $"\
{pass "enable fast watches"}
timeout {fail "(timeout) enable fast watches"}
}
send_gdb "rwatch ival3\n"
gdb_expect {
-re "Target does not have this type of hardware watchpoint support.*$gdb_prompt $"\
{pass "read watches disallowed"}
-re "$gdb_prompt $"\
{fail "read watches disallowed"}
timeout {fail "(timeout) read watches disallowed"}
}
send_gdb "awatch ival3\n"
gdb_expect {
-re "Target does not have this type of hardware watchpoint support.*$gdb_prompt $"\
{pass "access watches disallowed"}
-re "$gdb_prompt $"\
{fail "access watches disallowed"}
timeout {fail "(timeout) access watches disallowed"}
}
#***************
}
}

View File

@ -0,0 +1,71 @@
# 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 then {
strace $tracelevel
}
global usestubs
#
# test running programs
#
set prms_id 0
set bug_id 0
set testfile "xdb"
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."
}
global GDBFLAGS
set saved_gdbflags $GDBFLAGS
set GDBFLAGS "$GDBFLAGS --xdb"
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
gdb_test "set pagination off" ""
gdb_test "show pagination" "State of pagination is off."
gdb_test "set pagination on" ""
gdb_test "show pagination" "State of pagination is on."
gdb_test "txbreak callee" "Breakpoint.*at.*"
gdb_test "info break" "Num.*Type.*Disp.*Enb.*Address.*What\r\n.*breakpoint.*del.*y.*"
gdb_test "xbreak callee" "Breakpoint.*at.*.*"
gdb_test "info break" "Num.*Type.*Disp.*Enb.*Address.*What\r\n.*breakpoint.*keep.*y.*"
gdb_exit
set GDBFLAGS $saved_gdbflags
return 0

View File

@ -0,0 +1,97 @@
# 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 then {
strace $tracelevel
}
global message
#
# test running programs
#
set prms_id 0
set bug_id 0
set testfile "xdb"
set binfile ${objdir}/${subdir}/${testfile}
if { [gdb_compile "${srcdir}/${subdir}/xdb0.c" "${binfile}0.o" object {debug}] != "" } {
perror "Couldn't compile ${testfile}0.c to object"
return -1
}
if { [gdb_compile "${srcdir}/${subdir}/xdb1.c" "${binfile}1.o" object {debug}] != "" } {
perror "Couldn't compile ${testfile}1.c to object"
return -1
}
if { [gdb_compile "${binfile}0.o ${binfile}1.o" ${binfile} executable {debug}] != "" } {
perror "Couldn't link ${testfile}."
return -1
}
global GDBFLAGS
set saved_gdbflags $GDBFLAGS
set GDBFLAGS "$GDBFLAGS --xdb"
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
gdb_test "break main" ""
gdb_test "run" ""
gdb_test "go +2" "Breakpoint.*at.*file.*xdb0\.c, line 12\.\r\nContinuing at.*\r\nmain \\(\\) at.*xdb0\.c:12\r\n12\[ \t\]+foo \\(x\\+\\+\\);"
gdb_test "go -2" "Note: breakpoint.*also set at pc.*\.\r\nBreakpoint.*at.*file.*xdb0\.c, line 10\.\r\nContinuing at.*\.\r\n\r\nBreakpoint.*, main \\(\\) at.*xdb0\.c:10.*"
gdb_test "go 16" "Breakpoint.*at.*file.*xdb0\.c, line 16\.\r\nContinuing at.*\.\r\nmain \\(\\) at.*xdb0\.c:16\r\n16\[ \t\]+foo \\(x\\+\\+\\);"
send_gdb "go bar\n"
gdb_expect {
-re ".*Line 5 is not in .main.. Jump anyway.*y or n. $" {
send_gdb "y\n"
gdb_expect {
-re "$gdb_prompt $"\
{pass "go bar"}
timeout {fail "(timeout) go bar"}
}
}
-re "Continuing at.*\.\r\nbar \\(x=0\\) at.*xdb1\.c:5" {}
timeout { perror "(timeout) go bar" ; return }
}
# Verify that GDB responds gracefully to a "go" command without
# an argument.
#
gdb_test "go" "Usage: go <location>"
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
gdb_test "break bar" ""
gdb_test "run" ""
gdb_test "backtrace full" ".*bar \\(x=0\\) at.*xdb1\.c:5\r\nNo locals\.\r\n.1.* in foo \\(x=1\\) at.*xdb0\.h:8\r\nNo locals\.\r\n.2.* in main \\(\\) at.*xdb0\.c:11\r\n.*x = 1"
gdb_test "bt 1 full" ".*bar \\(x=0\\) at.*xdb1\.c:5\r\nNo locals\.\r\n\\(More stack frames follow\.\.\.\\)"
gdb_test "bt full 2" ".*bar \\(x=0\\) at.*xdb1\.c:5\r\nNo locals\.\r\n.1.* in foo \\(x=1\\) at.*xdb0\.h:8\r\nNo locals\.\r\n\\(More stack frames follow\.\.\.\\)"
set GDBFLAGS $saved_gdbflags
return 0

View File

@ -0,0 +1,301 @@
# 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 "xdb-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."
}
proc xdb_reinitialize_dir { subdir } {
global gdb_prompt
send_gdb "D\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 "D $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."
}
}
}
#
#test_search
#
proc test_search { } {
gdb_test "set listsize 4" ""
gdb_test "list average.c:1" "1\[ \t\]+/. This is a sample .*"
gdb_test "/ print_average" "10\[ \t\]+void print_average\\(int list.*"
gdb_test "/ print_average" "12\[ \t\]+void print_average\\(list, low, high\\)"
gdb_test "/ print_average" "35\[ \t\]+print_average \\(my_list, first, last\\);"
gdb_test "? print_average" "12\[ \t\]+void print_average\\(list, low, high\\)"
gdb_test "? sum" "Expression not found"
}
#
#test_viewing_loc
#
proc test_viewing_loc { } {
gdb_test "L" "No stack."
gdb_test "break main" ""
gdb_test "R" ""
gdb_test "L" "#0\[ \t\]+main \\(\\) at.*average.c:31\r\n31\[ \t\]+int first = 0;"
}
#
#test_dir_list
#
proc test_dir_list { } {
gdb_test "ld" "Source directories searched: .*"
}
#
#test_list_sources
#
proc test_list_sources { } {
gdb_test "lf" "Source files for which symbols have been read in:.*average\\.c,.*Source files for which symbols will be read in on demand:.*sum\\.c"
}
#
#test_vlist
#
proc test_vlist { } {
gdb_test "v main" "27\[ \t\]+main \\(\\)\r\n28\[ \t\]+#endif\r\n29\[ \t\]+.\r\n30\[ \t\]+char c;"
}
#
#test_va
#
proc test_va { } {
gdb_test "va main" "Dump of assembler code for function main:.*End of assembler dump\."
}
#
#test_list_globals
#
proc test_list_globals { } {
gdb_test "lg" "All defined variables:\r\n\r\nFile globals:.*"
# gdb_test "lg" "All defined variables:\r\n\r\nFile globals:\r\nchar __buffer.512.;\r\nint __d_eh_catch_catch;\r\nint __d_eh_catch_throw;.*"
}
#
#test_list_registers
#
proc test_list_registers { } {
gdb_test "lr" "\[ \t\]+flags:.*r18:.*pcsqt:.*ccr:.*\r\n\[ \t\]+r1:.*r19:.*eiem:.*cr12:.*"
gdb_test "lr r1" "r1 .*"
}
#
#test_backtrace
#
proc test_backtrace { } {
gdb_test "t" "#0 main \\(\\) at.*average.c:31"
gdb_test "T" "#0 main \\(\\) at.*average.c:31\r\n\[ \t\]+c = 0.*\r\n\[ \t\]+first = 0\r\n\[ \t\]+last = 0"
gdb_test "break sum" ""
gdb_test "cont" ""
gdb_test "t" "#0 sum \\(list=0x.*, low=0, high=9\\) at.*sum\.c:11\r\n#1 0x.* in print_average \\(list=0x.*, low=0, high=9\\) at.*average\.c:17\r\n#2 0x.* in main \\(\\) at.*average\.c:35"
gdb_test "t 1" "#0 sum \\(list=0x.*, low=0, high=9\\) at.*sum\.c:11\r\n\\(More stack frames follow\.\.\.\\)"
gdb_test "T" "#0 sum \\(list=0x.*, low=0, high=9\\) at.*sum\.c:11\r\n\[ \t\]+i = 0\r\n\[ \t\]+s = 0\r\n#1 0x.* in print_average \\(list=0x.*, low=0, high=9\\) at.*average\.c:17\r\n\[ \t\]+total = 0\r\n\[ \t\]+num_elements = 0\r\n\[ \t\]+average = 0\r\n#2 0x.* in main \\(\\) at.*average\.c:35\r\n\[ \t\]+c = 0 '.000'\r\n\[ \t\]+first = 0\r\n\[ \t\]+last = 9"
gdb_test "T 1" "#0 sum \\(list=0x.*, low=0, high=9\\) at.*sum\.c:11\r\n\[ \t\]+i = 0\r\n\[ \t\]+s = 0\r\n\\(More stack frames follow\.\.\.\\)"
gdb_test "V" "#0 sum \\(list=0x.*, low=0, high=9\\) at.*sum\.c:11\r\n\\11\[ \t\]+int i, s = 0;"
gdb_test "V 1" "#1 0x.* in print_average \\(list=0x.*, low=0, high=9\\) at.*average\.c:17\r\n17\[ \t\]+total = sum\\(list, low, high\\);"
}
#
# test_go
#
proc test_go { } {
gdb_test "break main" ""
gdb_test "R" ""
gdb_test "g +1" "Breakpoint.*at 0x.*: file.*average\.c, line 32\.\r\nContinuing at 0x.*\.\r\nmain \\(\\) at.*average\.c:32\r\n32\[ \t\]+int last = num-1;"
gdb_test "g 35" "Breakpoint.*at 0x.*: file.*average\.c, line 35\.\r\nContinuing at 0x.*\.\r\nmain \\(\\) at.*average\.c:35\r\n35\[ \t\]+print_average \\(my_list, first, last\\);"
}
#
#test_breakpoints
#
proc test_breakpoints { } {
global gdb_prompt
gdb_test "sb" ""
gdb_test "lb" "Num.*Type.*Disp.*Enb.*Address.*What\r\n1\[ \r\]+breakpoint\[ \r\]+keep n.*in main at.*average\.c:31.*"
gdb_test "ab" ""
gdb_test "lb" "Num.*Type.*Disp.*Enb.*Address.*What\r\n1\[ \r\]+breakpoint\[ \r\]+keep y.*in main at.*average\.c:31.*"
gdb_test "ba sum" "Breakpoint.*at.*: file.*sum\.c, line 11\."
gdb_test "cont" ""
gdb_test "bx" "Breakpoint.*at.*: file.*sum.c, line 15\."
gdb_test "bx if (1)" "Breakpoint.*at.*: file.*sum.c, line 15\."
gdb_test "bx 1" "Breakpoint.*at.*: file.*average.c, line 22\."
gdb_test "bx 1 if (1)" "Breakpoint.*at.*: file.*average.c, line 22\."
gdb_test "bc 1 2" "Will ignore next 2 crossings of breakpoint 1\."
gdb_test "lb 1" "Num.*Type.*Disp.*Enb.*Address.*What\r\n1\[ \r\]+breakpoint\[ \r\]+keep y.*in main at.*average\.c:31\r\n.*breakpoint already hit 1 time\r\n.*ignore next 2 hits.*"
send_gdb "db\n"
gdb_expect {
-re "Delete all breakpoints.*y or n. $" {
send_gdb "y\n"
exp_continue
}
-re "y\r\n$gdb_prompt $" {}
-re ".*$gdb_prompt $" { # This happens if there were no breakpoints
}
timeout { perror "Delete all breakpoints (timeout)" ; return }
}
send_gdb "lb\n"
gdb_expect {
-re "No breakpoints or watchpoints..*$gdb_prompt $" {}
-re ".*$gdb_prompt $" { perror "breakpoints not deleted" ; return }
timeout { perror "info breakpoints (timeout)" ; return }
}
gdb_test "xbreak" "Breakpoint.*at.*file.*sum.c, line 15."
gdb_test "xbreak print_average" "Breakpoint.*at.*file.*average.c, line 22."
gdb_test "xbreak if (1)" "Note: breakpoint.*also set at pc.*Breakpoint.*at.*file.*sum.c, line 15."
gdb_test "xbreak print_average if (1)" "Note: breakpoint.*also set at pc.*Breakpoint.*at.*file.*average.c, line 22."
send_gdb "lb\n"
gdb_expect {
-re "Num Type Disp Enb Address What.*breakpoint keep y.*in sum at.*sum.c:15.*breakpoint keep y.*in print_average at.*average.c:22.*breakpoint keep y.*in sum at.*sum.c:15.*stop only if 1.*breakpoint keep y.*in print_average at.*average.c:22.*stop only if 1.*$gdb_prompt $" {pass "lb on xbreaks"}
-re ".*$gdb_prompt $" { fail "breakpoints not deleted"}
timeout { fail "info breakpoints (timeout)" }
}
}
#
# test_signals
#
proc test_signals { } {
gdb_test "handle SIGTERM nostop noprint" ""
gdb_test "z SIGTERM s" "Signal.*Stop.*Print.*Pass to program.*Description\r\nSIGTERM.*Yes.*Yes.*Yes.*Terminated"
gdb_test "z SIGTERM r" "Signal.*Stop.*Print.*Pass to program.*Description\r\nSIGTERM.*No.*No.*Yes.*Terminated"
gdb_test "z SIGTERM i" "Signal.*Stop.*Print.*Pass to program.*Description\r\nSIGTERM.*No.*No.*No.*Terminated"
gdb_test "z SIGTERM r" "Signal.*Stop.*Print.*Pass to program.*Description\r\nSIGTERM.*No.*Yes.*No.*Terminated"
gdb_test "z SIGTERM Q" "Signal.*Stop.*Print.*Pass to program.*Description\r\nSIGTERM.*No.*No.*No.*Terminated"
gdb_test "lz" "Signal.*Stop.*Print.*Pass to program.*Description\r\n\r\nSIGHUP.*Yes.*"
}
# Start with a fresh gdb.
global GDBFLAGS
set saved_gdbflags $GDBFLAGS
set GDBFLAGS "$GDBFLAGS --xdb"
gdb_exit
gdb_start
xdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
send_gdb "set width 0\n"
gdb_expect -re "$gdb_prompt $"
test_search
test_viewing_loc
test_dir_list
test_list_sources
test_vlist
test_va
gdb_test "l" "No arguments.\r\nc = 0.*\r\nfirst = 0\r\nlast = 0"
#test_list_globals
test_list_registers
test_backtrace
# Start with a fresh gdb.
gdb_exit
gdb_start
xdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
send_gdb "set width 0\n"
gdb_expect -re "$gdb_prompt $"
test_go
gdb_exit
gdb_start
xdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
send_gdb "set width 0\n"
gdb_expect -re "$gdb_prompt $"
gdb_test "break main" ""
gdb_test "R" ""
gdb_test "S" "32\[ \t\]+int last = num-1;"
test_breakpoints
test_signals
gdb_test "sm" ""
gdb_test "info set" ".*pagination: State of pagination is off.*"
gdb_test "am" ""
gdb_test "info set" ".*pagination: State of pagination is on.*"
gdb_exit
set GDBFLAGS $saved_gdbflags
return 0