From patchwork Tue Feb 27 18:07:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Arnez X-Patchwork-Id: 26109 Received: (qmail 9415 invoked by alias); 27 Feb 2018 18:07:34 -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 9296 invoked by uid 89); 27 Feb 2018 18:07:34 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=H*o:Research X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 27 Feb 2018 18:07:32 +0000 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w1RI66vs142743 for ; Tue, 27 Feb 2018 13:07:31 -0500 Received: from e06smtp13.uk.ibm.com (e06smtp13.uk.ibm.com [195.75.94.109]) by mx0a-001b2d01.pphosted.com with ESMTP id 2gda6kp888-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 27 Feb 2018 13:07:30 -0500 Received: from localhost by e06smtp13.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 27 Feb 2018 18:07:28 -0000 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp13.uk.ibm.com (192.168.101.143) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 27 Feb 2018 18:07:26 -0000 Received: from d06av24.portsmouth.uk.ibm.com (mk.ibm.com [9.149.105.60]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w1RI7Q9o32243830 for ; Tue, 27 Feb 2018 18:07:26 GMT Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 004ED42045 for ; Tue, 27 Feb 2018 17:59:57 +0000 (GMT) Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C6E3F4203F for ; Tue, 27 Feb 2018 17:59:56 +0000 (GMT) Received: from oc1027705133.ibm.com (unknown [9.152.212.169]) by d06av24.portsmouth.uk.ibm.com (Postfix) with ESMTPS for ; Tue, 27 Feb 2018 17:59:56 +0000 (GMT) From: Andreas Arnez To: gdb-patches@sourceware.org Subject: [PATCH] Fix watching structs in C++ Date: Tue, 27 Feb 2018 19:07:23 +0100 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 18022718-0012-0000-0000-000005B61673 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18022718-0013-0000-0000-00001932229E Message-Id: X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-02-27_09:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1802270223 X-IsSubscribed: yes Some of the watchpoint logic depends on the fact that the head of the value chain represents the user-specified value to watch. Thus no additional values should be added to the value chain after that. However, this may happen in gnuv3_rrti_type, where value_addr is invoked. If no RTTI is found, then the pointer value built by value_addr, rather than the original value, stays in front of the value chain. With such a "polluted" value chain the watchpoint logic does not recognize when the user intended to watch a struct, and can_use_hardware_watchpoint returns zero. Instead of a hardware watchpoint, a software watchpoint will then be set for no apparent reason. This is fixed by adding an early exit to gnuv3_rtti_type when the input value is not a dynamic class object. gdb/testsuite/ChangeLog: * gdb.cp/watch-cp.cc: New test. * gdb.cp/watch-cp.exp: New file. gdb/ChangeLog: * gnu-v3-abi.c (gnuv3_rtti_type): Add early exit if the given value is not a dynamic class object. --- gdb/gnu-v3-abi.c | 5 +++-- gdb/testsuite/gdb.cp/watch-cp.cc | 28 ++++++++++++++++++++++++++++ gdb/testsuite/gdb.cp/watch-cp.exp | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 gdb/testsuite/gdb.cp/watch-cp.cc create mode 100644 gdb/testsuite/gdb.cp/watch-cp.exp diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c index 0965846ce6..859187f2e9 100644 --- a/gdb/gnu-v3-abi.c +++ b/gdb/gnu-v3-abi.c @@ -299,8 +299,9 @@ gnuv3_rtti_type (struct value *value, LONGEST offset_to_top; const char *atsign; - /* We only have RTTI for class objects. */ - if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT) + /* We only have RTTI for dynamic class objects. */ + if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT + || !gnuv3_dynamic_class (values_type)) return NULL; /* Determine architecture. */ diff --git a/gdb/testsuite/gdb.cp/watch-cp.cc b/gdb/testsuite/gdb.cp/watch-cp.cc new file mode 100644 index 0000000000..6954e854c9 --- /dev/null +++ b/gdb/testsuite/gdb.cp/watch-cp.cc @@ -0,0 +1,28 @@ +/* Copyright 2018 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 . */ + +/* A class that does not have RTTI and is small enough to fit in a + hardware watchpoint on all targets. */ +class smallstuff { public: int n; }; + +smallstuff watchme[5]; + +int +main () +{ + for (int i = 0; i < sizeof (watchme) / sizeof (watchme[0]); i++) + watchme[i].n = i; + return 0; +} diff --git a/gdb/testsuite/gdb.cp/watch-cp.exp b/gdb/testsuite/gdb.cp/watch-cp.exp new file mode 100644 index 0000000000..bdf0f13886 --- /dev/null +++ b/gdb/testsuite/gdb.cp/watch-cp.exp @@ -0,0 +1,35 @@ +# Copyright 2018 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 . + +if { [skip_cplus_tests] || [skip_hw_watchpoint_tests]} { continue } + +standard_testfile .cc + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} { + return -1 +} + +if ![runto_main] then { + perror "couldn't run to main" + continue +} + +gdb_test "watch watchme\[3\]" "atchpoint .*: watchme.*" "set watchpoint" + +# Verify that a hardware watchpoint is used. +gdb_test "info watchpoints" " hw watchpoint .* watchme.*" + +# Now see whether it actually works. +gdb_test "continue" "Hardware watchpoint .*New value = \\{n = 3\\}.*"