diff options
author | Pedro Alves <palves@redhat.com> | 2008-10-15 19:15:34 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2008-10-15 19:15:34 +0000 |
commit | 1c5cfe8615a947f26ef1569f3af3017bb1c63899 (patch) | |
tree | 67c00221d017a285eaf67bc17815044541a57d9f /gdb/testsuite | |
parent | 41702f1b3391a34327b3fb4786b690583c1249b6 (diff) | |
download | gdb-1c5cfe8615a947f26ef1569f3af3017bb1c63899.zip gdb-1c5cfe8615a947f26ef1569f3af3017bb1c63899.tar.gz gdb-1c5cfe8615a947f26ef1569f3af3017bb1c63899.tar.bz2 |
gdb/
* breakpoint.c (breakpoint_init_inferior): Clean up the moribund
locations list.
(moribund_breakpoint_here_p): Record the moribund
location in the moribund_locations vector.
* breakpoint.h (moribund_breakpoint_here_p): Declare.
(displaced_step_fixup): Check if the breakpoint the thread was
trying to step over has been removed since having been placed in
the displaced stepping queue.
(adjust_pc_after_break): In non-stop mode, check for a moribund
breakpoint at the stop pc.
(handle_inferior_event): Don't retire moribund breakpoints on
TARGET_WAITKIND_IGNORE.
gdb/testsuite/
* gdb.mi/mi-nsmoribund.exp, gdb.mi/nsmoribund.c: New test.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r-- | gdb/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-nsmoribund.exp | 177 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/nsmoribund.c | 72 |
3 files changed, 253 insertions, 0 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 98c2188..1dd8d4b 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-10-15 Pedro Alves <pedro@codesourcery.com> + + * gdb.mi/mi-nsmoribund.exp, gdb.mi/nsmoribund.c: New test. + 2008-10-15 Denis Pilat <denis.pilat@st.com> * gdb.cp/mb-ctor.exp: Fix a typo. diff --git a/gdb/testsuite/gdb.mi/mi-nsmoribund.exp b/gdb/testsuite/gdb.mi/mi-nsmoribund.exp new file mode 100644 index 0000000..85e5138 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-nsmoribund.exp @@ -0,0 +1,177 @@ +# Copyright 2008 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/>. + +# This only works with native configurations +if {![isnative]} { + return +} + +load_lib mi-support.exp +set MIFLAGS "-i=mi" + +gdb_exit +if {[mi_gdb_start]} { + continue +} + +# +# Start here +# +set testfile "nsmoribund" +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 + +mi_gdb_test "200-break-insert -t main" ".*" + +set created "=thread-created,id=\"$decimal\"\r\n" +set running "\\*running,thread-id=\"$decimal\"\r\n" + +set notifs "($created)*($running)*" + +# Note: presently, we skip this test on non-native targets, +# so 'run' is OK. As soon as we start to run this on remote +# target, the logic from mi_run_cmd will have to be refactored. +send_gdb "-exec-run\n" +gdb_expect { + -re "\\^running\r\n$notifs$mi_gdb_prompt" { + } + -re "\\^error,msg=\"The target does not support running in non-stop mode.\"" { + verbose -log "Non-stop mode not supported, skipping all tests" + return + } + -re "\r\n$mi_gdb_prompt" { + perror "Cannot start target (unknown output after running)" + return -1 + } + timeout { + perror "Cannot start target (timeout)" + return -1 + } +} +mi_expect_stop "breakpoint-hit" main ".*" ".*" "\[0-9\]+" \ + { "" "disp=\"del\"" } "run to main" + +# Keep this in sync with THREADS in the the $srcfile. +set nthreads 10 + +# Set a breakpoint and let all threads hit it (except the main +# thread). + +set bkpt_line [gdb_get_line_number "set breakpoint here"] + +mi_create_breakpoint "$srcfile:$bkpt_line" 2 keep thread_function .* .* .* \ + "breakpoint at thread_function" + +mi_send_resuming_command "exec-continue --all" "resume all" +for {set i 0} {$i < $nthreads} {incr i} { + mi_expect_stop "breakpoint-hit" "thread_function" "\[^\n\]*" "$srcfile" \ + "\[0-9\]*" {"" "disp=\"keep\""} "stop $i" +} + +# All but the main thread should have hit it. + +mi_check_thread_states \ + {"running" "stopped" "stopped" "stopped" "stopped" "stopped" "stopped" "stopped" "stopped" "stopped" "stopped"} \ + "thread state: all stopped except the main thread" + +# Select a stopped thread to make sure we're able to delete +# breakpoints +mi_gdb_test "-thread-select 5" "\\^done.*" "select thread 5" + +# Now that we know about all the threads, we can get rid of +# breakpoint. +mi_delete_breakpoints + +# Recreate the same breakpoint, but this time, specific to thread 5. +mi_create_breakpoint "-p 5 $srcfile:$bkpt_line" 3 keep thread_function .* .* .* \ + "thread specific breakpoint at thread_function" + +# Resume all threads. Only thread 5 should report a stop. + +set running_re "" +for {set i $nthreads} {$i > 0} {incr i -1} { + set running_re "$running_re\\*running,thread-id=\"$decimal\"\r\n" +} + +send_gdb "-exec-continue --all\n" +gdb_expect { + -re ".*$running_re$mi_gdb_prompt" { + pass "resume all, thread specific breakpoint" + } + timeout { + fail "resume all, thread specific breakpoint (timeout)" + } +} + +mi_expect_stop "breakpoint-hit" "thread_function" "\[^\n\]*" "$srcfile" \ + "\[0-9\]*" {"" "disp=\"keep\""} "hit thread specific breakpoint" + +# All threads except both thread 5 (and the main thread) should now be +# repeatedly hitting the thread specific breakpoint and stepping over +# it transparently. These are internal events, so the frontend should +# see those threads as running. + +mi_check_thread_states \ + {"running" "running" "running" "running" "stopped" "running" "running" "running" "running"} \ + "thread state: all running except the breakpoint thread" + +# Get rid of the breakpoint while the other threads are stepping over +# it, and tell all threads to exit. The program should exit +# gracefully shortly. Send all commands in a row, since if something +# goes wrong with moribund locations support or displaced stepping (or +# a target bug if it can step over breakpoints itself), a spurious +# SIGTRAP/SIGSEGV can come at any time after deleting the breakpoint. + +send_gdb "102-break-delete\n" +send_gdb "print done = 1\n" +send_gdb "103-exec-continue --all\n" + +gdb_expect { + -re "\\*stopped,reason=\"exited-normally\"" { + pass "resume all, program exited normally" + } + -re "\\*stopped" { + fail "unexpected stop" + } + timeout { + fail "resume all, waiting for program exit (timeout)" + } +} + +mi_gdb_exit diff --git a/gdb/testsuite/gdb.mi/nsmoribund.c b/gdb/testsuite/gdb.mi/nsmoribund.c new file mode 100644 index 0000000..aa41dbd --- /dev/null +++ b/gdb/testsuite/gdb.mi/nsmoribund.c @@ -0,0 +1,72 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2002, 2003, 2004, 2007, 2008 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/>. + + This file is based on schedlock.c. */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <pthread.h> + +int THREADS = 10; +unsigned int *args; +volatile int done = 0; + +void * +thread_function (void *arg) +{ + int my_number = (long) arg; + volatile int *myp = (volatile int *) &args[my_number]; + + /* Don't run forever. Run just short of it :) */ + while (*myp > 0 && !done) + { + (*myp)++; /* set breakpoint here */ + } + + if (done) + usleep (100); /* Some time to make sure we don't mask any bad + SIGTRAP handling. */ + + pthread_exit (NULL); +} + +int +main (int argc, char **argv) +{ + int res; + pthread_t *threads; + void *thread_result; + long i = 0; + + threads = malloc (THREADS * sizeof (pthread_t)); + args = malloc (THREADS * sizeof (unsigned int)); + + for (i = 0; i < THREADS; i++) + { + args[i] = 1; /* Init value. */ + res = pthread_create (&threads[i], + NULL, + thread_function, + (void *) i); + } + + for (i = 0; i < THREADS; i++) + pthread_join (threads[i], &thread_result); + + exit(EXIT_SUCCESS); +} |