From patchwork Tue Sep 16 13:18:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 2859 Received: (qmail 357 invoked by alias); 16 Sep 2014 13:18:38 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 344 invoked by uid 89); 16 Sep 2014 13:18:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.1 required=5.0 tests=AWL, BAYES_50, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS, UNSUBSCRIBE_BODY autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 16 Sep 2014 13:18:35 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8GDIYJO017865 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 16 Sep 2014 09:18:34 -0400 Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8GDIWUL026339 for ; Tue, 16 Sep 2014 09:18:33 -0400 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [pushed] Add test to make sure GDB knows which "kind" of watchpoint the target has Date: Tue, 16 Sep 2014 14:18:32 +0100 Message-Id: <1410873512-762-1-git-send-email-palves@redhat.com> This adds a test that makes sure GDB knows whether the target has continuable, or non-continuable watchpoints. That is, the test confirms that GDB presents a watchpoint value change at the first instruction right after the instruction that changes memory. gdb/testsuite/ChangeLog: 2014-09-16 Pedro Alves * gdb.base/watchpoint-stops-at-right-insn.c: New file. * gdb.base/watchpoint-stops-at-right-insn.exp: New file. --- gdb/testsuite/ChangeLog | 5 + .../gdb.base/watchpoint-stops-at-right-insn.c | 33 ++++ .../gdb.base/watchpoint-stops-at-right-insn.exp | 177 +++++++++++++++++++++ 3 files changed, 215 insertions(+) create mode 100644 gdb/testsuite/gdb.base/watchpoint-stops-at-right-insn.c create mode 100644 gdb/testsuite/gdb.base/watchpoint-stops-at-right-insn.exp diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 361c819..c2588d3 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2014-09-16 Pedro Alves + * gdb.base/watchpoint-stops-at-right-insn.c: New file. + * gdb.base/watchpoint-stops-at-right-insn.exp: New file. + +2014-09-16 Pedro Alves + * config/vx.exp, config/vxworks.exp, config/vxworks29k.exp: Delete files. * gdb.base/a2-run.exp: Remove all code guarded by istarget diff --git a/gdb/testsuite/gdb.base/watchpoint-stops-at-right-insn.c b/gdb/testsuite/gdb.base/watchpoint-stops-at-right-insn.c new file mode 100644 index 0000000..005d63f --- /dev/null +++ b/gdb/testsuite/gdb.base/watchpoint-stops-at-right-insn.c @@ -0,0 +1,33 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2014 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 . */ + +volatile int global; + +void +set_global (int val) +{ + global = val; +} + +int +main (void) +{ + set_global (1); + set_global (2); + + return 0; +} diff --git a/gdb/testsuite/gdb.base/watchpoint-stops-at-right-insn.exp b/gdb/testsuite/gdb.base/watchpoint-stops-at-right-insn.exp new file mode 100644 index 0000000..9ad6080 --- /dev/null +++ b/gdb/testsuite/gdb.base/watchpoint-stops-at-right-insn.exp @@ -0,0 +1,177 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2014 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 . + +# This file is part of the gdb testsuite. + +# Test that GDB presents a hardware watchpoint stop at the first +# instruction right after the instruction that changes memory. +# +# Some targets trigger a hardware watchpoint after the instruction +# that wrote memory executes, thus with the memory already changed and +# the PC pointing to the instruction after the instruction that wrote +# to memory. These targets are said to have "continuable" +# watchpoints, referring to the fact that to make progress after the +# watchpoint triggers, GDB just needs to continue the target. +# +# Other targets trigger a hardware watchpoint at the instruction which +# has attempted to write to the piece of memory under control of the +# watchpoint, with the instruction actually not executed yet. To be +# able to check whether the watched value changed, GDB needs to +# complete the memory write, single-stepping the target once. These +# targets are said to have "non-continuable" watchpoints. +# +# This test makes sure that GDB knows which kind of watchpoint the +# target has, using this sequence of steps: +# +# 1 - run to main +# +# 2 - set a software watchpoint +# +# 3 - continue until watchpoint triggers +# +# 4 - the PC now points to the instruction right after the instruction +# that actually caused the memory write. So this is the address a +# hardware watchpoint should present the stop to the user too. +# Store the PC address. +# +# 5 - replace the software watchpoint by a hardware watchpoint +# +# 6 - continue until hardware watchpoint triggers +# +# 7 - the PC must point to the same address the software watchpoint +# triggered at. +# +# If the target has continuable watchpoints, but GDB thinks it has +# non-continuable watchpoints, GDB will stop the inferior two +# instructions after the watched value change, rather than at the next +# instruction. +# +# If the target has non-continuable watchpoints, while GDB thinks it +# has continuable watchpoints, GDB will see a watchpoint trigger, +# notice no value changed, and immediatly continue the target. Now, +# either the target manages to step-over the watchpoint transparently, +# and GDB thus fails to present to value change to the user, or, the +# watchpoint will keep re-triggering, with the program never making +# any progress. + +standard_testfile + +# No use testing this if we can't use hardware watchpoints. +if {[target_info exists gdb,no_hardware_watchpoints]} { + return -1 +} + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { + untested ${testfile}.exp + return -1 +} + +if { ![runto main] } then { + fail "run to main" + return +} + +# Get the current PC. TEST is used as test prefix. + +proc get_pc {test} { + global hex gdb_prompt + + set addr "" + gdb_test_multiple "p /x \$pc" "$test" { + -re " = ($hex).*$gdb_prompt $" { + set addr $expect_out(1,string) + pass "$test" + } + } + + return $addr +} + +# So we get an immediate warning/error if the target doesn't support a +# given watchpoint type. +gdb_test_no_output "set breakpoint always-inserted on" + +set hw_watchpoints_supported 0 + +set test "set probe hw watchpoint" +gdb_test_multiple "watch global" $test { + -re "You may have requested too many.*$gdb_prompt $" { + pass $test + } + -re "Target does not support.*$gdb_prompt $" { + pass $test + } + -re "$gdb_prompt $" { + pass $test + set hw_watchpoints_supported 1 + } +} + +if {!$hw_watchpoints_supported} { + unsupported "no hw watchpoints support" + return +} + +delete_breakpoints + +proc test {always_inserted} { + global srcfile binfile + + with_test_prefix "always-inserted $always_inserted" { + + clean_restart $binfile + + if { ![runto main] } then { + fail "run to main" + return + } + + # Force use of software watchpoints. + gdb_test_no_output "set can-use-hw-watchpoints 0" + + gdb_test "watch global" \ + "Watchpoint .*: global" \ + "set software watchpoint on global variable" + + gdb_test "continue" \ + "Watchpoint .*: global.*Old value = 0.*New value = 1.*set_global \\(val=1\\).*$srcfile.*" \ + "software watchpoint triggers" + + set sw_watch_pc [get_pc "get sw watchpoint PC"] + + delete_breakpoints + + # Allow hardware watchpoints again. + gdb_test_no_output "set can-use-hw-watchpoints 1" + + gdb_test "watch global" \ + "Hardware watchpoint .*: global" \ + "set hardware watchpoint on global variable" + + gdb_test "continue" \ + "Hardware watchpoint .*: global.*Old value = 1.*New value = 2.*set_global \\(val=2\\).*$srcfile.*" \ + "hardware watchpoint triggers" + + set hw_watch_pc [get_pc "get hw watchpoint PC"] + + gdb_assert {$sw_watch_pc == $sw_watch_pc} "hw watchpoint stops at right instruction" + } +} + +foreach always_inserted {"off" "on" } { + test $always_inserted +}