This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
hpux11 vs interrupt.exp
- From: law at redhat dot com
- To: gdb-patches at sources dot redhat dot com
- Date: Thu, 20 Dec 2001 14:20:41 -0700
- Subject: hpux11 vs interrupt.exp
- Reply-to: law at redhat dot com
We are failing various tests in interrupt.exp due to a unwanted signal
delivery to the inferior when it's restarted to perform an inferior
function call after it was interrupted via ^C. The unwanted signal causes
the inferior to prematurely exit.
The fundamental problem is infttrace.c::child_resume attempts to be clever
and use TT_PROC_CONTINUE to restart the inferior. TT_PROC_CONTINUE is
more efficient than TT_LWP_CONTINUE, but it can not clear pending signals
in the inferior.
Rather than trying to be clever, my patch just uses TT_LWP_CONTINUE -- which
results in cleaner code and code that actually works.
The net result is we get no unexpected failures in interrupt.exp. Yippie.
* infttrace.c (child_resume): Don't try to use TT_PROC_CONTINUE,
just use the slightly less efficient TT_LWP_CONTINUE.
Index: infttrace.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/infttrace.c,v
retrieving revision 2.22.14.2
diff -c -3 -p -r2.22.14.2 infttrace.c
*** infttrace.c 2001/12/20 05:01:35 2.22.14.2
--- infttrace.c 2001/12/20 21:17:44
*************** child_resume (ptid_t ptid, int step, enu
*** 4539,4636 ****
else
{
! /* TT_LWP_CONTINUE can pass signals to threads,
! * TT_PROC_CONTINUE can't. So if there are any
! * signals to pass, we have to use the (slower)
! * loop over the stopped threads.
! *
! * Equally, if we have to not continue some threads,
! * due to saved events, we have to use the loop.
! */
! if ((signal != 0) || saved_signals_exist ())
! {
! if (resume_all_threads)
! {
!
! #ifdef THREAD_DEBUG
! if (debug_on)
! printf ("Doing a continue by loop of all threads\n");
! #endif
! threads_continue_all_with_signals (tid, signal);
!
! clear_all_handled ();
! clear_all_stepping_mode ();
! }
!
! else
! {
#ifdef THREAD_DEBUG
! printf ("Doing a continue w/signal of just thread %d\n", tid);
#endif
! threads_continue_one_with_signal (tid, signal);
! /* Clear the "handled" state of this thread, because
! * we'll soon get a new event for it. Other events
! * can stay as they were.
! */
! clear_handled (tid);
! clear_stepping_mode (tid);
! }
}
-
else
{
- /* No signals to send.
- */
- if (resume_all_threads)
- {
- #ifdef THREAD_DEBUG
- if (debug_on)
- printf ("Doing a continue by process of process %d\n", tid);
- #endif
-
- if (more_events_left > 0)
- {
- warning ("Losing buffered events on continue.");
- more_events_left = 0;
- }
-
- call_ttrace (TT_PROC_CONTINUE,
- tid,
- TT_NIL,
- TT_NIL,
- TT_NIL);
-
- clear_all_handled ();
- clear_all_stepping_mode ();
- }
-
- else
- {
#ifdef THREAD_DEBUG
! if (debug_on)
! {
! printf ("Doing a continue of just thread %d\n", tid);
! if (is_terminated (tid))
! printf ("Why are we continuing a dead thread? (5)\n");
! }
#endif
! call_ttrace (TT_LWP_CONTINUE,
! tid,
! TT_NIL,
! TT_NIL,
! TT_NIL);
! /* Clear the "handled" state of this thread, because
! * we'll soon get a new event for it. Other events
! * can stay as they were.
! */
! clear_handled (tid);
! clear_stepping_mode (tid);
! }
}
}
--- 4539,4579 ----
else
{
! /* TT_LWP_CONTINUE can pass signals to threads, TT_PROC_CONTINUE can't.
! Therefore, we really can't use TT_PROC_CONTINUE here.
! Consider a process which stopped due to signal which gdb decides
! to handle and not pass on to the inferior. In that case we must
! clear the pending signal by restarting the inferior using
! TT_LWP_CONTINUE and pass zero as the signal number. Else the
! pending signal will be passed to the inferior. interrupt.exp
! in the testsuite does this precise thing and fails due to the
! unwanted signal delivery to the inferior. */
! if (resume_all_threads)
! {
#ifdef THREAD_DEBUG
! if (debug_on)
! printf ("Doing a continue by loop of all threads\n");
#endif
! threads_continue_all_with_signals (tid, signal);
! clear_all_handled ();
! clear_all_stepping_mode ();
}
else
{
#ifdef THREAD_DEBUG
! printf ("Doing a continue w/signal of just thread %d\n", tid);
#endif
! threads_continue_one_with_signal (tid, signal);
! /* Clear the "handled" state of this thread, because we
! will soon get a new event for it. Other events can
! stay as they were. */
! clear_handled (tid);
! clear_stepping_mode (tid);
}
}
T