From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 91066 invoked by alias); 29 Aug 2018 15:56:08 -0000 Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org Received: (qmail 91057 invoked by uid 89); 29 Aug 2018 15:56:08 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-1.0 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,UNSUBSCRIBE_BODY autolearn=no version=3.3.2 spammy=cooperation X-HELO: mx1.redhat.com Received: from mx3-rdu2.redhat.com (HELO mx1.redhat.com) (66.187.233.73) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 29 Aug 2018 15:56:06 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 501004023337; Wed, 29 Aug 2018 15:56:05 +0000 (UTC) Received: from [127.0.0.1] (ovpn04.gateway.prod.ext.ams2.redhat.com [10.39.146.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2F26C2166B41; Wed, 29 Aug 2018 15:56:04 +0000 (UTC) Subject: Re: gdb requires watchpoints to fire after the write To: Joel Brobecker , Simon Marchi References: <3833782b96d47551263798eb78f448bd@polymtl.ca> <20180829154739.GB2521@adacore.com> Cc: Tim Newsome , gdb From: Pedro Alves Message-ID: <2e51a311-1cdb-a94e-b38f-1c19171aa362@redhat.com> Date: Wed, 29 Aug 2018 15:56:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 MIME-Version: 1.0 In-Reply-To: <20180829154739.GB2521@adacore.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-SW-Source: 2018-08/txt/msg00050.txt.bz2 On 08/29/2018 04:47 PM, Joel Brobecker wrote: >> I don't have experience with many different architectures, but as far as I >> know, the expectation of the GDB is that the watchpoint is reported after >> the write. Otherwise it wouldn't need to save the value of the watched >> expression. That's also how software watchpoints seem to work. >> >> The easiest way to deal with this would be to match GDB's expectation. But >> if you really prefer the behavior of reporting the watchpoint before the >> event, I suppose it's always possible to teach GDB about this, but it's a >> less trivial task. Especially that when you GDB evaluates whether the watch >> expression has changed value, it would need to consider the not-yet-written >> value in memory. >> >> I'm also curious to know if other architectures work in this way (report the >> event before the write actually take place). > > I seem to remember some architectures having different behaviors, > and so we have a couple of entry points in GDB. For architecture-specific > settings, we have gdbarch_have_nonsteppable_watchpoint. For target-specific > settings, you would use target_have_steppable_watchpoint. (IIRC) Yes, the key bit is this here in infrun.c: /* If necessary, step over this watchpoint. We'll be back to display it in a moment. */ if (stopped_by_watchpoint && (target_have_steppable_watchpoint || gdbarch_have_nonsteppable_watchpoint (gdbarch))) { /* At this point, we are stopped at an instruction which has attempted to write to a piece of memory under control of a watchpoint. The instruction hasn't actually executed yet. If we were to evaluate the watchpoint expression now, we would get the old value, and therefore no change would seem to have occurred. In order to make watchpoints work `right', we really need to complete the memory write, and then evaluate the watchpoint expression. We do this by single-stepping the target. It may not be necessary to disable the watchpoint to step over it. For example, the PA can (with some kernel cooperation) single step over a watchpoint without disabling the watchpoint. It is far more common to need to disable a watchpoint to step the inferior over it. If we have non-steppable watchpoints, we must disable the current watchpoint; it's simplest to disable all watchpoints. Any breakpoint at PC must also be stepped over -- if there's one, it will have already triggered before the watchpoint triggered, and we either already reported it to the user, or it didn't cause a stop and we called keep_going. In either case, if there was a breakpoint at PC, we must be trying to step past it. */ ecs->event_thread->stepping_over_watchpoint = 1; keep_going (ecs); return; } Thanks, Pedro Alves