Blob Blame History Raw
Index: ./gdb/linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-nat.c,v
retrieving revision 1.64
diff -u -p -r1.64 linux-nat.c
--- ./gdb/linux-nat.c	16 Jun 2007 17:16:25 -0000	1.64
+++ ./gdb/linux-nat.c	18 Jun 2007 12:53:41 -0000
@@ -1109,15 +1109,17 @@ resume_set_callback (struct lwp_info *lp
 }
 
 static void
-linux_nat_resume (ptid_t ptid, int step, enum target_signal signo)
+linux_nat_resume (ptid_t ptid, int step_int, enum target_signal signo)
 {
   struct lwp_info *lp;
   int resume_all;
+  enum resume_step step = step_int;
 
   if (debug_linux_nat)
     fprintf_unfiltered (gdb_stdlog,
 			"LLR: Preparing to %s %s, %s, inferior_ptid %s\n",
-			step ? "step" : "resume",
+			(step == RESUME_STEP_NEEDED
+			 ? "needed" : (step ? "step" : "resume")),
 			target_pid_to_str (ptid),
 			signo ? strsignal (signo) : "0",
 			target_pid_to_str (inferior_ptid));
@@ -2077,6 +2082,9 @@ retry:
 	  /* Check if the thread has exited.  */
 	  if ((WIFEXITED (status) || WIFSIGNALED (status)) && num_lwps > 1)
 	    {
+	      enum resume_step step = lp->step;
+	      pid_t pid = GET_PID (lp->ptid);
+
 	      /* If this is the main thread, we must stop all threads and
 	         verify if they are still alive.  This is because in the nptl
 	         thread model, there is no signal issued for exiting LWPs
@@ -2095,6 +2103,10 @@ retry:
 		fprintf_unfiltered (gdb_stdlog,
 				    "LLW: %s exited.\n",
 				    target_pid_to_str (lp->ptid));
+	      /* Backward compatibility with:
+		 gdb-6.3-step-thread-exit-20050211.patch  */
+	      if (step == RESUME_STEP_USER)
+		printf_unfiltered ("[Stepped over thread exit]\n");
 
 	      exit_lwp (lp);
 
@@ -2105,8 +2117,29 @@ retry:
 	         ignored.  */
 	      if (num_lwps > 0)
 		{
-		  /* Make sure there is at least one thread running.  */
-		  gdb_assert (iterate_over_lwps (running_callback, NULL));
+		  if (step == RESUME_STEP_USER)
+		    {
+		      /* Now stop the closest LWP's ...  */
+		      lp = find_lwp_pid (pid_to_ptid (pid));
+		      if (!lp)
+		        lp = lwp_list;
+		      errno = 0;
+		      ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0,
+			      (void *) (unsigned long) SIGSTOP);
+		      if (debug_linux_nat)
+			fprintf_unfiltered (gdb_stdlog,
+					    "PTRACE_CONT %s, 0, 0 (%s)\n",
+					    target_pid_to_str (lp->ptid),
+					    errno ? safe_strerror (errno)
+						  : "OK");
+		      /* Avoid the silent `delayed SIGSTOP' handling.  */
+		      lp->signalled = 0;
+		    }
+		  else
+		    {
+		      /* Make sure there is at least one thread running.  */
+		      gdb_assert (iterate_over_lwps (running_callback, NULL));
+		    }
 
 		  /* Discard the event.  */
 		  status = 0;