2004-11-03 Andrew Cagney <cagney@gnu.org>
* gdb.base/savedregs.exp, gdb.base/savedregs.c: New files.
This commit is contained in:
parent
4577593c76
commit
a1e167bbea
|
@ -1,3 +1,7 @@
|
|||
2004-11-03 Andrew Cagney <cagney@gnu.org>
|
||||
|
||||
* gdb.base/savedregs.exp, gdb.base/savedregs.c: New files.
|
||||
|
||||
2004-10-30 Mark Kettenis <kettenis@gnu.org>
|
||||
|
||||
* gdb.asm/asm-source.exp: Add mips*-*-netbsd* to the list of
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2004 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.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
static volatile int done;
|
||||
|
||||
extern int
|
||||
callee (int param)
|
||||
{
|
||||
return param * done + 1;
|
||||
}
|
||||
|
||||
extern int
|
||||
caller (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
|
||||
{
|
||||
return callee (a1 << a2 * a3 / a4 + a6 & a6 % a7 - a8) + done;
|
||||
}
|
||||
|
||||
static void
|
||||
catcher (int sig)
|
||||
{
|
||||
done = 1;
|
||||
} /* handler */
|
||||
|
||||
static void
|
||||
thrower (void)
|
||||
{
|
||||
*(char *)0 = 0;
|
||||
}
|
||||
|
||||
main ()
|
||||
{
|
||||
signal (SIGSEGV, catcher);
|
||||
thrower ();
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
# Copyright 2004 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.
|
||||
|
||||
# This test is to check that a frame's "info frame", especially the
|
||||
# saved registers list, doesn't change while that frame isn't current.
|
||||
|
||||
# It uses the program savedregs.c to construct a somewhat warped
|
||||
# backtrace (contains both signal and dummy frames) and then, at each
|
||||
# step checks that non-inner frames have consistent "info frame"
|
||||
# output. Note that a frame's "info frame" can only be captured after
|
||||
# it is non-current (made a call, interrupted, ...), this is because
|
||||
# instructions executed to perform the call may affect "info frame"
|
||||
# output.
|
||||
|
||||
if [target_info exists gdb,nosignals] {
|
||||
verbose "Skipping savedregs.exp because of nosignals."
|
||||
continue
|
||||
}
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
|
||||
set prms_id 0
|
||||
set bug_id 0
|
||||
|
||||
set testfile savedregs
|
||||
set srcfile ${testfile}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
||||
untested "Couldn't compile ${module}.c"
|
||||
return -1
|
||||
}
|
||||
|
||||
# get things started
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
gdb_load ${binfile}
|
||||
|
||||
# Advance to main
|
||||
if { ![runto_main] } {
|
||||
gdb_suppress_tests;
|
||||
}
|
||||
|
||||
proc process_saved_regs { current inner outer } {
|
||||
global gdb_prompt
|
||||
global expect_out
|
||||
global saved_regs
|
||||
|
||||
# Skip the CURRENT frame.
|
||||
|
||||
set level 1
|
||||
|
||||
# Run over the list of INNER frames capturing the "info frame"
|
||||
# output for each. Both dummy and sigtramp frames need to be
|
||||
# handled specially: they do not yet have correct function names;
|
||||
# and for dummy frames won't have saved registers. If there's a
|
||||
# problem, fail but capture the output anyway, hopefully later
|
||||
# "info frame" requests for that same frame will at least fail in
|
||||
# a consistent manner (stops propogated fails).
|
||||
|
||||
foreach func $inner {
|
||||
set saved_regs($func) "error"
|
||||
set test "Get $func info frame"
|
||||
# Both dummy and sigtramp frames have problems.
|
||||
switch $func {
|
||||
dummy {
|
||||
# Dummy frame's do not have saved registers, and do
|
||||
# not print <dummy>.
|
||||
set pat "Stack frame at .* in .*"
|
||||
}
|
||||
sigtramp {
|
||||
# Sigtramp frames don't yet print <signal trampoline>.
|
||||
set pat "Stack frame at .* in .* .* Saved registers:.*"
|
||||
}
|
||||
default {
|
||||
set pat "Stack frame at .* in $func .* Saved registers:.*"
|
||||
}
|
||||
}
|
||||
# If the "info frame" barf, capture the output anyway so that
|
||||
# it does not cascade further failures.
|
||||
gdb_test_multiple "info frame $level" "$test" {
|
||||
-re "($pat)$gdb_prompt " {
|
||||
set saved_regs($func) "$expect_out(1,string)"
|
||||
pass "$test"
|
||||
}
|
||||
-re "(Stack frame at .*)$gdb_prompt " {
|
||||
set saved_regs($func) "$expect_out(1,string)"
|
||||
fail "$test"
|
||||
}
|
||||
-re "(Cannot access .*)$gdb_prompt " {
|
||||
set saved_regs($func) "$expect_out(1,string)"
|
||||
fail "$test"
|
||||
}
|
||||
}
|
||||
incr level
|
||||
}
|
||||
|
||||
# Now iterate through the list of OUTER frames checking that the
|
||||
# "info frame" output from each still matches what was captured
|
||||
# during an early query. To avoid cascading failures, checking is
|
||||
# abandoned after the first failure. The assumption is that,
|
||||
# since frames outer to the botched frame rely on the botched
|
||||
# frame's info, those more outer frames are also botched. Besides
|
||||
# we've got the failure we're after.
|
||||
|
||||
set ok 1
|
||||
foreach func $outer {
|
||||
set test [concat "Check $func info frame; stack contains" \
|
||||
$current $inner $outer]
|
||||
if $ok {
|
||||
set ok 0
|
||||
set pat [string_to_regexp "$saved_regs($func)"]
|
||||
gdb_test_multiple "info frame $level" "$test" {
|
||||
-re "$pat$gdb_prompt " {
|
||||
pass "$test"
|
||||
set ok 1
|
||||
}
|
||||
}
|
||||
} {
|
||||
pass "$test (skipped)"
|
||||
}
|
||||
incr level
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Continue to the signal thrower, capture main's saved-reg info.
|
||||
gdb_test "advance thrower" "thrower .* at .*"
|
||||
process_saved_regs thrower { main } { }
|
||||
|
||||
# Continue to the signal catcher, check main's saved-reg info, capture
|
||||
# catcher's saved-reg info.
|
||||
gdb_test "handle SIGSEGV pass print nostop"
|
||||
gdb_test "advance catcher" "catcher .* at .*"
|
||||
process_saved_regs catcher { sigtramp thrower } { main }
|
||||
|
||||
# Breakpoint at and call the caller function, saved-regs of main and
|
||||
# catcher, capture caller's registers.
|
||||
gdb_test "break caller"
|
||||
gdb_test "call caller (1,2,3,4,5,6,7,8)"
|
||||
process_saved_regs caller { dummy catcher } { sigtramp thrower main }
|
||||
|
||||
# Run to callee, again check everything.
|
||||
gdb_test "advance callee" "callee .* at .*"
|
||||
process_saved_regs callee { caller } { dummy catcher sigtramp thrower main }
|
Loading…
Reference in New Issue