This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

hpux11 vs interrupt.exp



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






Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]