From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 92276 invoked by alias); 20 Jun 2016 11:47:20 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 92261 invoked by uid 89); 20 Jun 2016 11:47:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=watch 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; Mon, 20 Jun 2016 11:47:15 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DE35B80F6D; Mon, 20 Jun 2016 11:47:13 +0000 (UTC) Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u5KBlCpw010929; Mon, 20 Jun 2016 07:47:13 -0400 Subject: Re: [patch] aarch64: PR 19806: watchpoints: false negatives -> false positives To: Jan Kratochvil References: <20160606075945.GA19395@host1.jankratochvil.net> <86eg89w2sr.fsf@gmail.com> <48622de4-dc45-c48f-7172-495b669f2334@redhat.com> <86a8ixvx5k.fsf@gmail.com> <7fabd183-eb46-e916-77f2-f62d5c4e4ce7@redhat.com> <86oa7bvdi0.fsf@gmail.com> <4f4d2f70-3931-6467-37c7-f97f99ad5c63@redhat.com> <380b5288-f46f-3e20-c9c3-8cc8738ee322@redhat.com> <20160619182909.GA9883@host1.jankratochvil.net> Cc: Yao Qi , gdb-patches@sourceware.org From: Pedro Alves Message-ID: Date: Mon, 20 Jun 2016 11:47:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.1.1 MIME-Version: 1.0 In-Reply-To: <20160619182909.GA9883@host1.jankratochvil.net> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-SW-Source: 2016-06/txt/msg00323.txt.bz2 On 06/19/2016 07:29 PM, Jan Kratochvil wrote: > On Wed, 08 Jun 2016 20:46:35 +0200, Pedro Alves wrote: >> I thought of a case where this is the wrong thing to do. >> (Alternative below.) >> >> The same example as before: e.g., a machine that only supports >> watching 32-bit-aligned words. Then with: >> >> union >> { >> char buf[4]; >> uint32_t force_align; >> } global; >> >> (gdb) watch global.buf[1]; >> Hardware watchpoint 1 ... >> (gdb) watch global.buf[3]; >> Hardware watchpoint 2 ... >> >> ... if the program writes to global.buf[3], and the target >> reports a memory access to 'global.buf + 1' (because that's the >> first watchpoint in its own watchpoint list that overlaps >> the global.buf[0]..global.buf[3] range (what is really being >> watched)), gdb will believe that watchpoint 1 triggered, notice >> the value didn't change, and thus incorrectly ignore the watchpoint hit. > > Here if the program really does 'global.buf[3] = 0xff;' then it still does > work as despite GDB places watchpoint at &global.buf[0] for 4 bytes aarch64 > still reports the exact 1-byte location &global.buf[3]: > echo -e 'union { char buf[8]; unsigned long ul; } u; int main(void) {\n u.buf[3]=0xff;\n return 0; }'|gcc -Wall -g -x c -;./gdb -data-directory ./data-directory/ ./a.out -ex start -ex 'watch u.buf[1]' -ex 'watch u.buf[3]' -ex c -ex 'p u.buf[1]' -ex 'p u.buf[3]' > Hardware watchpoint 2: u.buf[1] > Hardware watchpoint 3: u.buf[3] > Continuing. > Hardware watchpoint 3: u.buf[3] > Old value = 0 '\000' > New value = 255 '\377' Sounds what would happen when gdbserver looks for the first watchpoint that overlaps the kernel-reported siginfo.si_addr trap address, it finds watchpoint 3 first. Which is entirely plausible because gdbserver actually iterates backwards: /* Check if the address matches any watched address. */ state = aarch64_get_debug_reg_state (pid_of (current_thread)); for (i = aarch64_num_wp_regs - 1; i >= 0; --i) { const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]); So I guess that if you manage to reverse the order of the watchpoints in gdbserver, gdbserver will find u.buf[1] as first overlapping watchpoint, and then we'd see what I described. Or if you reverse the iteration order in that for loop. Maybe just setting the watchpoint at buf[3] first would be sufficient. (gdb) watch global.buf[3]; Hardware watchpoint 1 ... (gdb) watch global.buf[1]; Hardware watchpoint 2 ... ... Thanks, Pedro Alves