diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f13c19a63c..850b26754b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,19 @@ +2014-06-19 Pedro Alves + + * 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 * i386-nat.c (i386_stopped_by_watchpoint): diff --git a/gdb/btrace.c b/gdb/btrace.c index 601eb4126c..87a171e812 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -958,7 +958,7 @@ btrace_free_objfile (struct objfile *objfile) DEBUG ("free objfile"); - ALL_THREADS (tp) + ALL_NON_EXITED_THREADS (tp) btrace_clear (tp); } diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h index 9f5dee6ea0..64e37c3cdc 100644 --- a/gdb/gdbthread.h +++ b/gdb/gdbthread.h @@ -317,10 +317,12 @@ void thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid); 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); diff --git a/gdb/infrun.c b/gdb/infrun.c index 2be2e5e7d4..bef69a8124 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2160,7 +2160,7 @@ find_thread_needs_step_over (int step, struct thread_info *except) return NULL; } - ALL_THREADS (tp) + ALL_NON_EXITED_THREADS (tp) { /* Ignore the EXCEPT thread. */ if (tp == except) @@ -5204,7 +5204,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs) 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 diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index e0c537a8d3..6a9bfe1187 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -206,7 +206,7 @@ record_btrace_open (char *args, int from_tty) 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); @@ -238,7 +238,7 @@ record_btrace_stop_recording (struct target_ops *self) record_btrace_auto_disable (); - ALL_THREADS (tp) + ALL_NON_EXITED_THREADS (tp) if (tp->btrace.target != NULL) btrace_disable (tp); } @@ -259,7 +259,7 @@ record_btrace_close (struct target_ops *self) /* 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); } @@ -835,7 +835,7 @@ record_btrace_is_replaying (struct target_ops *self) { struct thread_info *tp; - ALL_THREADS (tp) + ALL_NON_EXITED_THREADS (tp) if (btrace_is_replaying (tp)) return 1; @@ -1522,7 +1522,7 @@ record_btrace_resume (struct target_ops *ops, ptid_t ptid, int step, /* 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. */ @@ -1572,7 +1572,7 @@ record_btrace_find_thread_to_move (ptid_t ptid) 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; @@ -1777,7 +1777,7 @@ record_btrace_wait (struct target_ops *ops, ptid_t ptid, /* 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. */ diff --git a/gdb/remote.c b/gdb/remote.c index 6915dd8d04..b5318f1d07 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -4626,7 +4626,7 @@ append_pending_thread_resumptions (char *p, char *endp, ptid_t ptid) { 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 diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 2fdcbb4601..af374091d0 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-06-19 Pedro Alves + + * 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 * gdb.cp/nsalias.exp: Set type of low_pc and high_pc entries diff --git a/gdb/testsuite/gdb.threads/thread-execl.exp b/gdb/testsuite/gdb.threads/thread-execl.exp index d837fe4d1c..14b96d21d7 100644 --- a/gdb/testsuite/gdb.threads/thread-execl.exp +++ b/gdb/testsuite/gdb.threads/thread-execl.exp @@ -28,19 +28,33 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ return -1 } -clean_restart ${binfile} +# Run the test proper. SCHEDLOCK specifies what scheduler-locking +# should be set to. -runto_main +proc do_test { schedlock } { + global binfile -# Get ourselves to the thread that execs -gdb_breakpoint "thread_execler" -gdb_test "continue" ".*thread_execler.*" "continue to thread start" + with_test_prefix "schedlock $schedlock" { + clean_restart ${binfile} -# 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" + if ![runto_main] { + return 0 + } -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" + } +} + +foreach schedlock {"off" "step" "on"} { + do_test $schedlock +} diff --git a/gdb/thread.c b/gdb/thread.c index 7bc5271fed..532149ddc6 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -1243,7 +1243,7 @@ thread_apply_all_command (char *cmd, int from_tty) ta_cleanup.tp_array = tp_array; ta_cleanup.count = tc; - ALL_THREADS (tp) + ALL_NON_EXITED_THREADS (tp) { tp_array[i] = tp; tp->refcount++;