+2014-06-19  Pedro Alves  <palves@redhat.com>
+
+       * gdbthread.h (ALL_THREADS): Delete.
+       (ALL_NON_EXITED_THREADS): New macro.
+       * btrace.c (btrace_free_objfile): Use ALL_NON_EXITED_THREADS
+       instead of ALL_THREADS.
+       * infrun.c (find_thread_needs_step_over)
+       (switch_back_to_stepped_thread): Use ALL_NON_EXITED_THREADS
+       instead of ALL_THREADS.
+       * record-btrace.c (record_btrace_open)
+       (record_btrace_stop_recording, record_btrace_close)
+       (record_btrace_is_replaying, record_btrace_resume)
+       (record_btrace_find_thread_to_move, record_btrace_wait): Likewise.
+       * remote.c (append_pending_thread_resumptions): Likewise.
+       * thread.c (thread_apply_all_command): Likewise.
+
 2014-06-19  Gary Benson  <gbenson@redhat.com>
 
        * i386-nat.c (i386_stopped_by_watchpoint):
 
 
   DEBUG ("free objfile");
 
-  ALL_THREADS (tp)
+  ALL_NON_EXITED_THREADS (tp)
     btrace_clear (tp);
 }
 
 
 typedef int (*thread_callback_func) (struct thread_info *, void *);
 extern struct thread_info *iterate_over_threads (thread_callback_func, void *);
 
-/* Traverse all threads.  */
+/* Traverse all threads, except those that have THREAD_EXITED
+   state.  */
 
-#define ALL_THREADS(T)                         \
-  for (T = thread_list; T; T = T->next)
+#define ALL_NON_EXITED_THREADS(T)                              \
+  for (T = thread_list; T; T = T->next) \
+    if ((T)->state != THREAD_EXITED)
 
 extern int thread_count (void);
 
 
       return NULL;
     }
 
-  ALL_THREADS (tp)
+  ALL_NON_EXITED_THREADS (tp)
     {
       /* Ignore the EXCEPT thread.  */
       if (tp == except)
         step/next/etc.  */
       stepping_thread = NULL;
       step_over = NULL;
-      ALL_THREADS (tp)
+      ALL_NON_EXITED_THREADS (tp)
         {
          /* Ignore threads of processes we're not resuming.  */
          if (!sched_multi
 
   gdb_assert (record_btrace_thread_observer == NULL);
 
   disable_chain = make_cleanup (null_cleanup, NULL);
-  ALL_THREADS (tp)
+  ALL_NON_EXITED_THREADS (tp)
     if (args == NULL || *args == 0 || number_is_in_list (args, tp->num))
       {
        btrace_enable (tp);
 
   record_btrace_auto_disable ();
 
-  ALL_THREADS (tp)
+  ALL_NON_EXITED_THREADS (tp)
     if (tp->btrace.target != NULL)
       btrace_disable (tp);
 }
 
   /* We should have already stopped recording.
      Tear down btrace in case we have not.  */
-  ALL_THREADS (tp)
+  ALL_NON_EXITED_THREADS (tp)
     btrace_teardown (tp);
 }
 
 {
   struct thread_info *tp;
 
-  ALL_THREADS (tp)
+  ALL_NON_EXITED_THREADS (tp)
     if (btrace_is_replaying (tp))
       return 1;
 
 
   /* Stop replaying other threads if the thread to resume is not replaying.  */
   if (!btrace_is_replaying (tp) && execution_direction != EXEC_REVERSE)
-    ALL_THREADS (other)
+    ALL_NON_EXITED_THREADS (other)
       record_btrace_stop_replaying (other);
 
   /* As long as we're not replaying, just forward the request.  */
     return tp;
 
   /* Otherwise, find one other thread that has been resumed.  */
-  ALL_THREADS (tp)
+  ALL_NON_EXITED_THREADS (tp)
     if ((tp->btrace.flags & BTHR_MOVE) != 0)
       return tp;
 
 
   /* Stop all other threads. */
   if (!non_stop)
-    ALL_THREADS (other)
+    ALL_NON_EXITED_THREADS (other)
       other->btrace.flags &= ~BTHR_MOVE;
 
   /* Start record histories anew from the current position.  */
 
 {
   struct thread_info *thread;
 
-  ALL_THREADS (thread)
+  ALL_NON_EXITED_THREADS (thread)
     if (ptid_match (thread->ptid, ptid)
        && !ptid_equal (inferior_ptid, thread->ptid)
        && thread->suspend.stop_signal != GDB_SIGNAL_0
 
+2014-06-19  Pedro Alves  <palves@redhat.com>
+
+       * gdb.threads/thread-execl.exp (do_test): New procedure, factored
+       out from ...
+       (top level): ... here.  Iterate running tests under different
+       scheduler-locking settings.
+
 2014-06-18  Luis Machado  <lgustavo@codesourcery.com>
 
        * gdb.cp/nsalias.exp: Set type of low_pc and high_pc entries
 
     return -1
 }
 
-clean_restart ${binfile}
-
-runto_main
-
-# Get ourselves to the thread that execs
-gdb_breakpoint "thread_execler"
-gdb_test "continue" ".*thread_execler.*" "continue to thread start"
-
-# Now set a breakpoint at `main', and step over the execl call.  The
-# breakpoint at main should be reached.  GDB should not try to revert
-# back to the old thread from the old image and resume stepping it
-# (since it is gone).
-gdb_breakpoint "main"
-gdb_test "next" ".*main.*" "get to main in new image"
+# Run the test proper.  SCHEDLOCK specifies what scheduler-locking
+# should be set to.
+
+proc do_test { schedlock } {
+    global binfile
+
+    with_test_prefix "schedlock $schedlock" {
+       clean_restart ${binfile}
+
+       if ![runto_main] {
+           return 0
+       }
+
+       # Get ourselves to the thread that execs.
+       gdb_breakpoint "thread_execler"
+       gdb_test "continue" ".*thread_execler.*" "continue to thread start"
+
+       # Now set a breakpoint at `main', and step over the execl call.  The
+       # breakpoint at main should be reached.  GDB should not try to revert
+       # back to the old thread from the old image and resume stepping it
+       # (since it is gone).
+       gdb_breakpoint "main"
+       gdb_test_no_output "set scheduler-locking $schedlock"
+       gdb_test "next" ".*main.*" "get to main in new image"
+    }
+}
 
-return 0
+foreach schedlock {"off" "step" "on"} {
+    do_test $schedlock
+}
 
       ta_cleanup.tp_array = tp_array;
       ta_cleanup.count = tc;
 
-      ALL_THREADS (tp)
+      ALL_NON_EXITED_THREADS (tp)
         {
           tp_array[i] = tp;
           tp->refcount++;