This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFA] testsuite: handle SIGBUS like SIGSEGV
- From: Tristan Gingold <gingold at ACT-Europe dot FR>
- To: gdb-patches at sourceware dot org
- Date: Tue, 16 Dec 2008 14:57:21 +0100
- Subject: [RFA] testsuite: handle SIGBUS like SIGSEGV
Hi,
on Darwin, dereferencing NULL generates SIGBUS instead of SIGSEGV on other
platforms. (On darwin, SIGBUS is generated when the map rights do not
allow the access while SIGSEGV is generated when there is no page mapped
at the address).
All the testcase assumes SIGSEGV is generated and therefore fails on Darwin.
This patch fixes the issue: the first test accepts both signals and keeps its
name and the following ones check against the name.
There are no regressions on x86/gnu-linux.
This patch fixes two major occurences but I know there are a few others.
Tristan.
2008-12-16 Tristan Gingold <gingold@adacore.com>
* gdb.base/sigbpt.exp: Detect which signal is received when a NULL
pointer is dereferenced and use this signal name in regexp.
* gdb.base/signull.exp: Ditto.
* gdb.base/sigbpt.c (main): Catch SIGBUS too.
* gdb.base/signull.c (main): Ditto.
diff -u -p -r1.4 sigbpt.c
--- testsuite/gdb.base/sigbpt.c 1 Jan 2008 22:53:19 -0000 1.4
+++ testsuite/gdb.base/sigbpt.c 16 Dec 2008 13:49:52 -0000
@@ -45,6 +45,7 @@ main ()
memset (&act, 0, sizeof act);
act.sa_handler = keeper;
sigaction (SIGSEGV, &act, NULL);
+ sigaction (SIGBUS, &act, NULL);
bowler ();
return 0;
Index: testsuite/gdb.base/sigbpt.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/sigbpt.exp,v
retrieving revision 1.13
diff -u -p -r1.13 sigbpt.exp
--- testsuite/gdb.base/sigbpt.exp 1 Jan 2008 22:53:19 -0000 1.13
+++ testsuite/gdb.base/sigbpt.exp 16 Dec 2008 13:49:52 -0000
@@ -83,15 +83,19 @@ gdb_test "break keeper"
# 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.
+# Note: this test detects which signal is received. Usually it is SIGSEGV
+# (and we use SIGSEGV in comments) but on Darwin it is SIGBUS.
set bowler_addrs bowler
set segv_addr none
gdb_test {display/i $pc}
gdb_test "advance *bowler" "bowler.*" "advance to the bowler"
-set test "stepping to SIGSEGV"
+set test "stepping to fault"
+set signame "SIGSEGV"
gdb_test_multiple "stepi" "$test" {
- -re "Program received signal SIGSEGV.*pc(\r\n| *) *(0x\[0-9a-f\]*).*$gdb_prompt $" {
- set segv_addr $expect_out(2,string)
+ -re "Program received signal (SIG\[A-Z\]*).*pc(\r\n| *) *(0x\[0-9a-f\]*).*$gdb_prompt $" {
+ set signame $expect_out(1,string)
+ set segv_addr $expect_out(3,string)
pass "$test"
}
-re " .*pc(\r\n| *)(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" {
@@ -132,7 +136,7 @@ proc after_segv { } {
# Check that the address table and SIGSEGV correspond.
-set test "Verify that SIGSEGV occurs at the last STEPI insn"
+set test "Verify that ${signame} occurs at the last STEPI insn"
if {[string compare $segv_addr [at_segv]] == 0} {
pass "$test"
} else {
@@ -144,6 +148,7 @@ if {[string compare $segv_addr [at_segv]
proc stepi_out { name args } {
global gdb_prompt
+ global signame
# Set SIGSEGV to pass+nostop and then run the inferior all the way
# through to the signal handler. With the handler is reached,
@@ -151,9 +156,9 @@ proc stepi_out { name args } {
# 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" "" "${name}; pass SIGSEGV"
+ gdb_test "handle ${signame} nostop print pass" "" "${name}; pass ${signame}"
gdb_test "continue" "keeper.*" "${name}; continue to keeper"
- gdb_test "handle SIGSEGV stop print nopass" "" "${name}; nopass SIGSEGV"
+ gdb_test "handle ${signame} stop print nopass" "" "${name}; nopass ${signame}"
# Insert all the breakpoints. To avoid the need to step over
# these instructions, this is delayed until after the keeper has
@@ -213,6 +218,7 @@ proc stepi_out { name args } {
proc cont_out { name args } {
global gdb_prompt
+ global signame
# Set SIGSEGV to pass+nostop and then run the inferior all the way
# through to the signal handler. With the handler is reached,
@@ -220,9 +226,9 @@ proc cont_out { name args } {
# 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" "" "${name}; pass SIGSEGV"
+ gdb_test "handle ${signame} nostop print pass" "" "${name}; pass ${signame}"
gdb_test "continue" "keeper.*" "${name}; continue to keeper"
- gdb_test "handle SIGSEGV stop print nopass" "" "${name}; nopass SIGSEGV"
+ gdb_test "handle ${signame} stop print nopass" "" "${name}; nopass ${signame}"
# Insert all the breakpoints. To avoid the need to step over
# these instructions, this is delayed until after the keeper has
@@ -243,7 +249,7 @@ proc cont_out { name args } {
# Now single step the faulted instrction at that breakpoint.
gdb_test "stepi" \
- "Program received signal SIGSEGV.*pc(\r\n| *)[at_segv] .*" \
+ "Program received signal ${signame}.*pc(\r\n| *)[at_segv] .*" \
"${name}; stepi fault"
# Clear any breakpoints
Index: testsuite/gdb.base/signull.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/signull.c,v
retrieving revision 1.7
diff -u -p -r1.7 signull.c
--- testsuite/gdb.base/signull.c 1 Jan 2008 22:53:19 -0000 1.7
+++ testsuite/gdb.base/signull.c 16 Dec 2008 13:49:52 -0000
@@ -77,6 +77,7 @@ main ()
memset (&act, 0, sizeof act);
act.sa_handler = keeper;
sigaction (SIGSEGV, &act, NULL);
+ sigaction (SIGBUS, &act, NULL);
for (i = 0; i < 10; i++)
{
Index: testsuite/gdb.base/signull.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/signull.exp,v
retrieving revision 1.10
diff -u -p -r1.10 signull.exp
--- testsuite/gdb.base/signull.exp 1 Jan 2008 22:53:19 -0000 1.10
+++ testsuite/gdb.base/signull.exp 16 Dec 2008 13:49:52 -0000
@@ -83,6 +83,7 @@ gdb_expect {
gdb_test "set test = code_entry_point" "" "set for function pointer probe"
set test "probe function pointer"
set function_pointer code_entry_point
+set signame "SIGSEGV"
gdb_test_multiple "continue" "$test" {
-re "Program received signal SIGSEGV.*bowler .*$gdb_prompt $" {
set function_pointer code_descriptor
@@ -91,6 +92,10 @@ gdb_test_multiple "continue" "$test" {
-re "Program received signal SIGSEGV.*0.*$gdb_prompt $" {
pass "$test (function entry-point)"
}
+ -re "Program received signal SIGBUS.*0.*$gdb_prompt $" {
+ set signame SIGBUS
+ pass "$test (function entry-point)"
+ }
}
# Re-start from scratch, breakpoint the bowler so that control is
@@ -100,20 +105,22 @@ gdb_test "break bowler"
gdb_test "break keeper"
# By default Stop:Yes Print:Yes Pass:Yes
gdb_test "handle SIGSEGV" "SIGSEGV.*Yes.*Yes.*Yes.*Segmentation fault"
+gdb_test "handle SIGBUS" "SIGBUS.*Yes.*Yes.*Yes.*Bus error"
# For the given signal type, check that: the SIGSEGV occures; a
# backtrace from the SEGV works; the sigsegv is delivered; a backtrace
# through the SEGV works.
proc test_segv { name tag bt_from_segv bt_from_keeper } {
+ global signame
gdb_test continue "Breakpoint.* bowler.*" "${name}; start with the bowler"
# NB: Don't use $tag in the testname - changes across systems.
gdb_test "set test = $tag" "" "${name}; select the pointer type"
- gdb_test continue "Program received signal SIGSEGV.*" \
- "${name}; take the SIGSEGV"
- gdb_test backtrace $bt_from_segv "${name}; backtrace from SIGSEGV"
+ gdb_test continue "Program received signal ${signame}.*" \
+ "${name}; take the ${signame}"
+ gdb_test backtrace $bt_from_segv "${name}; backtrace from ${signame}"
gdb_test continue "Breakpoint.* keeper.*" "${name}; continue to the keeper"
- gdb_test backtrace $bt_from_keeper "${name}; backtrace from keeper through SIGSEGV"
+ gdb_test backtrace $bt_from_keeper "${name}; backtrace from keeper through ${signame}"
}
test_segv "data read" data_read \