new files -- part of HP merge.
This commit is contained in:
parent
65fedafeb8
commit
d55ea55c19
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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" }
|
||||
}
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
@ -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" }
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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)" }
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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); */
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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" }
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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" );
|
||||
|
||||
}
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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" }
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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)" }
|
||||
#}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define NTHREADS 4
|
||||
#define NUM_ELEMS 12
|
||||
|
||||
#define ELEMS_PER_THREAD (NUM_ELEMS/NTHREADS)
|
|
@ -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" );
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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"}
|
||||
}
|
||||
|
||||
#***************
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue