aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/testsuite')
-rw-r--r--gdb/testsuite/ChangeLog12
-rw-r--r--gdb/testsuite/gdb.base/break.exp2
-rw-r--r--gdb/testsuite/gdb.base/hbreak2.exp2
-rw-r--r--gdb/testsuite/gdb.base/sepdebug.exp2
-rw-r--r--gdb/testsuite/gdb.base/watch_thread_num.exp2
-rw-r--r--gdb/testsuite/gdb.linespec/keywords.exp8
-rw-r--r--gdb/testsuite/gdb.multi/info-threads.exp2
-rw-r--r--gdb/testsuite/gdb.multi/tids.c56
-rw-r--r--gdb/testsuite/gdb.multi/tids.exp296
-rw-r--r--gdb/testsuite/gdb.threads/thread-find.exp4
10 files changed, 375 insertions, 11 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index ec2a067..d9bafe1 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,15 @@
+2016-01-07 Pedro Alves <palves@redhat.com>
+
+ * gdb.base/break.exp: Adjust to output changes.
+ * gdb.base/hbreak2.exp: Likewise.
+ * gdb.base/sepdebug.exp: Likewise.
+ * gdb.base/watch_thread_num.exp: Likewise.
+ * gdb.linespec/keywords.exp: Likewise.
+ * gdb.multi/info-threads.exp: Likewise.
+ * gdb.threads/thread-find.exp: Likewise.
+ * gdb.multi/tids.c: New file.
+ * gdb.multi/tids.exp: New file.
+
2016-01-13 Pedro Alves <palves@redhat.com>
* gdb.python/py-infthread.exp: Test InferiorThread.inferior.
diff --git a/gdb/testsuite/gdb.base/break.exp b/gdb/testsuite/gdb.base/break.exp
index 3ec74bf..2b4587e 100644
--- a/gdb/testsuite/gdb.base/break.exp
+++ b/gdb/testsuite/gdb.base/break.exp
@@ -550,7 +550,7 @@ gdb_test "break $bp_location12 thread 999" "Unknown thread 999.*" \
"thread-specific breakpoint on non-existent thread disallowed"
gdb_test "break $bp_location12 thread foo" \
- "Junk after thread keyword.*" \
+ "Invalid thread ID: foo" \
"thread-specific breakpoint on bogus thread ID disallowed"
# Verify that GDB responds gracefully to a breakpoint command with
diff --git a/gdb/testsuite/gdb.base/hbreak2.exp b/gdb/testsuite/gdb.base/hbreak2.exp
index dbf55f3..3a303ec 100644
--- a/gdb/testsuite/gdb.base/hbreak2.exp
+++ b/gdb/testsuite/gdb.base/hbreak2.exp
@@ -341,7 +341,7 @@ gdb_test "hbreak $bp_location12 thread 999" "Unknown thread 999.*" \
"thread-specific hardware breakpoint on non-existent thread disallowed"
gdb_test "hbreak $bp_location12 thread foo" \
- "Junk after thread keyword.*" \
+ "Invalid thread ID: foo" \
"thread-specific hardware breakpoint on bogus thread ID disallowed"
# Verify that GDB responds gracefully to a breakpoint command with
diff --git a/gdb/testsuite/gdb.base/sepdebug.exp b/gdb/testsuite/gdb.base/sepdebug.exp
index ad87269..3ad3669 100644
--- a/gdb/testsuite/gdb.base/sepdebug.exp
+++ b/gdb/testsuite/gdb.base/sepdebug.exp
@@ -361,7 +361,7 @@ gdb_test "break $bp_location12 thread 999" "Unknown thread 999.*" \
"thread-specific breakpoint on non-existent thread disallowed"
gdb_test "break $bp_location12 thread foo" \
- "Junk after thread keyword.*" \
+ "Invalid thread ID: foo" \
"thread-specific breakpoint on bogus thread ID disallowed"
# Verify that GDB responds gracefully to a breakpoint command with
diff --git a/gdb/testsuite/gdb.base/watch_thread_num.exp b/gdb/testsuite/gdb.base/watch_thread_num.exp
index b3ce273..eff9fbd 100644
--- a/gdb/testsuite/gdb.base/watch_thread_num.exp
+++ b/gdb/testsuite/gdb.base/watch_thread_num.exp
@@ -46,7 +46,7 @@ if { ![runto main] } then {
return
}
-gdb_test "watch shared_var thread 0" "Unknown thread 0\." "Watchpoint on invalid thread"
+gdb_test "watch shared_var thread 0" "Invalid thread ID: 0" "Watchpoint on invalid thread"
gdb_test "watch shared_var thread" "A syntax error in expression, near `thread'\." "Invalid watch syntax"
set bpexitline [gdb_get_line_number "all threads started"]
diff --git a/gdb/testsuite/gdb.linespec/keywords.exp b/gdb/testsuite/gdb.linespec/keywords.exp
index 03f662c..11e2c4c 100644
--- a/gdb/testsuite/gdb.linespec/keywords.exp
+++ b/gdb/testsuite/gdb.linespec/keywords.exp
@@ -54,16 +54,16 @@ with_test_prefix "trailing whitespace" {
# break {thread,task} NUMBER --> invalid thread/task
# break {thread,task} STUFF --> "junk" after keyword (STUFF is not numeric)
gdb_test "break thread 123" "Unknown thread 123\\."
-gdb_test "break thread foo" "Junk after thread keyword\\."
+gdb_test "break thread foo" "Invalid thread ID: foo"
gdb_test "break task 123" "Unknown task 123\\."
gdb_test "break task foo" "Junk after task keyword\\."
gdb_breakpoint "thread if 0" "message"
# These are also NULL locations, but using a subsequent keyword
# as the "junk".
-gdb_test "break thread thread" "Junk after thread keyword\\."
-gdb_test "break thread task" "Junk after thread keyword\\."
-gdb_test "break thread if" "Junk after thread keyword\\."
+gdb_test "break thread thread" "Invalid thread ID: thread"
+gdb_test "break thread task" "Invalid thread ID: task"
+gdb_test "break thread if" "Invalid thread ID: if"
gdb_test "break task task" "Junk after task keyword\\."
gdb_test "break task thread" "Junk after task keyword\\."
gdb_test "break task if" "Junk after task keyword\\."
diff --git a/gdb/testsuite/gdb.multi/info-threads.exp b/gdb/testsuite/gdb.multi/info-threads.exp
index 7ae60d7..f8d9c6d 100644
--- a/gdb/testsuite/gdb.multi/info-threads.exp
+++ b/gdb/testsuite/gdb.multi/info-threads.exp
@@ -36,4 +36,4 @@ gdb_test "inferior 2" "Switching to inferior 2.*" "switch to inferior 2"
# "info threads" while inferior 1 has execution and inferior 2 is not
# running yet should show inferior 1's thread, and give no error.
-gdb_test "info threads" "1 .* main .* at .*$srcfile:.*No selected thread.*"
+gdb_test "info threads" "1\.1 .* main .* at .*$srcfile:.*No selected thread.*"
diff --git a/gdb/testsuite/gdb.multi/tids.c b/gdb/testsuite/gdb.multi/tids.c
new file mode 100644
index 0000000..8a53d43
--- /dev/null
+++ b/gdb/testsuite/gdb.multi/tids.c
@@ -0,0 +1,56 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2015-2016 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 <unistd.h>
+#include <pthread.h>
+
+pthread_t child_thread[2];
+
+void *
+thread_function2 (void *arg)
+{
+ while (1)
+ sleep (1);
+
+ return NULL;
+}
+
+void *
+thread_function1 (void *arg)
+{
+ pthread_create (&child_thread[1], NULL, thread_function2, NULL);
+
+ while (1)
+ sleep (1);
+
+ return NULL;
+}
+
+int
+main (void)
+{
+ int i;
+
+ alarm (300);
+
+ pthread_create (&child_thread[0], NULL, thread_function1, NULL);
+
+ for (i = 0; i < 2; i++)
+ pthread_join (child_thread[i], NULL);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp
new file mode 100644
index 0000000..70a1d81
--- /dev/null
+++ b/gdb/testsuite/gdb.multi/tids.exp
@@ -0,0 +1,296 @@
+# Copyright 2015-2016 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/>.
+
+# Test thread ID parsing and display.
+
+load_lib gdb-python.exp
+
+standard_testfile
+
+# Multiple inferiors are needed, therefore both native and extended
+# gdbserver modes are supported. Only non-extended gdbserver is not
+# supported.
+if [target_info exists use_gdb_stub] {
+ untested ${testfile}.exp
+ return
+}
+
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} {pthreads debug}] } {
+ return -1
+}
+
+clean_restart ${testfile}
+
+if { ![runto_main] } then {
+ return -1
+}
+
+# Issue "thread apply TID_LIST p 1234" and expect EXP_TID_LIST (a list
+# of thread ids) to be displayed.
+proc thread_apply {tid_list exp_tid_list {message ""}} {
+ global decimal
+ set any "\[^\r\n\]*"
+ set expected [string_to_regexp $exp_tid_list]
+
+ set r ""
+ foreach tid $expected {
+ append r "\[\r\n\]+"
+ append r "Thread $tid $any:\r\n"
+ append r "\\$$decimal = 1234"
+ }
+
+ set cmd "thread apply $tid_list"
+ if {$message == ""} {
+ set message $cmd
+ }
+ gdb_test "$cmd p 1234" $r $message
+}
+
+# Issue "info threads TID_LIST" and expect EXP_TID_LIST (a list of
+# thread ids) to be displayed.
+proc info_threads {tid_list exp_tid_list {message ""}} {
+ set any "\[^\r\n\]*"
+ set expected [string_to_regexp $exp_tid_list]
+ set r [join $expected " ${any}\r\n${any} "]
+ set r "${any} $r ${any}"
+ set cmd "info threads $tid_list"
+ if {$message == ""} {
+ set message $cmd
+ }
+ gdb_test $cmd $r $message
+}
+
+# Issue "info threads TID_LIST" and expect INFO_THR output. Then
+# issue "thread apply TID_LIST" and expect THR_APPLY output. If
+# THR_APPLY is omitted, INFO_THR is expected instead.
+proc thr_apply_info_thr {tid_list info_thr {thr_apply ""}} {
+ if {$thr_apply == ""} {
+ set thr_apply $info_thr
+ }
+
+ info_threads $tid_list $info_thr
+ thread_apply $tid_list $thr_apply
+}
+
+# Issue both "info threads TID_LIST" and "thread apply TID_LIST" and
+# expect both commands to error out with EXP_ERROR.
+proc thr_apply_info_thr_error {tid_list exp_error} {
+ gdb_test "info threads $tid_list" \
+ $exp_error
+
+ gdb_test "thread apply $tid_list p 1234" \
+ $exp_error \
+ "thread apply $tid_list"
+}
+
+# Issue both "info threads TID_LIST" and "thread apply TID_LIST" and
+# expect the command to error out with "Invalid thread ID: $EXPECTED".
+# EXPECTED is a literal string, not a regexp.
+proc thr_apply_info_thr_invalid {tid_list expected} {
+ set expected [string_to_regexp $expected]
+ gdb_test "info threads $tid_list" \
+ "Invalid thread ID: $expected"
+
+ gdb_test "thread apply $tid_list p 1234" \
+ "Invalid thread ID: $expected p 1234" \
+ "thread apply $tid_list"
+}
+
+# "info threads" while there's only inferior 1 should show
+# single-number thread IDs.
+with_test_prefix "single inferior" {
+ info_threads "" "1"
+
+ gdb_test "thread" "Current thread is 1 .*"
+}
+
+# "info threads" while there are multiple inferiors should show
+# qualified thread IDs.
+with_test_prefix "two inferiors" {
+ # Add another inferior.
+ gdb_test "add-inferior" "Added inferior 2.*" "add empty inferior 2"
+
+ # Now that we've added another inferior, thread IDs now show the
+ # inferior number.
+ info_threads "" "1.1"
+
+ gdb_test "thread" "Current thread is 1\.1 .*"
+
+ gdb_test "inferior 2" "Switching to inferior 2 .*" "switch to inferior 2"
+ gdb_test "file ${binfile}" ".*" "load file in inferior 2"
+
+ runto_main
+
+ # Now that we've added another inferior, thread IDs now show the
+ # inferior number.
+ info_threads "" "1.1 2.1" \
+ "info threads show inferior numbers"
+
+ gdb_test "thread" "Current thread is 2\.1 .*" \
+ "switch to thread using extended thread ID"
+
+ gdb_breakpoint "thread_function1"
+
+ gdb_continue_to_breakpoint "once"
+ gdb_test "inferior 1" "Switching to inferior 1 .*"
+ gdb_continue_to_breakpoint "twice"
+
+ info_threads "" "1.1 1.2 2.1 2.2" \
+ "info threads again"
+
+ # Confirm the convenience variable show the expected number.
+ gdb_test "p \$_thread == 2" " = 1"
+
+ # Without an explicit inferior component, GDB defaults to the
+ # current inferior. Make sure we don't refer to a thread by
+ # global ID by mistake.
+ gdb_test "thread 4" "Unknown thread 1.4\\."
+
+ # Test thread ID list parsing. Test qualified and unqualified
+ # IDs; qualified and unqualified ranges; invalid IDs and invalid
+ # ranges.
+
+ # First spawn a couple more threads so ranges includes more than
+ # two threads.
+ with_test_prefix "more threads" {
+ gdb_breakpoint "thread_function2"
+
+ gdb_test "inferior 2" "Switching to inferior 2 .*"
+ gdb_continue_to_breakpoint "once"
+
+ gdb_test "inferior 1" "Switching to inferior 1 .*"
+ gdb_continue_to_breakpoint "twice"
+ }
+
+ thr_apply_info_thr "1 2 3" \
+ "1.1 1.2 1.3"
+
+ # Same, but with qualified thread IDs.
+ thr_apply_info_thr "1.1 1.2 1.3 2.1 2.2" \
+ "1.1 1.2 1.3 2.1 2.2"
+
+ # Test a thread number range.
+ thr_apply_info_thr "1-3" \
+ "1.1 1.2 1.3"
+
+ # Same, but using a qualified range.
+ thr_apply_info_thr "1.1-3" \
+ "1.1 1.2 1.3"
+
+ # A mix of qualified and unqualified thread IDs/ranges.
+ thr_apply_info_thr "1.1 2-3" \
+ "1.1 1.2 1.3"
+
+ thr_apply_info_thr "1 1.2-3" \
+ "1.1 1.2 1.3"
+
+ # Likewise, but mix inferiors too.
+ thr_apply_info_thr "2.1 2-3" \
+ "1.2 1.3 2.1" \
+ "2.1 1.2 1.3"
+
+ # Multiple ranges with mixed explicit inferiors.
+ thr_apply_info_thr "1.1-2 2.2-3" \
+ "1.1 1.2 2.2 2.3"
+
+ # Now test a set of invalid thread IDs/ranges.
+
+ thr_apply_info_thr_invalid "1." \
+ "1."
+
+ thr_apply_info_thr_invalid "1-3 1." \
+ "1."
+
+ thr_apply_info_thr_invalid "1.1.1" \
+ "1.1.1"
+
+ thr_apply_info_thr_invalid "2 1.1.1" \
+ "1.1.1"
+
+ thr_apply_info_thr_invalid "1.1.1 2" \
+ "1.1.1 2"
+
+ thr_apply_info_thr_invalid "1-2.1" \
+ "1-2.1"
+
+ thr_apply_info_thr_error "1-0" "inverted range"
+ thr_apply_info_thr_error "1.1-0" "inverted range"
+
+ thr_apply_info_thr_error "1-" "inverted range"
+ thr_apply_info_thr_error "1.1-" "inverted range"
+
+ thr_apply_info_thr_error "2-1" "inverted range"
+ thr_apply_info_thr_error "1.2-1" "inverted range"
+
+ thr_apply_info_thr_error "-1" "negative value"
+ thr_apply_info_thr_error "1.-1" "negative value"
+
+ # Check that we do parse the inferior number and don't confuse it.
+ gdb_test "info threads 3.1" \
+ "No threads match '3.1'\."
+}
+
+if { ![skip_python_tests] } {
+ with_test_prefix "python" {
+ # Check that InferiorThread.num returns the expected number.
+ gdb_py_test_silent_cmd "python t0 = gdb.selected_thread ()" \
+ "test gdb.selected_thread" 1
+ gdb_test "python print ('result = %s' % t0.num)" " = 3" \
+ "test InferiorThread.num"
+ }
+}
+
+# Remove the second inferior and confirm that GDB goes back to showing
+# single-number thread IDs.
+with_test_prefix "back to one inferior" {
+ gdb_test "kill inferior 2" "" "kill inferior 2" "Kill the program being debugged.*" "y"
+ gdb_test "thread 1.1" "Switching to thread 1\.1 .*"
+ gdb_test "remove-inferior 2" ".*" "remove inferior 2"
+
+ # "info threads" while there's only inferior 1 should show
+ # single-number thread IDs.
+ info_threads "" "1 2 3"
+
+ gdb_test "thread" "Current thread is 1 .*"
+}
+
+# Add another inferior and remove inferior 1. Since even though
+# there's a single inferior, its number is not 1, GDB should show
+# inferior-qualified thread IDs.
+with_test_prefix "single-inferior but not initial" {
+ # Add another inferior.
+ gdb_test "add-inferior" "Added inferior 3.*" "add empty inferior"
+
+ # Now that we'd added another inferior, thread IDs should show the
+ # inferior number.
+ info_threads "" "1.1 1.2 1.3" \
+ "info threads with multiple inferiors"
+
+ gdb_test "thread" "Current thread is 1\.1 .*"
+
+ gdb_test "inferior 3" "Switching to inferior 3 .*" "switch to inferior 3"
+ gdb_test "file ${binfile}" ".*" "load file in inferior 3"
+
+ runto_main
+
+ gdb_test "remove-inferior 1" ".*" "remove inferior 1"
+
+ # Even though we have a single inferior, its number is > 1, so
+ # thread IDs should include the inferior number.
+ info_threads "" "3.1" \
+ "info threads with single inferior"
+
+ gdb_test "thread" "Current thread is 3\.1 .*" "thread again"
+}
diff --git a/gdb/testsuite/gdb.threads/thread-find.exp b/gdb/testsuite/gdb.threads/thread-find.exp
index bd90c57..6d885a7 100644
--- a/gdb/testsuite/gdb.threads/thread-find.exp
+++ b/gdb/testsuite/gdb.threads/thread-find.exp
@@ -276,9 +276,9 @@ gdb_test_multiple "info threads 3-3" "info threads 3-3" {
# Test bad input
gdb_test "info thread foo" \
- "Args must be numbers or '.' variables." \
+ "Invalid thread ID: foo" \
"info thread foo"
gdb_test "info thread foo -1" \
- "Args must be numbers or '.' variables." \
+ "Invalid thread ID: foo -1" \
"info thread foo -1"