diff options
Diffstat (limited to 'gdb/testsuite')
-rw-r--r-- | gdb/testsuite/ChangeLog | 12 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/break.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/hbreak2.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/sepdebug.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/watch_thread_num.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.linespec/keywords.exp | 8 | ||||
-rw-r--r-- | gdb/testsuite/gdb.multi/info-threads.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.multi/tids.c | 56 | ||||
-rw-r--r-- | gdb/testsuite/gdb.multi/tids.exp | 296 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/thread-find.exp | 4 |
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" |