diff options
Diffstat (limited to 'gdb/testsuite/gdb.mi')
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-nsthrexec.exp | 101 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/nsthrexec.c | 48 |
2 files changed, 149 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.mi/mi-nsthrexec.exp b/gdb/testsuite/gdb.mi/mi-nsthrexec.exp new file mode 100644 index 0000000..9d48376 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-nsthrexec.exp @@ -0,0 +1,101 @@ +# Copyright 2009 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 that when a thread other than the main thread execs, and the +# main thread was stopped due to user request, the new incarnation of +# the main thread doesn't just silently stop at the first internal +# breakpoint (usually the _dl_debug_state breakpoint). + +# No exec event support in the remote protocol. +if { [is_remote target] } then { + continue +} + +load_lib mi-support.exp +set MIFLAGS "-i=mi" + +gdb_exit +if {[mi_gdb_start]} { + continue +} + +# +# Start here +# +set testfile "nsthrexec" +set srcfile "$testfile.c" +set binfile "$objdir/$subdir/mi-$testfile" + +set options [list debug incdir=$objdir] +if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $options] != "" } { + return -1 +} + +mi_gdb_reinitialize_dir $srcdir/$subdir +mi_gdb_load $binfile + +set supported 0 +send_gdb "-gdb-show non-stop\n" +gdb_expect { + -re ".*\\^done,value=\"off\",supported=\"(\[^\"\]+)\"\r\n$mi_gdb_prompt$" { + if { $expect_out(1,string) == "1" } { + set supported 1 + } + } + -re ".$mi_gdb_prompt$" { + } +} + +mi_gdb_test "-gdb-set non-stop 1" ".*" +mi_gdb_test "-gdb-set target-async 1" ".*" +detect_async + +if { [mi_run_to_main] < 0 } { + perror "mi-nsthrexec.exp tests suppressed" + continue +} + +mi_create_breakpoint thread_execler 2 keep thread_execler .* .* .* \ + "breakpoint at thread_execler" + +# All threads should stop, except the main thread. +mi_send_resuming_command "exec-continue --all" "resume all" +mi_expect_stop "breakpoint-hit" "thread_execler" "\[^\n\]*" "$srcfile" \ + "\[0-9\]*" {"" "disp=\"keep\""} "stop at thread_execler" + +mi_check_thread_states \ + {"running" "stopped"} \ + "thread state, execler stopped, main running" + +mi_gdb_test "200-exec-interrupt --thread 1" "200\\^done" "interrupt main thread" +mi_expect_interrupt "main thread interrupted" + +mi_check_thread_states {"stopped" "stopped"} "thread state, all stopped" + +# now that we know about all the threads, we can get rid of the breakpoints +mi_delete_breakpoints + +mi_create_breakpoint main 3 keep main .* .* .* \ + "breakpoint at main" + +# Now resume the execler thread. Eventually, it execs. +mi_send_resuming_command "exec-continue --thread 2" "resume execler thread" + +# Check that the main thread passes by the _dl_debug_state internal +# breakpoint without silently stopping. +mi_expect_stop "breakpoint-hit" "main" "\[^\n\]*" "$srcfile" \ + "\[0-9\]*" {"" "disp=\"keep\""} "stop at main after exec" + +mi_gdb_exit diff --git a/gdb/testsuite/gdb.mi/nsthrexec.c b/gdb/testsuite/gdb.mi/nsthrexec.c new file mode 100644 index 0000000..ec23535 --- /dev/null +++ b/gdb/testsuite/gdb.mi/nsthrexec.c @@ -0,0 +1,48 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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> + +static const char *image; + +void * +thread_execler (void *arg) +{ + /* Exec ourselves again. */ + if (execl (image, image, NULL) == -1) + { + perror ("execl"); + abort (); + } + + return NULL; +} + +int +main (int argc, char **argv) +{ + pthread_t thread; + + image = argv[0]; + + pthread_create (&thread, NULL, thread_execler, NULL); + pthread_join (thread, NULL); + + return 0; +} |