This is the mail archive of the gdb-patches@sourceware.org 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]

[PATCH] Fix staticthreads test case with merged Linux targets


Hello,

another problem triggered by Linux target rework: the staticthreads
test case hangs.  This is because when the thread-db handling does
not work properly (because the statically linked inferior uses
LinuxThreads, while the dynamically linked gdb expects NPTL), we
still get informed of clone events; the kernel then automatically
attaches gdb to the new clone as well.  What the old child_wait
function did in this case was to simply detach again and leave
the new clone alone.

With the merged Linux targets, linux_nat_handle_extended gets
invoked and simply adds the new clone to the LWP list.  However,
it not only does not detach from the new clone, it also does
not *continue* it.  

Now, when linux_nat_handle_extended is invoked from within
stop_wait_callback (via wait_lwp), this is likely the correct
behaviour -- we are currenly in the process of stopping all
LWPs, so the new one should be stopped as well.  It will be
continued when we resume all LWPs.

However, when linux_nat_handle_extended is invoked from within
linux_nat_wait, that function will simply continue waiting on
the inferior, without resuming the new clone.

In the staticthreads test case, this deadlocks: gdb waits on
an event on the initial thread of the inferior, which is blocked
on waiting for the new thread -- which never started up.

Now, I'm not sure how the whole treatment of LWPs in the absence
of thread-db is really supposed to work.  However, the following
patch appears reasonable to me and does fix the test case.  What
the patch does is to simply add an argument to linux_nat_handle_extended
whether it should leave the new clone stopped or resume it.  The
two callers can then choose the proper behaviour.

This exposed another bug in exit_lwp: if one such LWP exists, it
may have never been on the main thread list -- in that case the
exit_lwp code accesses a NULL pointer.  The fix should be obvious.

Tested on s390-ibm-linux and s390x-ibm-linux without regressions.

OK for mainline?

Bye,
Ulrich

ChangeLog:

	* linux-nat.c (exit_lwp): Fix NULL pointer access.
	(linux_nat_handle_extended): New parameter STOPPING.
	(wait_lwp): Call it with STOPPING equals 1.
	(linux_nat_wait): Call it with STOPPING equals 0.


Index: gdb/linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-nat.c,v
retrieving revision 1.41
diff -c -p -r1.41 linux-nat.c
*** gdb/linux-nat.c	30 Mar 2006 16:34:23 -0000	1.41
--- gdb/linux-nat.c	6 Apr 2006 00:17:46 -0000
*************** exit_lwp (struct lwp_info *lp)
*** 899,908 ****
        struct thread_info *thr;
  
        thr = iterate_over_threads (find_thread_from_lwp, &lp->ptid);
!       if (thr && !ptid_equal (thr->ptid, inferior_ptid))
! 	delete_thread (thr->ptid);
!       else
! 	record_dead_thread (thr->ptid);
      }
  
    delete_lwp (lp->ptid);
--- 899,911 ----
        struct thread_info *thr;
  
        thr = iterate_over_threads (find_thread_from_lwp, &lp->ptid);
!       if (thr)
! 	{
! 	  if (!ptid_equal (thr->ptid, inferior_ptid))
! 	    delete_thread (thr->ptid);
! 	  else
! 	    record_dead_thread (thr->ptid);
! 	}
      }
  
    delete_lwp (lp->ptid);
*************** kill_lwp (int lwpid, int signo)
*** 1278,1287 ****
     just pass off to linux_handle_extended_wait, but if it reports a
     clone event we need to add the new LWP to our list (and not report
     the trap to higher layers).  This function returns non-zero if
!    the event should be ignored and we should wait again.  */
  
  static int
! linux_nat_handle_extended (struct lwp_info *lp, int status)
  {
    linux_handle_extended_wait (GET_LWP (lp->ptid), status,
  			      &lp->waitstatus);
--- 1281,1291 ----
     just pass off to linux_handle_extended_wait, but if it reports a
     clone event we need to add the new LWP to our list (and not report
     the trap to higher layers).  This function returns non-zero if
!    the event should be ignored and we should wait again.  If STOPPING
!    is true, the new LWP remains stopped, otherwise it is continued.  */
  
  static int
! linux_nat_handle_extended (struct lwp_info *lp, int status, int stopping)
  {
    linux_handle_extended_wait (GET_LWP (lp->ptid), status,
  			      &lp->waitstatus);
*************** linux_nat_handle_extended (struct lwp_in
*** 1293,1299 ****
        new_lp = add_lwp (BUILD_LWP (lp->waitstatus.value.related_pid,
  				   GET_PID (inferior_ptid)));
        new_lp->cloned = 1;
!       new_lp->stopped = 1;
  
        lp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
  
--- 1297,1307 ----
        new_lp = add_lwp (BUILD_LWP (lp->waitstatus.value.related_pid,
  				   GET_PID (inferior_ptid)));
        new_lp->cloned = 1;
! 
!       if (stopping)
! 	new_lp->stopped = 1;
!       else
! 	ptrace (PTRACE_CONT, lp->waitstatus.value.related_pid, 0, 0);
  
        lp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
  
*************** wait_lwp (struct lwp_info *lp)
*** 1377,1383 ****
  	fprintf_unfiltered (gdb_stdlog,
  			    "WL: Handling extended status 0x%06x\n",
  			    status);
!       if (linux_nat_handle_extended (lp, status))
  	return wait_lwp (lp);
      }
  
--- 1385,1391 ----
  	fprintf_unfiltered (gdb_stdlog,
  			    "WL: Handling extended status 0x%06x\n",
  			    status);
!       if (linux_nat_handle_extended (lp, status, 1))
  	return wait_lwp (lp);
      }
  
*************** retry:
*** 2022,2028 ****
  		fprintf_unfiltered (gdb_stdlog,
  				    "LLW: Handling extended status 0x%06x\n",
  				    status);
! 	      if (linux_nat_handle_extended (lp, status))
  		{
  		  status = 0;
  		  continue;
--- 2030,2036 ----
  		fprintf_unfiltered (gdb_stdlog,
  				    "LLW: Handling extended status 0x%06x\n",
  				    status);
! 	      if (linux_nat_handle_extended (lp, status, 0))
  		{
  		  status = 0;
  		  continue;
-- 
  Dr. Ulrich Weigand
  Linux on zSeries Development
  Ulrich.Weigand@de.ibm.com


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