diff options
author | Antoine Tremblay <antoine.tremblay@ericsson.com> | 2016-06-16 23:46:53 +0100 |
---|---|---|
committer | Antoine Tremblay <antoine.tremblay@ericsson.com> | 2016-06-16 23:46:53 +0100 |
commit | 533c9fe36683102b1f0b8655d83393fa3d456651 (patch) | |
tree | 8189d67de3f136619152b57a85155f0c48de73e5 | |
parent | 77c306892bb9a948ac1c6675ab01f58b25efdd3f (diff) | |
download | binutils-gdb-users/palves/detach-gone-thread-wip.tar.gz |
Test for detach problemusers/palves/detach-gone-thread-wip
-rw-r--r-- | gdb/testsuite/gdb.threads/detach-gone-thread-fork.c | 71 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/detach-gone-thread-nofork.c | 49 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/detach-gone-thread.exp | 182 |
3 files changed, 302 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.threads/detach-gone-thread-fork.c b/gdb/testsuite/gdb.threads/detach-gone-thread-fork.c new file mode 100644 index 00000000000..ebd8413fc6f --- /dev/null +++ b/gdb/testsuite/gdb.threads/detach-gone-thread-fork.c @@ -0,0 +1,71 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 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 <pthread.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + +pthread_barrier_t barrier; + +#define NTHREADS 256 + +int globalvar = 1; + +void * +child_function (void *arg) +{ + pthread_barrier_wait (&barrier); + _exit (0); +} + +int +main () +{ + pthread_t threads[NTHREADS]; + int res; + int i; + pid_t pid; + + pid = fork (); + if (pid == -1) + return 1; + + if (pid == 0) + { + pthread_barrier_init (&barrier, NULL, NTHREADS + 1); + + for (i = 0; i < NTHREADS; i++) + res = pthread_create (&threads[i], NULL, child_function, NULL); + pthread_barrier_wait (&barrier); + exit (0); + } + else + { + int status, ret; + ret = waitpid (pid, &status, 0); + if (ret == -1) + exit (1); + if (WIFEXITED(status)) { + printf("exited, status=%d\n", WEXITSTATUS(status)); + } + if (WIFEXITED (status) || WIFSIGNALED (status)) + exit (0); + else + exit (1); + } +} diff --git a/gdb/testsuite/gdb.threads/detach-gone-thread-nofork.c b/gdb/testsuite/gdb.threads/detach-gone-thread-nofork.c new file mode 100644 index 00000000000..233de073d81 --- /dev/null +++ b/gdb/testsuite/gdb.threads/detach-gone-thread-nofork.c @@ -0,0 +1,49 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 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 <pthread.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + +pthread_barrier_t barrier; + +#define NTHREADS 256 + +void * +child_function (void *arg) +{ + pthread_barrier_wait (&barrier); + _exit (0); +} + +int +main () +{ + pthread_t threads[NTHREADS]; + int res; + int i; + pid_t pid; + + pthread_barrier_init (&barrier, NULL, NTHREADS + 1); + + for (i = 0; i < NTHREADS; i++) + res = pthread_create (&threads[i], NULL, child_function, NULL); + pthread_barrier_wait (&barrier); + exit (0); + +} diff --git a/gdb/testsuite/gdb.threads/detach-gone-thread.exp b/gdb/testsuite/gdb.threads/detach-gone-thread.exp new file mode 100644 index 00000000000..a3f438b3f8a --- /dev/null +++ b/gdb/testsuite/gdb.threads/detach-gone-thread.exp @@ -0,0 +1,182 @@ +# 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/>. + +standard_testfile $gdb_test_file_name-fork.c + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/$srcfile" "${binfile}" executable {debug}] != "" } { + return -1 +} + +clean_restart ${testfile} + +if ![runto_main] { + fail "Can't run to main" + return -1 +} + +# Check if the target is native. +proc check_native_target {test} { + global gdb_prompt + + gdb_test_multiple "maint print target-stack" $test { + -re " native .*$gdb_prompt $" { + pass $test + return 1 + } + -re "$gdb_prompt $" { + pass $test + } + } + + return 0 +} + +# Test that GDBserver exits. +proc test_server_exit {} { + global server_spawn_id + if ![info exists server_spawn_id] { + return + } + + set test "server exits" + gdb_expect { + -i $server_spawn_id + eof { + pass $test + wait -i $server_spawn_id + unset server_spawn_id + } + timeout { + fail "$test (timeout)" + } + } +} + +proc test_local_detach {} { + global testfile decimal + clean_restart ${testfile} + + if ![runto_main] { + fail "Can't run to main" + return -1 + } + + gdb_test_no_output "set detach-on-fork off" + gdb_test_no_output "set follow-fork-mode child" + + gdb_breakpoint "_exit" + gdb_continue_to_breakpoint "_exit" ".*_exit.*" + gdb_test_no_output "set confirm off" + gdb_test_no_output "delete" + gdb_test "detach" "Detaching from .*, process $decimal.*" + gdb_test "inferior 1" "\[Switching to inferior $decimal\].*" + # Make sure that detach works and that the parent process exited cleanly + gdb_test "detach" "Detaching from .*, process $decimal.*exited, status=0.*" +} + +proc test_local_checkpoint {} { + global testfile decimal + clean_restart ${testfile} + + if ![runto_main] { + fail "Can't run to main" + return -1 + } + + gdb_test_no_output "set detach-on-fork off" + gdb_test_no_output "set follow-fork-mode child" + gdb_test "checkpoint" + gdb_breakpoint "_exit" + gdb_continue_to_breakpoint "_exit" ".*_exit.*" + gdb_test_no_output "set confirm off" + gdb_test_no_output "delete" + gdb_test "detach" "Detaching from .*, process $decimal.*" + gdb_test "inferior 1" "\[Switching to inferior $decimal\].*" + # Make sure that detach works and that the parent process exited cleanly + gdb_test "detach" "Detaching from .*, process $decimal.*exited, status=0.*" +} + +proc test_local_watch {} { + global testfile decimal + clean_restart ${testfile} + + if ![runto_main] { + fail "Can't run to main" + return -1 + } + + gdb_test_no_output "set detach-on-fork off" + gdb_test_no_output "set follow-fork-mode child" + + gdb_breakpoint "_exit" + gdb_continue_to_breakpoint "_exit" ".*_exit.*" + gdb_test "watch globalvar" ".* watchpoint $decimal: globalvar" + gdb_test "si" + gdb_test_no_output "set confirm off" + gdb_test_no_output "delete" + gdb_test "detach" "Detaching from .*, process $decimal.*" + gdb_test "inferior 1" "\[Switching to inferior $decimal\].*" + # Make sure that detach works and that the parent process exited cleanly + gdb_test "detach" "Detaching from .*, process $decimal.*exited, status=0.*" +} + +proc test_remote_detach {} { + global testfile decimal gdb_prompt + clean_restart ${testfile} + + if ![runto_main] { + fail "Can't run to main" + return -1 + } + + # Test that GDBserver exits. + gdb_breakpoint "_exit" + gdb_continue_to_breakpoint "_exit" ".*_exit.*" + set test "detach" + gdb_test_multiple $test $test { + -re "Detaching from .*, process $decimal\r\nEnding remote debugging\.\r\n$gdb_prompt $" { + # This is what you get with "target remote". + pass $test + + # The server should exit now. + test_server_exit + } + -re "Detaching from .*, process $decimal\r\n$gdb_prompt $" { + pass $test + } + } +} + + +if { [check_native_target "Check if target is native"] } { + + test_local_detach + test_local_watch + #test_local_checkpoint +} else { + + set $srcfile $gdb_test_file_name-nofork.c + if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + return -1 + } + + clean_restart ${testfile} + + if ![runto_main] { + fail "Can't run to main" + return -1 + } + + test_remote_detach +} |