2007-04-28 Jan Kratochvil * infrun.c (handle_inferior_event): Handle (STEPPING_PAST_SINGLESTEP_BREAKPOINT && !SINGLESTEP_BREAKPOINTS_INSERTED_P). 2007-04-28 Jan Kratochvil * gdb.threads/atomic-step-mass-join.c, gdb.threads/atomic-step-mass-join.exp: New files. diff -u -rup gdb-6.6-orig/gdb/infrun.c gdb-6.6/gdb/infrun.c --- gdb-6.6-orig/gdb/infrun.c 2006-10-18 18:56:13.000000000 +0200 +++ gdb-6.6/gdb/infrun.c 2007-04-28 19:23:08.000000000 +0200 @@ -1561,10 +1561,17 @@ handle_inferior_event (struct execution_ if (stepping_past_singlestep_breakpoint) { - gdb_assert (SOFTWARE_SINGLE_STEP_P () - && singlestep_breakpoints_inserted_p); - gdb_assert (ptid_equal (singlestep_ptid, ecs->ptid)); - gdb_assert (!ptid_equal (singlestep_ptid, saved_singlestep_ptid)); + gdb_assert (SOFTWARE_SINGLE_STEP_P ()); + /* SINGLESTEP_BREAKPOINTS_INSERTED_P is 0 if the another thread which hit + the singlestep breakpoint intended for SAVED_SINGLESTEP_PTID is not + right now at the atomic sequence. SINGLESTEP_PTID is not defined in + such case. SINGLESTEP_BREAKPOINTS_INSERTED_P is 1 when both the + SAVED_SINGLESTEP_PTID thread and the SINGLESTEP_PTID thread skip over + an atomic sequence, possibly a different one. */ + gdb_assert (!singlestep_breakpoints_inserted_p + || ptid_equal (singlestep_ptid, ecs->ptid)); + gdb_assert (!singlestep_breakpoints_inserted_p + || !ptid_equal (singlestep_ptid, saved_singlestep_ptid)); stepping_past_singlestep_breakpoint = 0; @@ -1575,9 +1582,13 @@ handle_inferior_event (struct execution_ { if (debug_infrun) fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n"); - /* Pull the single step breakpoints out of the target. */ - (void) SOFTWARE_SINGLE_STEP (0, 0); - singlestep_breakpoints_inserted_p = 0; + + if (singlestep_breakpoints_inserted_p) + { + /* Pull the single step breakpoints out of the target. */ + (void) SOFTWARE_SINGLE_STEP (0, 0); + singlestep_breakpoints_inserted_p = 0; + } ecs->random_signal = 0; diff -u -rup gdb-6.6-orig/gdb/testsuite/gdb.threads/atomic-step-mass-join.c gdb-6.6/gdb/testsuite/gdb.threads/atomic-step-mass-join.c --- gdb-6.6-orig/gdb/testsuite/gdb.threads/atomic-step-mass-join.c 2007-04-28 19:43:46.000000000 +0200 +++ gdb-6.6/gdb/testsuite/gdb.threads/atomic-step-mass-join.c 2007-04-28 19:24:15.000000000 +0200 @@ -0,0 +1,57 @@ +/* Test case for stepping over RISC atomic code constructs. + + Copyright 2007 + free software foundation, inc. + + This file is part of GDB. + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include + +static volatile int var; + +static void *start (void *arg) +{ + /* Do not start quitting before all the threads were spawn. */ + sleep (5); + + return arg; +} + +#define LENGTH(x) (sizeof (x) / sizeof (x)[0]) + +int main (void) +{ + pthread_t thread[20]; + int i, j; + + var = 0; + for (j = 0; j < LENGTH (thread); j++) + { + i = pthread_create (&thread[j], NULL, start, NULL); /* _create_ */ + assert (i == 0); + } + for (j = 0; j < LENGTH (thread); j++) + { + i = pthread_join (thread[j], NULL); /* _delete_ */ + assert (i == 0); + } + + return 0; /* _quit_ */ +} diff -u -rup gdb-6.6-orig/gdb/testsuite/gdb.threads/atomic-step-mass-join.exp gdb-6.6/gdb/testsuite/gdb.threads/atomic-step-mass-join.exp --- gdb-6.6-orig/gdb/testsuite/gdb.threads/atomic-step-mass-join.exp 2007-04-28 19:43:46.000000000 +0200 +++ gdb-6.6/gdb/testsuite/gdb.threads/atomic-step-mass-join.exp 2007-04-28 19:42:25.000000000 +0200 @@ -0,0 +1,93 @@ +# atomic-step-mass-join.exp -- Test case for stepping over RISC atomic code constructs. +# Copyright (C) 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +set testfile atomic-step-mass-join +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if [istarget "*-*-linux"] then { + set target_cflags "-D_MIT_POSIX_THREADS" +} else { + set target_cflags "" +} + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir + +gdb_load ${binfile} +if ![runto_main] then { + fail "Can't run to main" + return 0 +} + +# With a watchpoint we would crash on pthread_create(3): +# Program received signal SIGSTOP, Stopped (signal). +# [Switching to Thread 4160681152 (LWP 979)] +# 0x0f55c368 in clone () from /lib/libc.so.6 +# Still it is not applicable so far due to: +# [New Thread 4139709632 (LWP 9022)]^M +# 0x0f354a28 in __nptl_create_event () from /lib/libpthread.so.0^M +# ptrace: No such process.^M +#gdb_test "handle SIGSTOP nostop noprint pass" \ +# ".*SIGSTOP +No\tNo\tYes\t+Stopped \\(signal\\)" \ +# "Disown SIGSTOP" + +set line [gdb_get_line_number "_delete_"] +gdb_test "tbreak $line" \ + "Breakpoint (\[0-9\]+) at .*$srcfile, line $line\..*" \ + "set breakpoint at delete" +gdb_test "c" \ + ".*/\\* _delete_ \\*/.*" \ + "run till _delete_" + +# Without a software watchpoint no single-stepping would be used. +set test "Start (software) watchpoint" +gdb_test_multiple "watch var" $test { + -re "Watchpoint \[0-9\]+: var.*$gdb_prompt $" { + pass $test + } + -re "Hardware watchpoint \[0-9\]+: var.*$gdb_prompt $" { + # We do not test the goal but still the whole testcase should pass. + unsupported $test + } +} + +###gdb_test "set debug infrun 1" "" + +set line [gdb_get_line_number "_quit_"] +gdb_test "tbreak $line" \ + "Breakpoint \[0-9\]+ at .*$srcfile, line $line\..*" \ + "set breakpoint at _quit_" +set timeout_old $timeout +# 20 threads may take about 45 seconds. */ +set timeout 180 +gdb_test "c" \ + ".*/\\* _quit_ \\*/.*" \ + "run till _quit_" +set timeout $timeout_old + +gdb_test "c" \ + ".*Program exited normally\\." \ + "run till program exit"