From: Pedro Alves Date: Wed, 23 Dec 2020 13:39:18 +0000 (+0000) Subject: Testcase for attaching in non-stop mode X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=92234eb192f11b1981acb46a3a5e725360b89d6f;p=binutils-gdb.git Testcase for attaching in non-stop mode This adds a testcase exercising attaching to a multi-threaded process, in all combinations of: - set non-stop on/off - maint target non-stop off/on - "attach" vs "attach &" This exercises the bugs fixed in the two previous patches. gdb/testsuite/ChangeLog: * gdb.threads/attach-non-stop.c: New file. * gdb.threads/attach-non-stop.exp: New file. --- diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 5731d0e08b0..75fcf3e77e4 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2021-02-03 Pedro Alves + + * gdb.threads/attach-non-stop.c: New file. + * gdb.threads/attach-non-stop.exp: New file. + 2021-02-02 Lancelot SIX * gdb.base/inferior-noarg.c: New test. diff --git a/gdb/testsuite/gdb.threads/attach-non-stop.c b/gdb/testsuite/gdb.threads/attach-non-stop.c new file mode 100644 index 00000000000..23a8b258c18 --- /dev/null +++ b/gdb/testsuite/gdb.threads/attach-non-stop.c @@ -0,0 +1,58 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2021 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 . */ + +#define _GNU_SOURCE +#include +#include +#include + +/* Number of threads we'll create. */ +static const int n_threads = 10; + +/* Entry point for threads. Loops forever. */ + +void * +thread_func (void *arg) +{ + while (1) + sleep (1); + + return NULL; +} + +int +main (int argc, char **argv) +{ + int i; + + alarm (30); + + /* Spawn the test threads. */ + for (i = 0; i < n_threads; ++i) + { + pthread_t child; + int rc; + + rc = pthread_create (&child, NULL, thread_func, NULL); + assert (rc == 0); + } + + while (1) + sleep (1); + + return 0; +} diff --git a/gdb/testsuite/gdb.threads/attach-non-stop.exp b/gdb/testsuite/gdb.threads/attach-non-stop.exp new file mode 100644 index 00000000000..99b5bff94c8 --- /dev/null +++ b/gdb/testsuite/gdb.threads/attach-non-stop.exp @@ -0,0 +1,148 @@ +# Copyright 2021 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 . + +# Test attaching to a multi-threaded process, in all combinations of: +# +# - set non-stop on/off +# - maint target non-stop off/on +# - "attach" vs "attach &" + +if {![can_spawn_for_attach]} { + return 0 +} + +standard_testfile + +# The test proper. See description above. + +proc test {target_non_stop non_stop cmd} { + global binfile srcfile + global gdb_prompt + global decimal + global GDBFLAGS + + # Number of threads started by the program. + set n_threads 10 + + save_vars { GDBFLAGS } { + append GDBFLAGS " -ex \"maint set target-non-stop $target_non_stop\"" + append GDBFLAGS " -ex \"set non-stop $non_stop\"" + clean_restart $binfile + } + + set test_spawn_id [spawn_wait_for_attach $binfile] + set testpid [spawn_id_get_pid $test_spawn_id] + + set attached 0 + set test "attach" + set any "\[^\r\n\]*" + + if {$cmd == "attach"} { + gdb_test_multiple "attach $testpid" $test { + -re "Attaching to program:${any}process $testpid\r\n.*$gdb_prompt " { + pass $test + set attached 1 + } + } + + if {!$attached} { + kill_wait_spawned_process $test_spawn_id + return + } + + if {$non_stop} { + # In non-stop, we will see one stop per thread after + # the prompt. + set stops 0 + set test "seen all stops" + for {set thread 1} { $thread <= $n_threads } { incr thread } { + gdb_test_multiple "" $test { + -re "Thread $::decimal ${any} stopped" { + incr stops + } + } + } + + # If we haven't seen all stops, then the gdb_test_multiple + # in the loop above will have already issued a FAIL. + if {$stops == $n_threads} { + pass $test + } + } + + gdb_test_multiple "info threads" "" { + -re "\\(running\\).*$gdb_prompt $" { + fail $gdb_test_name + } + -re "$gdb_prompt $" { + pass $gdb_test_name + } + } + } else { + gdb_test_multiple "attach $testpid &" $test { + -re "Attaching to program:${any}process $testpid\r\n.*$gdb_prompt " { + pass $test + set attached 1 + } + } + + if {!$attached} { + kill_wait_spawned_process $test_spawn_id + return + } + + set running_count 0 + gdb_test_multiple "info threads" "all threads running" { + -re "\\(running\\)" { + incr running_count + exp_continue + } + -re "Cannot execute this command while the target is running.*$gdb_prompt $" { + # Testing against a remote server that doesn't do + # non-stop mode. Explicitly interrupt. This doesn't + # test the same code paths in GDB, but it's still + # something. + gdb_test_multiple "interrupt" "" { + -re "$gdb_prompt " { + gdb_test_multiple "" $gdb_test_name { + -re "received signal SIGINT, Interrupt" { + pass $gdb_test_name + } + } + } + } + } + -re "$gdb_prompt $" { + gdb_assert {$running_count == ($n_threads + 1)} $gdb_test_name + } + } + } + + gdb_test "detach" "Detaching from.*" + + kill_wait_spawned_process $test_spawn_id +} + +if {[build_executable "failed to prepare" $testfile $srcfile {debug pthreads}] == -1} { + return -1 +} + +foreach_with_prefix target-non-stop {"off" "on"} { + foreach_with_prefix non-stop {"off" "on"} { + foreach_with_prefix cmd {"attach" "attach&"} { + test ${target-non-stop} ${non-stop} ${cmd} + } + } +}