* Re: [rfa] New test sigbpt.{c,exp}
@ 2004-06-30 3:53 Michael Elizabeth Chastain
2004-06-30 15:25 ` Andrew Cagney
0 siblings, 1 reply; 16+ messages in thread
From: Michael Elizabeth Chastain @ 2004-06-30 3:53 UTC (permalink / raw)
To: ac131313, gdb-patches
Mostly okay, but there's too many duplicated test names.
% cat gdb.sum | sort | uniq -c | sort -rn
8 PASS: gdb.base/sigbpt.exp: pass SIGSEGV for no breakpoints
7 PASS: gdb.base/sigbpt.exp: rerun to main
4 PASS: gdb.base/sigbpt.exp: continue to keeper for no breakpoints
3 PASS: gdb.base/sigbpt.exp: stepi fault for no breakpoints
3 PASS: gdb.base/sigbpt.exp: continue to breakpoint at fault for no breakpoints
2 PASS: gdb.base/sigbpt.exp: pass SIGSEGV for bp before segv
2 PASS: gdb.base/sigbpt.exp: pass SIGSEGV for bp before and at segv
2 PASS: gdb.base/sigbpt.exp: pass SIGSEGV for bp at segv
Can you make more of the test names more unique?
I'm not worried about stuff like "rerun to main" where if the test
fails then something is really wrong with gdb anyways. I'm more
concerned with multiple identical blocks like this:
gdb_test "handle SIGSEGV nostop print pass" "" "pass SIGSEGV for $name"
gdb_test "continue" "keeper.*" "continue to keeper for $name"
gdb_test "handle SIGSEGV stop print nopass" "" "pass SIGSEGV for $name"
If one of these fails, and all we have is the name of the test
(which is normal), then we don't know which test failed.
Also I'm getting four FAIL results (native i686-pc-linux-gnu,
red hat 8.0, gcc 3.3.3, binutils 2.15, glibc 2.2.93-5-rh,
kernel 2.4.8-14-rh).
FAIL: gdb.base/sigbpt.exp: stepi out of handler for no breakpoints (executed fault insn)
FAIL: gdb.base/sigbpt.exp: stepi out of handler for bp before segv (executed fault insn)
FAIL: gdb.base/sigbpt.exp: stepi out of handler for bp at segv
FAIL: gdb.base/sigbpt.exp: stepi out of handler for bp before and at segv
Is that a fault of the system under test, or a fault of the test script?
Your message implies the former (because it passes with a hacked kernel),
but I just want to check.
Last, a typo:
set test "Verify that SIGSEGV occures at the last STEPI insn"
Michael C
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [rfa] New test sigbpt.{c,exp}
2004-06-30 3:53 [rfa] New test sigbpt.{c,exp} Michael Elizabeth Chastain
@ 2004-06-30 15:25 ` Andrew Cagney
2004-06-30 15:30 ` Daniel Jacobowitz
0 siblings, 1 reply; 16+ messages in thread
From: Andrew Cagney @ 2004-06-30 15:25 UTC (permalink / raw)
To: Michael Elizabeth Chastain; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2130 bytes --]
> Mostly okay, but there's too many duplicated test names.
>
> % cat gdb.sum | sort | uniq -c | sort -rn
> 8 PASS: gdb.base/sigbpt.exp: pass SIGSEGV for no breakpoints
> 7 PASS: gdb.base/sigbpt.exp: rerun to main
> 4 PASS: gdb.base/sigbpt.exp: continue to keeper for no breakpoints
> 3 PASS: gdb.base/sigbpt.exp: stepi fault for no breakpoints
> 3 PASS: gdb.base/sigbpt.exp: continue to breakpoint at fault for no breakpoints
> 2 PASS: gdb.base/sigbpt.exp: pass SIGSEGV for bp before segv
> 2 PASS: gdb.base/sigbpt.exp: pass SIGSEGV for bp before and at segv
> 2 PASS: gdb.base/sigbpt.exp: pass SIGSEGV for bp at segv
>
> Can you make more of the test names more unique?
Oops, I thought I'd covered that. Try the attached.
> Last, a typo:
>
> set test "Verify that SIGSEGV occures at the last STEPI insn"
Fixed.
> Also I'm getting four FAIL results (native i686-pc-linux-gnu,
> red hat 8.0, gcc 3.3.3, binutils 2.15, glibc 2.2.93-5-rh,
> kernel 2.4.8-14-rh).
>
> FAIL: gdb.base/sigbpt.exp: stepi out of handler for no breakpoints (executed fault insn)
> FAIL: gdb.base/sigbpt.exp: stepi out of handler for bp before segv (executed fault insn)
> FAIL: gdb.base/sigbpt.exp: stepi out of handler for bp at segv
> FAIL: gdb.base/sigbpt.exp: stepi out of handler for bp before and at segv
>
> Is that a fault of the system under test, or a fault of the test script?
> Your message implies the former (because it passes with a hacked kernel),
> but I just want to check.
"yes", so far I've identified the following:
- h/w single-step #1 - kernel
The kernel is issuing two-for-one instructions when single stepping a
system call.
- h/w single-step #2 - kernel
The kernel is continuing, instead of single-stepping, the sigreturn
system call.
- s/w single-step #1 - gdb
GDB's OSABI software single-step code doesn't know how to single-step
sigreturn.
We, GDB, can work around the kernel bugs by using software single step.
But that means fixing software single-step.
Are there [get_kernel_info] and [get_software_singlestep] testsuite calls?
Andrew
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 10835 bytes --]
2004-06-18 Andrew Cagney <cagney@gnu.org>
* gdb.base/sigbpt.exp, gdb.base/sigbpt.c: New test.
Index: gdb.base/sigbpt.c
===================================================================
RCS file: gdb.base/sigbpt.c
diff -N gdb.base/sigbpt.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb.base/sigbpt.c 30 Jun 2004 14:58:02 -0000
@@ -0,0 +1,53 @@
+/* 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 <signal.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern void
+keeper (int sig)
+{
+}
+
+volatile long v1 = 0;
+volatile long v2 = 0;
+volatile long v3 = 0;
+
+extern long
+bowler (void)
+{
+ /* Try to read address zero. Do it in a slightly convoluted way so
+ that more than one instruction is used. */
+ return *(char *) (v1 + v2 + v3);
+}
+
+int
+main ()
+{
+ static volatile int i;
+
+ struct sigaction act;
+ memset (&act, 0, sizeof act);
+ act.sa_handler = keeper;
+ sigaction (SIGSEGV, &act, NULL);
+
+ bowler ();
+ return 0;
+}
Index: gdb.base/sigbpt.exp
===================================================================
RCS file: gdb.base/sigbpt.exp
diff -N gdb.base/sigbpt.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb.base/sigbpt.exp 30 Jun 2004 14:58:02 -0000
@@ -0,0 +1,253 @@
+# 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.
+
+# Check that GDB can and only executes single instructions when
+# stepping through a sequence of breakpoints interleaved by signal.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "sigbpt"
+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."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+# If we can examine what's at memory address 0, it is possible that we
+# could also execute it. This could probably make us run away,
+# executing random code, which could have all sorts of ill effects,
+# especially on targets without an MMU. Don't run the tests in that
+# case.
+
+send_gdb "x 0\n"
+gdb_expect {
+ -re "0x0:.*Cannot access memory at address 0x0.*$gdb_prompt $" { }
+ -re "0x0:.*Error accessing memory address 0x0.*$gdb_prompt $" { }
+ -re ".*$gdb_prompt $" {
+ untested "Memory at address 0 is possibly executable"
+ return
+ }
+}
+
+gdb_test "break keeper"
+
+# Run to bowler, and then single step until there's a SIGSEGV. Record
+# the address of each single-step instruction (up to and including the
+# instruction that causes the SIGSEGV) in bowler_addrs, and the address
+# of the actual SIGSEGV in segv_addr.
+
+set bowler_addrs bowler
+gdb_test {display/i $pc}
+gdb_test "advance *bowler" "bowler.*" "advance to the bowler"
+set test "stepping to SIGSEGV"
+gdb_test_multiple "stepi" "$test" {
+ -re "Program received signal SIGSEGV.*pc *(0x\[0-9a-f\]*).*$gdb_prompt $" {
+ set segv_addr $expect_out(1,string)
+ pass "$test"
+ }
+ -re " .*pc *(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" {
+ set bowler_addrs [concat $expect_out(1,string) $bowler_addrs]
+ send_gdb "stepi\n"
+ exp_continue
+ }
+}
+
+# Now record the address of the instruction following the faulting
+# instruction in bowler_addrs.
+
+set test "get insn after fault"
+gdb_test_multiple {x/2i $pc} "$test" {
+ -re "(0x\[0-9a-f\]*).*bowler.*(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" {
+ set bowler_addrs [concat $expect_out(2,string) $bowler_addrs]
+ pass "$test"
+ }
+}
+
+# Procedures for returning the address of the instruction before, at
+# and after, the faulting instruction.
+
+proc before_segv { } {
+ global bowler_addrs
+ return [lindex $bowler_addrs 2]
+}
+
+proc at_segv { } {
+ global bowler_addrs
+ return [lindex $bowler_addrs 1]
+}
+
+proc after_segv { } {
+ global bowler_addrs
+ return [lindex $bowler_addrs 0]
+}
+
+# Check that the address table and SIGSEGV correspond.
+
+set test "Verify that SIGSEGV occurs at the last STEPI insn"
+if {[string compare $segv_addr [at_segv]] == 0} {
+ pass "$test"
+} else {
+ fail "$test ($segv_addr [at_segv])"
+}
+
+# Check that the inferior is correctly single stepped all the way back
+# to a faulting instruction.
+
+proc stepi_out { name args } {
+ global gdb_prompt
+
+ # Set SIGSEGV to pass+nostop and then run the inferior all the way
+ # through to the signal handler. With the handler is reached,
+ # disable SIGSEGV, ensuring that further signals stop the
+ # inferior. Stops a SIGSEGV infinite loop when a broke system
+ # keeps re-executing the faulting instruction.
+ rerun_to_main
+ gdb_test "handle SIGSEGV nostop print pass" "" "pass SIGSEGV; $name"
+ gdb_test "continue" "keeper.*" "continue to keeper; $name"
+ gdb_test "handle SIGSEGV stop print nopass" "" "nopass SIGSEGV; $name"
+
+ # Insert all the breakpoints. To avoid the need to step over
+ # these instructions, this is delayed until after the keeper has
+ # been reached.
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "break [lindex $args $i]" "Breakpoint.*" \
+ "set breakpoint $i of [llength $args]; $name"
+ }
+
+ # Single step our way out of the keeper, through the signal
+ # trampoline, and back to the instruction that faulted.
+ set test "stepi out of handler; $name"
+ gdb_test_multiple "stepi" "$test" {
+ -re "keeper.*$gdb_prompt $" {
+ send_gdb "stepi\n"
+ exp_continue
+ }
+ -re "signal handler.*$gdb_prompt $" {
+ send_gdb "stepi\n"
+ exp_continue
+ }
+ -re "Program received signal SIGSEGV.*$gdb_prompt $" {
+ fail "$test (executed fault insn)"
+ }
+ -re "Breakpoint.*pc *[at_segv] .*bowler.*$gdb_prompt $" {
+ pass "$test (at breakpoint)"
+ }
+ -re "Breakpoint.*pc *[after_segv] .*bowler.*$gdb_prompt $" {
+ fail "$test (executed breakpoint)"
+ }
+ -re "pc *[at_segv] .*bowler.*$gdb_prompt $" {
+ pass "$test"
+ }
+ -re "pc *[after_segv] .*bowler.*$gdb_prompt $" {
+ fail "$test (skipped fault insn)"
+ }
+ }
+
+ # Clear any breakpoints
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "clear [lindex $args $i]" "Deleted .*" \
+ "clear breakpoint $i of [llength $args]; $name"
+ }
+}
+
+# Let a signal handler exit, returning to a breakpoint instruction
+# inserted at the original fault instruction. Check that the
+# breakpoint is hit, and that single stepping off that breakpoint
+# executes the underlying fault instruction causing a SIGSEGV.
+
+proc cont_out { name args } {
+ global gdb_prompt
+
+ # Set SIGSEGV to pass+nostop and then run the inferior all the way
+ # through to the signal handler. With the handler is reached,
+ # disable SIGSEGV, ensuring that further signals stop the
+ # inferior. Stops a SIGSEGV infinite loop when a broke system
+ # keeps re-executing the faulting instruction.
+ rerun_to_main
+ gdb_test "handle SIGSEGV nostop print pass" "" "pass SIGSEGV; $name"
+ gdb_test "continue" "keeper.*" "continue to keeper; $name"
+ gdb_test "handle SIGSEGV stop print nopass" "" "nopass SIGSEGV; $name"
+
+ # Insert all the breakpoints. To avoid the need to step over
+ # these instructions, this is delayed until after the keeper has
+ # been reached. Always set a breakpoint at the signal trampoline
+ # instruction.
+ set args [concat $args "*[at_segv]"]
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "break [lindex $args $i]" "Breakpoint.*" \
+ "set breakpoint $i of [llength $args]; $name"
+ }
+
+ # Let the handler return, it should "appear to hit" the breakpoint
+ # inserted at the faulting instruction. Note that the breakpoint
+ # instruction wasn't executed, rather the inferior was SIGTRAPed
+ # with the PC at the breakpoint.
+ gdb_test "continue" "Breakpoint.*pc *[at_segv] .*" \
+ "continue to breakpoint at fault; $name"
+
+ # Now single step the faulted instrction at that breakpoint.
+ gdb_test "stepi" \
+ "Program received signal SIGSEGV.*pc *[at_segv] .*" \
+ "stepi fault; $name"
+
+ # Clear any breakpoints
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "clear [lindex $args $i]" "Deleted .*" \
+ "clear breakpoint $i of [llength $args]; $name"
+ }
+
+}
+
+
+
+# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering
+# breakpoints around the faulting address. In all cases the inferior
+# should single-step out of the signal trampoline halting (but not
+# executing) the fault instruction.
+
+stepi_out "stepi"
+stepi_out "stepi bp before segv" "*[before_segv]"
+stepi_out "stepi bp at segv" "*[at_segv]"
+stepi_out "stepi bp before and at segv" "*[at_segv]" "*[before_segv]"
+
+
+# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering
+# breakpoints around the faulting address. In all cases the inferior
+# should exit the signal trampoline halting at the breakpoint that
+# replaced the fault instruction.
+cont_out "cont"
+cont_out "cont bp after segv" "*[before_segv]"
+cont_out "cont bp before and after segv" "*[before_segv]" "*[after_segv]"
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [rfa] New test sigbpt.{c,exp}
2004-06-30 15:25 ` Andrew Cagney
@ 2004-06-30 15:30 ` Daniel Jacobowitz
2004-07-02 13:24 ` Andrew Cagney
0 siblings, 1 reply; 16+ messages in thread
From: Daniel Jacobowitz @ 2004-06-30 15:30 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Michael Elizabeth Chastain, gdb-patches
On Wed, Jun 30, 2004 at 11:25:06AM -0400, Andrew Cagney wrote:
> Are there [get_kernel_info] and [get_software_singlestep] testsuite calls?
I don't even know a reliable way to find out if we're using software
singlestep from the GDB prompt, besides trying to grok the multiarch
dump (and I'm not sure that would work). Perhaps we should add one.
Is [get_kernel_info] a good idea? Version numbers don't tell you much;
everyone seems to port fixes every which way.
--
Daniel Jacobowitz
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [rfa] New test sigbpt.{c,exp}
2004-06-30 15:30 ` Daniel Jacobowitz
@ 2004-07-02 13:24 ` Andrew Cagney
0 siblings, 0 replies; 16+ messages in thread
From: Andrew Cagney @ 2004-07-02 13:24 UTC (permalink / raw)
To: Daniel Jacobowitz, Michael Elizabeth Chastain; +Cc: gdb-patches
> On Wed, Jun 30, 2004 at 11:25:06AM -0400, Andrew Cagney wrote:
>
>>> Are there [get_kernel_info] and [get_software_singlestep] testsuite calls?
>
>
> I don't even know a reliable way to find out if we're using software
> singlestep from the GDB prompt, besides trying to grok the multiarch
> dump (and I'm not sure that would work). Perhaps we should add one.
Rooting round in the architecture vector would work.
(I have a strong dislike for those hardwired <config>.exp predicates.
The testsuite should separatly: query GDB for a mechanisms status; cross
check with <config>.exp that the status matches what is expected.)
> Is [get_kernel_info] a good idea? Version numbers don't tell you much;
> everyone seems to port fixes every which way.
Or [kernel_..._p]. We have to assume that kernel vendors have vaguely
sane branding.
I'll kfail this since, in theory at least, GDB can work around the
breakage by using software single-step.
Andrew
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [rfa] New test sigbpt.{c,exp}
@ 2004-07-07 18:39 Michael Elizabeth Chastain
0 siblings, 0 replies; 16+ messages in thread
From: Michael Elizabeth Chastain @ 2004-07-07 18:39 UTC (permalink / raw)
To: cagney; +Cc: ac131313, drow, gdb-patches, mec.gnu
OK.
Michael C
===
2004-07-07 Andrew Cagney <cagney@gnu.org>
* gdb.base/sigbpt.exp (stepi_out): Check for a single step
corrupting the PC.
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [rfa] New test sigbpt.{c,exp}
@ 2004-07-06 18:59 Michael Elizabeth Chastain
2004-07-06 19:29 ` Andrew Cagney
0 siblings, 1 reply; 16+ messages in thread
From: Michael Elizabeth Chastain @ 2004-07-06 18:59 UTC (permalink / raw)
To: drow, mec.gnu; +Cc: ac131313, gdb-patches
mec> How about:
mec>
mec> (1) before running the program, 'disassemble bowler'
mec> (2) at the breakpoint, 'x/i $pc'
mec> check that the output of (2) matches one of the lines in (1)
drow> That's not a good generic fix; it's just a peculiarity of x86 that we
drow> get this particular problem. If that hadn't been a multibyte opcode
drow> something different would have happened.
It would be a useful test because it would never give a false positive.
If the instruction in (2) is not present in (1) then that is
always a problem. I agree that it would be full of false
negatives; like, any RISC arch with fixed-width instructions
would PASS.
drow> I think just executing another instruction here after the faulting one
drow> is enough to match the kfail, whether it's the size of a breakpoint or
drow> not.
That's okay with me too.
Michael C
not-enough-sleep-today
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [rfa] New test sigbpt.{c,exp}
2004-07-06 18:59 Michael Elizabeth Chastain
@ 2004-07-06 19:29 ` Andrew Cagney
2004-07-07 17:31 ` Andrew Cagney
0 siblings, 1 reply; 16+ messages in thread
From: Andrew Cagney @ 2004-07-06 19:29 UTC (permalink / raw)
To: Michael Elizabeth Chastain; +Cc: drow, ac131313, gdb-patches
> mec> How about:
> mec>
> mec> (1) before running the program, 'disassemble bowler'
> mec> (2) at the breakpoint, 'x/i $pc'
> mec> check that the output of (2) matches one of the lines in (1)
FYI, that's effectively what I did. It checks the $pc address against a
table of valid instruction addresses. It doesn't match it fails, via
gdb_test_multiple internals. All thats missing is a pattern to match
any other pc address in bowler.
Trying to single-step after corrupting the $pc would be meaningless.
Andrew
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [rfa] New test sigbpt.{c,exp}
2004-07-06 19:29 ` Andrew Cagney
@ 2004-07-07 17:31 ` Andrew Cagney
2004-07-08 14:28 ` Daniel Jacobowitz
0 siblings, 1 reply; 16+ messages in thread
From: Andrew Cagney @ 2004-07-07 17:31 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Michael Elizabeth Chastain, drow, ac131313, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 574 bytes --]
>> mec> How about:
>> mec> mec> (1) before running the program, 'disassemble bowler'
>> mec> (2) at the breakpoint, 'x/i $pc'
>> mec> check that the output of (2) matches one of the lines in (1)
>
>
> FYI, that's effectively what I did. It checks the $pc address against a table of valid instruction addresses. It doesn't match it fails, via gdb_test_multiple internals. All thats missing is a pattern to match any other pc address in bowler.
I've added the attached.
Andrew
> Trying to single-step after corrupting the $pc would be meaningless.
>
> Andrew
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 728 bytes --]
2004-07-07 Andrew Cagney <cagney@gnu.org>
* gdb.base/sigbpt.exp (stepi_out): Check for a single step
corrupting the PC.
Index: gdb.base/sigbpt.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/sigbpt.exp,v
retrieving revision 1.1
diff -p -u -r1.1 sigbpt.exp
--- gdb.base/sigbpt.exp 6 Jul 2004 15:08:54 -0000 1.1
+++ gdb.base/sigbpt.exp 7 Jul 2004 17:28:50 -0000
@@ -184,6 +184,9 @@ proc stepi_out { name args } {
-re "pc *[after_segv] .*bowler.*$gdb_prompt $" {
kfail gdb/1702 "$test (skipped fault insn)"
}
+ -re "pc *0x\[a-z0-9\]* .*bowler.*$gdb_prompt $" {
+ kfail gdb/1702 "$test (corrupt pc)"
+ }
}
# Clear any breakpoints
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [rfa] New test sigbpt.{c,exp}
@ 2004-07-06 18:12 Michael Elizabeth Chastain
2004-07-06 18:30 ` Daniel Jacobowitz
0 siblings, 1 reply; 16+ messages in thread
From: Michael Elizabeth Chastain @ 2004-07-06 18:12 UTC (permalink / raw)
To: ac131313, drow, gdb-patches, mec.gnu
drow> 0x080483f2 in bowler () at /opt/src/gdb/src/gdb/testsuite/gdb.base/sigbpt.c:38
drow> 38 return *(char *) (v1 + v2 + v3);
drow> 1: x/i $pc 0x80483f2 <bowler+25>: mov $0x55c35d00,%esi
drow> (gdb) FAIL: gdb.base/sigbpt.exp: stepi out of handler; stepi bp at segv
drow>
drow> That's not the instruction that should be there; there's a multi-byte
drow> instruction at <bowler+24>.
How about:
(1) before running the program, 'disassemble bowler'
(2) at the breakpoint, 'x/i $pc'
check that the output of (2) matches one of the lines in (1)
Michael C
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [rfa] New test sigbpt.{c,exp}
2004-07-06 18:12 Michael Elizabeth Chastain
@ 2004-07-06 18:30 ` Daniel Jacobowitz
0 siblings, 0 replies; 16+ messages in thread
From: Daniel Jacobowitz @ 2004-07-06 18:30 UTC (permalink / raw)
To: Michael Elizabeth Chastain; +Cc: ac131313, gdb-patches
On Tue, Jul 06, 2004 at 02:12:21PM -0400, Michael Chastain wrote:
> drow> 0x080483f2 in bowler () at /opt/src/gdb/src/gdb/testsuite/gdb.base/sigbpt.c:38
> drow> 38 return *(char *) (v1 + v2 + v3);
> drow> 1: x/i $pc 0x80483f2 <bowler+25>: mov $0x55c35d00,%esi
> drow> (gdb) FAIL: gdb.base/sigbpt.exp: stepi out of handler; stepi bp at segv
> drow>
> drow> That's not the instruction that should be there; there's a multi-byte
> drow> instruction at <bowler+24>.
>
> How about:
>
> (1) before running the program, 'disassemble bowler'
> (2) at the breakpoint, 'x/i $pc'
> check that the output of (2) matches one of the lines in (1)
That's not a good generic fix; it's just a peculiarity of x86 that we
get this particular problem. If that hadn't been a multibyte opcode
something different would have happened. I think just executing
another instruction here after the faulting one is enough to match the
kfail, whether it's the size of a breakpoint or not.
--
Daniel Jacobowitz
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [rfa] New test sigbpt.{c,exp}
@ 2004-06-30 18:53 Michael Elizabeth Chastain
2004-07-06 15:10 ` Andrew Cagney
0 siblings, 1 reply; 16+ messages in thread
From: Michael Elizabeth Chastain @ 2004-06-30 18:53 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
mec> Can you make more of the test names more unique?
ac> Oops, I thought I'd covered that. Try the attached.
It works for me.
All the test names are unique except for "rerun to main".
Stil the same four FAILs but that's okay because they really are FAILs.
I approve this patch.
ac> Are there [get_kernel_info] and [get_software_singlestep] testsuite calls?
I don't know of any.
I'm a bit leery of "get_kernel_info", because we should be testing
for features rather than version numbers (the whole autoconf philosophy).
Although get_compiler_info has worked reasonably well for the job
that it does.
I'm more inclined to dump a bunch of KFAIL's into the gdb_test_multiple
arms for the bad results, along with comments about which kernel versions
have been observed to have which behavior. Then in 3-5 years it's not
hard to sort out the obsolete crap.
If KFAIL's are too hard then just the comments for starters.
Michael C
===
2004-06-18 Andrew Cagney <cagney@gnu.org>
* gdb.base/sigbpt.exp, gdb.base/sigbpt.c: New test.
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [rfa] New test sigbpt.{c,exp}
2004-06-30 18:53 Michael Elizabeth Chastain
@ 2004-07-06 15:10 ` Andrew Cagney
2004-07-06 15:35 ` Daniel Jacobowitz
0 siblings, 1 reply; 16+ messages in thread
From: Andrew Cagney @ 2004-07-06 15:10 UTC (permalink / raw)
To: Michael Elizabeth Chastain; +Cc: ac131313, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1047 bytes --]
> mec> Can you make more of the test names more unique?
> ac> Oops, I thought I'd covered that. Try the attached.
>
> It works for me.
> All the test names are unique except for "rerun to main".
> Stil the same four FAILs but that's okay because they really are FAILs.
>
> I approve this patch.
>
> ac> Are there [get_kernel_info] and [get_software_singlestep] testsuite calls?
>
> I don't know of any.
>
> I'm a bit leery of "get_kernel_info", because we should be testing
> for features rather than version numbers (the whole autoconf philosophy).
> Although get_compiler_info has worked reasonably well for the job
> that it does.
>
> I'm more inclined to dump a bunch of KFAIL's into the gdb_test_multiple
> arms for the bad results, along with comments about which kernel versions
> have been observed to have which behavior. Then in 3-5 years it's not
> hard to sort out the obsolete crap.
>
> If KFAIL's are too hard then just the comments for starters.
I both kfailed and and commented, committing the attached.
thanks,
Andrew
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 11406 bytes --]
2004-07-06 Andrew Cagney <cagney@gnu.org>
* gdb.base/sigbpt.exp, gdb.base/sigbpt.c: New test.
Index: gdb.base/sigbpt.c
===================================================================
RCS file: gdb.base/sigbpt.c
diff -N gdb.base/sigbpt.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb.base/sigbpt.c 6 Jul 2004 15:08:19 -0000
@@ -0,0 +1,53 @@
+/* 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 <signal.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern void
+keeper (int sig)
+{
+}
+
+volatile long v1 = 0;
+volatile long v2 = 0;
+volatile long v3 = 0;
+
+extern long
+bowler (void)
+{
+ /* Try to read address zero. Do it in a slightly convoluted way so
+ that more than one instruction is used. */
+ return *(char *) (v1 + v2 + v3);
+}
+
+int
+main ()
+{
+ static volatile int i;
+
+ struct sigaction act;
+ memset (&act, 0, sizeof act);
+ act.sa_handler = keeper;
+ sigaction (SIGSEGV, &act, NULL);
+
+ bowler ();
+ return 0;
+}
Index: gdb.base/sigbpt.exp
===================================================================
RCS file: gdb.base/sigbpt.exp
diff -N gdb.base/sigbpt.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb.base/sigbpt.exp 6 Jul 2004 15:08:19 -0000
@@ -0,0 +1,263 @@
+# 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.
+
+# Check that GDB can and only executes single instructions when
+# stepping through a sequence of breakpoints interleaved by a signal
+# handler.
+
+# This test is known to tickle the following problems: kernel letting
+# the inferior execute both the system call, and the instruction
+# following, when single-stepping a system call; kernel failing to
+# propogate the single-step state when single-stepping the sigreturn
+# system call, instead resuming the inferior at full speed; GDB
+# doesn't know how to software single-step across a sigreturn
+# instruction. Since the kernel problems can be "fixed" using
+# software single-step this is KFAILed rather than XFAILed.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "sigbpt"
+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."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+# If we can examine what's at memory address 0, it is possible that we
+# could also execute it. This could probably make us run away,
+# executing random code, which could have all sorts of ill effects,
+# especially on targets without an MMU. Don't run the tests in that
+# case.
+
+send_gdb "x 0\n"
+gdb_expect {
+ -re "0x0:.*Cannot access memory at address 0x0.*$gdb_prompt $" { }
+ -re "0x0:.*Error accessing memory address 0x0.*$gdb_prompt $" { }
+ -re ".*$gdb_prompt $" {
+ untested "Memory at address 0 is possibly executable"
+ return
+ }
+}
+
+gdb_test "break keeper"
+
+# Run to bowler, and then single step until there's a SIGSEGV. Record
+# the address of each single-step instruction (up to and including the
+# instruction that causes the SIGSEGV) in bowler_addrs, and the address
+# of the actual SIGSEGV in segv_addr.
+
+set bowler_addrs bowler
+gdb_test {display/i $pc}
+gdb_test "advance *bowler" "bowler.*" "advance to the bowler"
+set test "stepping to SIGSEGV"
+gdb_test_multiple "stepi" "$test" {
+ -re "Program received signal SIGSEGV.*pc *(0x\[0-9a-f\]*).*$gdb_prompt $" {
+ set segv_addr $expect_out(1,string)
+ pass "$test"
+ }
+ -re " .*pc *(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" {
+ set bowler_addrs [concat $expect_out(1,string) $bowler_addrs]
+ send_gdb "stepi\n"
+ exp_continue
+ }
+}
+
+# Now record the address of the instruction following the faulting
+# instruction in bowler_addrs.
+
+set test "get insn after fault"
+gdb_test_multiple {x/2i $pc} "$test" {
+ -re "(0x\[0-9a-f\]*).*bowler.*(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" {
+ set bowler_addrs [concat $expect_out(2,string) $bowler_addrs]
+ pass "$test"
+ }
+}
+
+# Procedures for returning the address of the instruction before, at
+# and after, the faulting instruction.
+
+proc before_segv { } {
+ global bowler_addrs
+ return [lindex $bowler_addrs 2]
+}
+
+proc at_segv { } {
+ global bowler_addrs
+ return [lindex $bowler_addrs 1]
+}
+
+proc after_segv { } {
+ global bowler_addrs
+ return [lindex $bowler_addrs 0]
+}
+
+# Check that the address table and SIGSEGV correspond.
+
+set test "Verify that SIGSEGV occurs at the last STEPI insn"
+if {[string compare $segv_addr [at_segv]] == 0} {
+ pass "$test"
+} else {
+ fail "$test ($segv_addr [at_segv])"
+}
+
+# Check that the inferior is correctly single stepped all the way back
+# to a faulting instruction.
+
+proc stepi_out { name args } {
+ global gdb_prompt
+
+ # Set SIGSEGV to pass+nostop and then run the inferior all the way
+ # through to the signal handler. With the handler is reached,
+ # disable SIGSEGV, ensuring that further signals stop the
+ # inferior. Stops a SIGSEGV infinite loop when a broke system
+ # keeps re-executing the faulting instruction.
+ rerun_to_main
+ gdb_test "handle SIGSEGV nostop print pass" "" "pass SIGSEGV; $name"
+ gdb_test "continue" "keeper.*" "continue to keeper; $name"
+ gdb_test "handle SIGSEGV stop print nopass" "" "nopass SIGSEGV; $name"
+
+ # Insert all the breakpoints. To avoid the need to step over
+ # these instructions, this is delayed until after the keeper has
+ # been reached.
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "break [lindex $args $i]" "Breakpoint.*" \
+ "set breakpoint $i of [llength $args]; $name"
+ }
+
+ # Single step our way out of the keeper, through the signal
+ # trampoline, and back to the instruction that faulted.
+ set test "stepi out of handler; $name"
+ gdb_test_multiple "stepi" "$test" {
+ -re "keeper.*$gdb_prompt $" {
+ send_gdb "stepi\n"
+ exp_continue
+ }
+ -re "signal handler.*$gdb_prompt $" {
+ send_gdb "stepi\n"
+ exp_continue
+ }
+ -re "Program received signal SIGSEGV.*$gdb_prompt $" {
+ kfail gdb/1702 "$test (executed fault insn)"
+ }
+ -re "Breakpoint.*pc *[at_segv] .*bowler.*$gdb_prompt $" {
+ pass "$test (at breakpoint)"
+ }
+ -re "Breakpoint.*pc *[after_segv] .*bowler.*$gdb_prompt $" {
+ kfail gdb/1702 "$test (executed breakpoint)"
+ }
+ -re "pc *[at_segv] .*bowler.*$gdb_prompt $" {
+ pass "$test"
+ }
+ -re "pc *[after_segv] .*bowler.*$gdb_prompt $" {
+ kfail gdb/1702 "$test (skipped fault insn)"
+ }
+ }
+
+ # Clear any breakpoints
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "clear [lindex $args $i]" "Deleted .*" \
+ "clear breakpoint $i of [llength $args]; $name"
+ }
+}
+
+# Let a signal handler exit, returning to a breakpoint instruction
+# inserted at the original fault instruction. Check that the
+# breakpoint is hit, and that single stepping off that breakpoint
+# executes the underlying fault instruction causing a SIGSEGV.
+
+proc cont_out { name args } {
+ global gdb_prompt
+
+ # Set SIGSEGV to pass+nostop and then run the inferior all the way
+ # through to the signal handler. With the handler is reached,
+ # disable SIGSEGV, ensuring that further signals stop the
+ # inferior. Stops a SIGSEGV infinite loop when a broke system
+ # keeps re-executing the faulting instruction.
+ rerun_to_main
+ gdb_test "handle SIGSEGV nostop print pass" "" "pass SIGSEGV; $name"
+ gdb_test "continue" "keeper.*" "continue to keeper; $name"
+ gdb_test "handle SIGSEGV stop print nopass" "" "nopass SIGSEGV; $name"
+
+ # Insert all the breakpoints. To avoid the need to step over
+ # these instructions, this is delayed until after the keeper has
+ # been reached. Always set a breakpoint at the signal trampoline
+ # instruction.
+ set args [concat $args "*[at_segv]"]
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "break [lindex $args $i]" "Breakpoint.*" \
+ "set breakpoint $i of [llength $args]; $name"
+ }
+
+ # Let the handler return, it should "appear to hit" the breakpoint
+ # inserted at the faulting instruction. Note that the breakpoint
+ # instruction wasn't executed, rather the inferior was SIGTRAPed
+ # with the PC at the breakpoint.
+ gdb_test "continue" "Breakpoint.*pc *[at_segv] .*" \
+ "continue to breakpoint at fault; $name"
+
+ # Now single step the faulted instrction at that breakpoint.
+ gdb_test "stepi" \
+ "Program received signal SIGSEGV.*pc *[at_segv] .*" \
+ "stepi fault; $name"
+
+ # Clear any breakpoints
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "clear [lindex $args $i]" "Deleted .*" \
+ "clear breakpoint $i of [llength $args]; $name"
+ }
+
+}
+
+
+
+# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering
+# breakpoints around the faulting address. In all cases the inferior
+# should single-step out of the signal trampoline halting (but not
+# executing) the fault instruction.
+
+stepi_out "stepi"
+stepi_out "stepi bp before segv" "*[before_segv]"
+stepi_out "stepi bp at segv" "*[at_segv]"
+stepi_out "stepi bp before and at segv" "*[at_segv]" "*[before_segv]"
+
+
+# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering
+# breakpoints around the faulting address. In all cases the inferior
+# should exit the signal trampoline halting at the breakpoint that
+# replaced the fault instruction.
+cont_out "cont"
+cont_out "cont bp after segv" "*[before_segv]"
+cont_out "cont bp before and after segv" "*[before_segv]" "*[after_segv]"
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [rfa] New test sigbpt.{c,exp}
2004-07-06 15:10 ` Andrew Cagney
@ 2004-07-06 15:35 ` Daniel Jacobowitz
2004-07-06 16:00 ` Andrew Cagney
0 siblings, 1 reply; 16+ messages in thread
From: Daniel Jacobowitz @ 2004-07-06 15:35 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Michael Elizabeth Chastain, ac131313, gdb-patches
On Tue, Jul 06, 2004 at 11:10:07AM -0400, Andrew Cagney wrote:
> >mec> Can you make more of the test names more unique?
> >ac> Oops, I thought I'd covered that. Try the attached.
> >
> >It works for me.
> >All the test names are unique except for "rerun to main".
> >Stil the same four FAILs but that's okay because they really are FAILs.
> >
> >I approve this patch.
> >
> >ac> Are there [get_kernel_info] and [get_software_singlestep] testsuite
> >calls?
> >
> >I don't know of any.
> >
> >I'm a bit leery of "get_kernel_info", because we should be testing
> >for features rather than version numbers (the whole autoconf philosophy).
> >Although get_compiler_info has worked reasonably well for the job
> >that it does.
> >
> >I'm more inclined to dump a bunch of KFAIL's into the gdb_test_multiple
> >arms for the bad results, along with comments about which kernel versions
> >have been observed to have which behavior. Then in 3-5 years it's not
> >hard to sort out the obsolete crap.
> >
> >If KFAIL's are too hard then just the comments for starters.
>
> I both kfailed and and commented, committing the attached.
I get:
KFAIL: gdb.base/sigbpt.exp: stepi out of handler; stepi (executed fault insn) (PRMS: gdb/1702)
KFAIL: gdb.base/sigbpt.exp: stepi out of handler; stepi bp before segv (executed fault insn) (PRMS: gdb/1702)
FAIL: gdb.base/sigbpt.exp: stepi out of handler; stepi bp at segv
FAIL: gdb.base/sigbpt.exp: stepi out of handler; stepi bp before and at segv
0x080483f2 in bowler () at /opt/src/gdb/src/gdb/testsuite/gdb.base/sigbpt.c:38
38 return *(char *) (v1 + v2 + v3);
1: x/i $pc 0x80483f2 <bowler+25>: mov $0x55c35d00,%esi
(gdb) FAIL: gdb.base/sigbpt.exp: stepi out of handler; stepi bp at segv
That's not the instruction that should be there; there's a multi-byte
instruction at <bowler+24>. My suspicion is that we single-stepped
with breakpoints inserted and no trap was triggered for the breakpint
at 0x80483f2 for whatever kernel reason. Make sense? If so, shall I
try to find a way to kfail this?
--
Daniel Jacobowitz
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [rfa] New test sigbpt.{c,exp}
2004-07-06 15:35 ` Daniel Jacobowitz
@ 2004-07-06 16:00 ` Andrew Cagney
0 siblings, 0 replies; 16+ messages in thread
From: Andrew Cagney @ 2004-07-06 16:00 UTC (permalink / raw)
To: Daniel Jacobowitz, gdb-patches, Michael Elizabeth Chastain
> On Tue, Jul 06, 2004 at 11:10:07AM -0400, Andrew Cagney wrote:
>
>>>> >mec> Can you make more of the test names more unique?
>>>> >ac> Oops, I thought I'd covered that. Try the attached.
>>>> >
>>>> >It works for me.
>>>> >All the test names are unique except for "rerun to main".
>>>> >Stil the same four FAILs but that's okay because they really are FAILs.
>>>> >
>>>> >I approve this patch.
>>>> >
>>>> >ac> Are there [get_kernel_info] and [get_software_singlestep] testsuite
>>>> >calls?
>>>> >
>>>> >I don't know of any.
>>>> >
>>>> >I'm a bit leery of "get_kernel_info", because we should be testing
>>>> >for features rather than version numbers (the whole autoconf philosophy).
>>>> >Although get_compiler_info has worked reasonably well for the job
>>>> >that it does.
>>>> >
>>>> >I'm more inclined to dump a bunch of KFAIL's into the gdb_test_multiple
>>>> >arms for the bad results, along with comments about which kernel versions
>>>> >have been observed to have which behavior. Then in 3-5 years it's not
>>>> >hard to sort out the obsolete crap.
>>>> >
>>>> >If KFAIL's are too hard then just the comments for starters.
>>
>>>
>>> I both kfailed and and commented, committing the attached.
>
>
> I get:
> KFAIL: gdb.base/sigbpt.exp: stepi out of handler; stepi (executed fault insn) (PRMS: gdb/1702)
> KFAIL: gdb.base/sigbpt.exp: stepi out of handler; stepi bp before segv (executed fault insn) (PRMS: gdb/1702)
> FAIL: gdb.base/sigbpt.exp: stepi out of handler; stepi bp at segv
> FAIL: gdb.base/sigbpt.exp: stepi out of handler; stepi bp before and at segv
>
> 0x080483f2 in bowler () at /opt/src/gdb/src/gdb/testsuite/gdb.base/sigbpt.c:38
> 38 return *(char *) (v1 + v2 + v3);
> 1: x/i $pc 0x80483f2 <bowler+25>: mov $0x55c35d00,%esi
> (gdb) FAIL: gdb.base/sigbpt.exp: stepi out of handler; stepi bp at segv
>
> That's not the instruction that should be there; there's a multi-byte
> instruction at <bowler+24>. My suspicion is that we single-stepped
> with breakpoints inserted and no trap was triggered for the breakpint
> at 0x80483f2 for whatever kernel reason. Make sense? If so, shall I
> try to find a way to kfail this?
s/we/the kernel/
The kernel executed both the system call and the breakpoint instruction
before returning control to GDB. This is a true loose loose situtation:
- GDB thinks its single stepping
- and that there's no bp at $pc
- and hence that after the single step there won't be a reason for decr
PC after break
outch!
Another pattern wouldn't hurt.
^ permalink raw reply [flat|nested] 16+ messages in thread
* [rfa] New test sigbpt.{c,exp}
@ 2004-06-29 23:44 Andrew Cagney
0 siblings, 0 replies; 16+ messages in thread
From: Andrew Cagney @ 2004-06-29 23:44 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 335 bytes --]
Hello,
This test checks for interaction between signal trampolines, single-step
and breakpoints. If nothing else, it highlights broken kernel code -
given a system call, both the system call instruction, and the one
following are executed.
I've a hacked i386 (Linux) and PPC (NetBSD) kernel where all the tests pass.
ok?
Andrew
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 10379 bytes --]
2004-06-18 Andrew Cagney <cagney@gnu.org>
* gdb.base/sigbpt.exp, gdb.base/sigbpt.c: New test.
Index: ./gdb/testsuite/gdb.base/sigbpt.c
===================================================================
RCS file: ./gdb/testsuite/gdb.base/sigbpt.c
diff -N ./gdb/testsuite/gdb.base/sigbpt.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.base/sigbpt.c 23 Jun 2004 13:52:43 -0000
@@ -0,0 +1,53 @@
+/* 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 <signal.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern void
+keeper (int sig)
+{
+}
+
+volatile long v1 = 0;
+volatile long v2 = 0;
+volatile long v3 = 0;
+
+extern long
+bowler (void)
+{
+ /* Try to read address zero. Do it in a slightly convoluted way so
+ that more than one instruction is used. */
+ return *(char *) (v1 + v2 + v3);
+}
+
+int
+main ()
+{
+ static volatile int i;
+
+ struct sigaction act;
+ memset (&act, 0, sizeof act);
+ act.sa_handler = keeper;
+ sigaction (SIGSEGV, &act, NULL);
+
+ bowler ();
+ return 0;
+}
Index: ./gdb/testsuite/gdb.base/sigbpt.exp
===================================================================
RCS file: ./gdb/testsuite/gdb.base/sigbpt.exp
diff -N ./gdb/testsuite/gdb.base/sigbpt.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.base/sigbpt.exp 23 Jun 2004 13:52:43 -0000
@@ -0,0 +1,231 @@
+# 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.
+
+# Check that GDB can and only executes single instructions when
+# stepping through a sequence of breakpoints interleaved by signal.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "sigbpt"
+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."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+# If we can examine what's at memory address 0, it is possible that we
+# could also execute it. This could probably make us run away,
+# executing random code, which could have all sorts of ill effects,
+# especially on targets without an MMU. Don't run the tests in that
+# case.
+
+send_gdb "x 0\n"
+gdb_expect {
+ -re "0x0:.*Cannot access memory at address 0x0.*$gdb_prompt $" { }
+ -re "0x0:.*Error accessing memory address 0x0.*$gdb_prompt $" { }
+ -re ".*$gdb_prompt $" {
+ untested "Memory at address 0 is possibly executable"
+ return
+ }
+}
+
+gdb_test "break keeper"
+
+# Run to bowler, and then single step until there's a SIGSEGV. Gather
+# the address of every stepped instruction in bowler (step_insn), and
+# the address of the SIGSEGV (segv_insn).
+
+set step_insn bowler
+gdb_test {display/i $pc}
+gdb_test "advance *bowler" "bowler.*" "advance to the bowler"
+set test "stepping to SIGSEGV"
+gdb_test_multiple "stepi" "$test" {
+ -re "Program received signal SIGSEGV.*pc *(0x\[0-9a-f\]*).*$gdb_prompt $" {
+ set segv_insn $expect_out(1,string)
+ pass "$test"
+ }
+ -re " .*pc *(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" {
+ set step_insn [concat $expect_out(1,string) $step_insn]
+ send_gdb "stepi\n"
+ exp_continue
+ }
+}
+
+# Now find the address of the instruction after the faulting
+# instruction.
+
+set test "get insn after fault"
+gdb_test_multiple {x/2i $pc} "$test" {
+ -re "(0x\[0-9a-f\]*).*bowler.*(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" {
+ set step_insn [concat $expect_out(2,string) $step_insn]
+ pass "$test"
+ }
+}
+
+set test "Verify that SIGSEGV occures at the last STEPI insn"
+if {[string compare $segv_insn [lindex $step_insn 1]] == 0} {
+ pass "$test"
+} else {
+ fail "$test ($segv_insn [lindex $step_insn 1])"
+}
+
+# Check that the inferior is correctly single stepped all the way back
+# to a faulting instruction.
+
+proc stepi_out { name step_insn args } {
+ global gdb_prompt
+
+ # Set SIGSEGV to pass+nostop and then run the inferior all the way
+ # through to the signal handler. With the handler is reached,
+ # disable SIGSEGV, ensuring that further signals stop the
+ # inferior. Stops a SIGSEGV infinite loop when a broke system
+ # keeps re-executing the faulting instruction.
+ rerun_to_main
+ gdb_test "handle SIGSEGV nostop print pass" "" "pass SIGSEGV for $name"
+ gdb_test "continue" "keeper.*" "continue to keeper for $name"
+ gdb_test "handle SIGSEGV stop print nopass" "" "pass SIGSEGV for $name"
+
+ # Insert all the breakpoints. To avoid the need to step over
+ # these instructions, this is delayed until after the keeper has
+ # been reached.
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "break [lindex $args $i]" "Breakpoint.*" \
+ "set breakpoint $i of [llength $args] for $name"
+ }
+
+ # Single step our way out of the keeper, through the signal
+ # trampoline, and back to the instruction that faulted.
+ set test "stepi out of handler for $name"
+ gdb_test_multiple "stepi" "$test" {
+ -re "keeper.*$gdb_prompt $" {
+ send_gdb "stepi\n"
+ exp_continue
+ }
+ -re "signal handler.*$gdb_prompt $" {
+ send_gdb "stepi\n"
+ exp_continue
+ }
+ -re "Program received signal SIGSEGV.*$gdb_prompt $" {
+ fail "$test (executed fault insn)"
+ }
+ -re "Breakpoint.*pc *[lindex $step_insn 1] .*bowler.*$gdb_prompt $" {
+ pass "$test (at breakpoint)"
+ }
+ -re "Breakpoint.*pc *[lindex $step_insn 0] .*bowler.*$gdb_prompt $" {
+ fail "$test (executed breakpoint)"
+ }
+ -re "pc *[lindex $step_insn 1] .*bowler.*$gdb_prompt $" {
+ pass "$test"
+ }
+ -re "pc *[lindex $step_insn 0] .*bowler.*$gdb_prompt $" {
+ fail "$test (skipped fault insn)"
+ }
+ }
+
+ # Clear any breakpoints
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "clear [lindex $args $i]" "Deleted .*" \
+ "clear breakpoint $i of [llength $args] for $name"
+ }
+}
+
+stepi_out "no breakpoints" $step_insn
+
+# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering
+# breakpoints around the faulting address.
+
+stepi_out "bp before segv" $step_insn \
+ "*[lindex $step_insn 2]"
+stepi_out "bp at segv" $step_insn \
+ "*[lindex $step_insn 1]"
+stepi_out "bp before and at segv" $step_insn \
+ "*[lindex $step_insn 1]" "*[lindex $step_insn 2]"
+
+# Let a signal handler exit, returning to a breakpoint instruction.
+# Check that the breakpoint is hit, and then single stepping triggers
+# a further SIGSEGV.
+
+proc cont_to_bp { name step_insn args } {
+ global gdb_prompt
+
+ # Set SIGSEGV to pass+nostop and then run the inferior all the way
+ # through to the signal handler. With the handler is reached,
+ # disable SIGSEGV, ensuring that further signals stop the
+ # inferior. Stops a SIGSEGV infinite loop when a broke system
+ # keeps re-executing the faulting instruction.
+ rerun_to_main
+ gdb_test "handle SIGSEGV nostop print pass" "" "pass SIGSEGV for $name"
+ gdb_test "continue" "keeper.*" "continue to keeper for $name"
+ gdb_test "handle SIGSEGV stop print nopass" "" "pass SIGSEGV for $name"
+
+ # Insert all the breakpoints. To avoid the need to step over
+ # these instructions, this is delayed until after the keeper has
+ # been reached. Always set a breakpoint at the signal trampoline
+ # instruction.
+ set args [concat $args "*[lindex $step_insn 1]"]
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "break [lindex $args $i]" "Breakpoint.*" \
+ "set breakpoint $i of [llength $args] for $name"
+ }
+
+ # Let the handler return, it should "appear to hit" the breakpoint
+ # inserted at the faulting instruction. Note that the breakpoint
+ # instruction wasn't executed, rather the inferior was SIGTRAPed
+ # with the PC at the breakpoint.
+ gdb_test "continue" "Breakpoint.*pc *[lindex $step_insn 1] .*" \
+ "continue to breakpoint at fault for $name"
+
+ # Now single step the faulted instrction at that breakpoint.
+ gdb_test "stepi" \
+ "Program received signal SIGSEGV.*pc *[lindex $step_insn 1] .*" \
+ "stepi fault for $name"
+
+ # Clear any breakpoints
+ for {set i 0} {$i < [llength $args]} {incr i} {
+ gdb_test "clear [lindex $args $i]" "Deleted .*" \
+ "clear breakpoint $i of [llength $args] for $name"
+ }
+
+}
+
+cont_to_bp "no breakpoints" $step_insn
+
+# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering
+# breakpoints around the faulting address.
+cont_to_bp "no breakpoints" $step_insn \
+ "*[lindex $step_insn 2]"
+cont_to_bp "no breakpoints" $step_insn \
+ "*[lindex $step_insn 2]" "*[lindex $step_insn 0]"
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2004-07-08 14:28 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-06-30 3:53 [rfa] New test sigbpt.{c,exp} Michael Elizabeth Chastain
2004-06-30 15:25 ` Andrew Cagney
2004-06-30 15:30 ` Daniel Jacobowitz
2004-07-02 13:24 ` Andrew Cagney
-- strict thread matches above, loose matches on Subject: below --
2004-07-07 18:39 Michael Elizabeth Chastain
2004-07-06 18:59 Michael Elizabeth Chastain
2004-07-06 19:29 ` Andrew Cagney
2004-07-07 17:31 ` Andrew Cagney
2004-07-08 14:28 ` Daniel Jacobowitz
2004-07-06 18:12 Michael Elizabeth Chastain
2004-07-06 18:30 ` Daniel Jacobowitz
2004-06-30 18:53 Michael Elizabeth Chastain
2004-07-06 15:10 ` Andrew Cagney
2004-07-06 15:35 ` Daniel Jacobowitz
2004-07-06 16:00 ` Andrew Cagney
2004-06-29 23:44 Andrew Cagney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox