summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine Tremblay <antoine.tremblay@ericsson.com>2016-06-16 23:46:53 +0100
committerAntoine Tremblay <antoine.tremblay@ericsson.com>2016-06-16 23:46:53 +0100
commit533c9fe36683102b1f0b8655d83393fa3d456651 (patch)
tree8189d67de3f136619152b57a85155f0c48de73e5
parent77c306892bb9a948ac1c6675ab01f58b25efdd3f (diff)
downloadbinutils-gdb-users/palves/detach-gone-thread-wip.tar.gz
-rw-r--r--gdb/testsuite/gdb.threads/detach-gone-thread-fork.c71
-rw-r--r--gdb/testsuite/gdb.threads/detach-gone-thread-nofork.c49
-rw-r--r--gdb/testsuite/gdb.threads/detach-gone-thread.exp182
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
+}