This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: RFC: Do not call write_pc for "signal SIGINT"
- From: Daniel Jacobowitz <drow at false dot org>
- To: Michael Snyder <msnyder at vmware dot com>, gdb-patches at sourceware dot org
- Date: Mon, 17 Nov 2008 16:55:01 -0500
- Subject: Re: RFC: Do not call write_pc for "signal SIGINT"
- References: <20080828155520.GA23110@caradoc.them.org> <48B6E9F4.5080403@vmware.com> <20080828181841.GA30866@caradoc.them.org> <48B6EFBD.2090203@vmware.com> <20080828223232.GA6407@caradoc.them.org>
On Thu, Aug 28, 2008 at 06:32:32PM -0400, Daniel Jacobowitz wrote:
> On Thu, Aug 28, 2008 at 11:34:37AM -0700, Michael Snyder wrote:
> > More than a testcase. This isn't very well explained.
> > You didn't reference the PR in your original post, and
>
> It was in the ChangeLog entry, sorry.
Here it is with a testcase.
To recap: there is a tricky bug in signal_command. If any non-zero
signal is specified, it performs a jump to the current address instead
of just resuming there. This causes any pending system call to be
interrupted, in a way that leaves a kernel-internal value in the
return value register. If we just delete that code, and the FIXME
that goes with it, the right thing happens: instead of "Unknown
error 514", the system call returns EINTR and the loop continues.
Michael, is that clearer?
--
Daniel Jacobowitz
CodeSourcery
2008-11-17 Daniel Jacobowitz <dan@codesourcery.com>
PR gdb/2241
* infcmd.c (signal_command): Do not specify a resume PC.
2008-11-17 Daniel Jacobowitz <dan@codesourcery.com>
PR gdb/2241
* gdb.base/interrupt.c (sigint_handler): New.
(main): Install a SIGINT handler if SIGNALS is defined. Exit
on error.
* gdb.base/interrupt.exp: Define SIGNALS unless gdb,nosignals.
Test "signal SIGINT".
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.222
diff -u -p -r1.222 infcmd.c
--- infcmd.c 5 Nov 2008 20:23:07 -0000 1.222
+++ infcmd.c 17 Nov 2008 21:27:58 -0000
@@ -1147,11 +1147,7 @@ signal_command (char *signum_exp, int fr
}
clear_proceed_status ();
- /* "signal 0" should not get stuck if we are stopped at a breakpoint.
- FIXME: Neither should "signal foo" but when I tried passing
- (CORE_ADDR)-1 unconditionally I got a testsuite failure which I haven't
- tried to track down yet. */
- proceed (oursig == TARGET_SIGNAL_0 ? (CORE_ADDR) -1 : stop_pc, oursig, 0);
+ proceed ((CORE_ADDR) -1, oursig, 0);
}
/* Proceed until we reach a different source line with pc greater than
Index: testsuite/gdb.base/interrupt.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/interrupt.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 interrupt.c
--- testsuite/gdb.base/interrupt.c 28 Jun 1999 16:03:16 -0000 1.1.1.2
+++ testsuite/gdb.base/interrupt.c 17 Nov 2008 21:29:38 -0000
@@ -2,6 +2,16 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
+
+#ifdef SIGNALS
+#include <signal.h>
+
+static void
+sigint_handler (int signo)
+{
+}
+#endif
+
int
main ()
{
@@ -11,6 +21,9 @@ main ()
set_debug_traps();
breakpoint();
#endif
+#ifdef SIGNALS
+ signal (SIGINT, sigint_handler);
+#endif
printf ("talk to me baby\n");
while (1)
{
@@ -20,7 +33,10 @@ main ()
#ifdef EINTR
if (errno != EINTR)
#endif
- perror ("");
+ {
+ perror ("");
+ return 1;
+ }
}
else if (nbytes == 0)
{
Index: testsuite/gdb.base/interrupt.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/interrupt.exp,v
retrieving revision 1.12
diff -u -p -r1.12 interrupt.exp
--- testsuite/gdb.base/interrupt.exp 6 Aug 2008 12:52:07 -0000 1.12
+++ testsuite/gdb.base/interrupt.exp 17 Nov 2008 21:29:38 -0000
@@ -34,7 +34,13 @@ set bug_id 0
set testfile interrupt
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
-if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+
+set options { debug }
+if { ! [target_info exists gdb,nosignals] } {
+ lappend options "additional_flags=-DSIGNALS"
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $options] != "" } {
untested interrupt.exp
return -1
}
@@ -165,7 +171,35 @@ if ![file exists $binfile] then {
eof { fail "echo data (eof)" }
}
- setup_xfail "i*86-pc-linux*-gnu*"
+ if { ! [target_info exists gdb,nosignals] } {
+ # Wait until the program is in the read system call again.
+ sleep 2
+
+ # Stop the program for another test.
+ set msg "Send Control-C, second time"
+ send_gdb "\003"
+ gdb_test_multiple "" "$msg" {
+ -re "Program received signal SIGINT.*$gdb_prompt $" {
+ pass "$msg"
+ }
+ }
+
+ # The "signal" command should deliver the correctg signal and
+ # return to the loop.
+ set msg "signal SIGINT"
+ gdb_test_multiple "signal SIGINT" "$msg" {
+ -re "^signal SIGINT\r\nContinuing with signal SIGINT.\r\n(\r\n|)$" { pass "$msg" }
+ }
+
+ # We should be back in the loop.
+ send_gdb "more data\n"
+ gdb_expect {
+ -re "^(\r\n|)more data\r\n(|more data\r\n)$" { pass "echo more data" }
+ timeout { fail "echo more data (timeout)" }
+ eof { fail "echo more data (eof)" }
+ }
+ }
+
send_gdb "\004"
gdb_expect {
-re "end of file.*Program exited normally.*$gdb_prompt $" {