aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.threads
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/testsuite/gdb.threads')
-rw-r--r--gdb/testsuite/gdb.threads/thread-specific-bp.c40
-rw-r--r--gdb/testsuite/gdb.threads/thread-specific-bp.exp127
2 files changed, 167 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.threads/thread-specific-bp.c b/gdb/testsuite/gdb.threads/thread-specific-bp.c
new file mode 100644
index 0000000..03831c6
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/thread-specific-bp.c
@@ -0,0 +1,40 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2013 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+
+static void *
+start (void *arg)
+{
+ return NULL;
+}
+
+static void
+end (void)
+{
+}
+
+int
+main (void)
+{
+ pthread_t thread;
+
+ pthread_create (&thread, NULL, start, NULL);
+ pthread_join (thread, NULL);
+ end ();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.threads/thread-specific-bp.exp b/gdb/testsuite/gdb.threads/thread-specific-bp.exp
new file mode 100644
index 0000000..9f7d142
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/thread-specific-bp.exp
@@ -0,0 +1,127 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Verify that a thread-specific breakpoint is deleted when the
+# corresponding thread is gone.
+
+standard_testfile
+
+if {[gdb_compile_pthreads \
+ "${srcdir}/${subdir}/${srcfile}" \
+ "${binfile}" executable {debug} ] != "" } {
+ return -1
+}
+
+clean_restart ${binfile}
+
+# Extract and return the thread ID of the thread stopped at function
+# FUNC.
+
+proc get_thread_id {func} {
+ global gdb_prompt
+
+ set thre -1
+ set test "get $func thread id"
+ gdb_test_multiple "info threads" $test {
+ -re "(\[0-9\]+)\[^\n\r\]*Thread\[^\n\r\]*$func.*$gdb_prompt $" {
+ # Get the thread's id.
+ set thre $expect_out(1,string)
+ pass $test
+ }
+ }
+
+ return $thre
+}
+
+proc check_thread_specific_breakpoint {mode} {
+ with_test_prefix "$mode" {
+ global gdb_prompt
+
+ if ![runto_main] {
+ untested "could not run to main"
+ return -1
+ }
+
+ set main_thre [get_thread_id "main"]
+ if { $main_thre < 0 } {
+ return -1
+ }
+
+ gdb_breakpoint "start"
+ gdb_continue_to_breakpoint "start"
+
+ set start_thre [get_thread_id "start"]
+ if { $start_thre < 0 } {
+ return -1
+ }
+
+ # Set a thread-specific breakpoint at "main". This can't ever
+ # be hit, but that's OK.
+ gdb_breakpoint "main thread $start_thre"
+ gdb_test "info break" ".*breakpoint.*thread $start_thre" "breakpoint set"
+
+ # Set breakpoint at a place only reacheable after the "start"
+ # thread exits.
+ gdb_breakpoint "end"
+
+ # Switch back to the main thread, and resume all threads. The
+ # "start" thread exits, and the main thread reaches "end".
+ gdb_test "thread $main_thre" \
+ "Switching to thread $main_thre.*" \
+ "thread $main_thre selected"
+
+ if { $mode == "non-stop" } {
+ set cmd "continue -a"
+ } else {
+ set cmd "continue"
+ }
+ gdb_test "$cmd" \
+ "Breakpoint .* end .* at .*" \
+ "continue to end"
+
+ # Force GDB to update the thread list. Otherwise, depending
+ # on target, GDB may not realize that the start thread has
+ # exited and thus not remove the thread specific breakpoint.
+ set test "thread start is gone"
+ gdb_test_multiple "info threads" $test {
+ -re "\[0-9\]+.*start.*$gdb_prompt $" {
+ fail $test
+ }
+ -re "$gdb_prompt $" {
+ pass $test
+ }
+ }
+
+ set test "thread-specific breakpoint was deleted"
+ gdb_test_multiple "info breakpoint" $test {
+ -re "thread $start_thre\n$gdb_prompt $" {
+ fail $test
+ }
+ -re "$gdb_prompt $" {
+ pass $test
+ }
+ }
+ }
+}
+
+# Test all-stop mode.
+check_thread_specific_breakpoint "all-stop"
+
+clean_restart ${binfile}
+
+# Test non-stop mode.
+gdb_test_no_output "set target-async on" "set async mode"
+gdb_test_no_output "set non-stop on" "set non-stop mode"
+check_thread_specific_breakpoint "non-stop"