From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8226 invoked by alias); 17 Apr 2012 21:07:34 -0000 Received: (qmail 8210 invoked by uid 22791); 17 Apr 2012 21:07:32 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 17 Apr 2012 21:06:59 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q3HL6tV4003058 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 17 Apr 2012 17:06:55 -0400 Received: from host2.jankratochvil.net (ovpn-116-17.ams2.redhat.com [10.36.116.17]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q3HL6lp4002719 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 17 Apr 2012 17:06:50 -0400 Date: Tue, 17 Apr 2012 21:15:00 -0000 From: Jan Kratochvil To: Hui Zhu Cc: gdb-patches@sourceware.org Subject: Re: [PATCH] breakpoint remove fail handle bug fix Message-ID: <20120417210647.GA21059@host2.jankratochvil.net> References: <4F8549BC.3050003@mentor.com> <20120411203549.GA4715@host2.jankratochvil.net> <4F863B12.2040304@mentor.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4F863B12.2040304@mentor.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes 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 X-SW-Source: 2012-04/txt/msg00515.txt.bz2 On Thu, 12 Apr 2012 04:16:50 +0200, Hui Zhu wrote: > But it didn't handle the issue when the target is remote. [...] > (gdb) c & > Continuing. > (gdb) d > Delete all breakpoints? (y or n) y > Cannot execute this command while the target is running. This is because you did not turn on non-stop mode: remote.c: if (!non_stop && target_can_async_p () && rs->waiting_for_stop_reply) error (_("Cannot execute this command while the target is running.")); It works then, gdbserver has this bug already fixed. Just I find it a loss of time fixing linux-nat which should get obsoleted by gdbserver anyway so posting this patch+testcase just FYI. Regards, Jan diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index ac1a0ea..299b3ca 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -4494,9 +4494,9 @@ linux_nat_make_corefile_notes (bfd *obfd, int *note_size) } /* Implement the to_xfer_partial interface for memory reads using the /proc - filesystem. Because we can use a single read() call for /proc, this - can be much more efficient than banging away at PTRACE_PEEKTEXT, - but it doesn't support writes. */ + filesystem. Because we can use a single read or write call for /proc, this + can be much more efficient than banging away at PTRACE_PEEKTEXT or + PTRACE_POKETEXT. */ static LONGEST linux_proc_xfer_partial (struct target_ops *ops, enum target_object object, @@ -4508,29 +4508,35 @@ linux_proc_xfer_partial (struct target_ops *ops, enum target_object object, int fd; char filename[64]; - if (object != TARGET_OBJECT_MEMORY || !readbuf) - return 0; - - /* Don't bother for one word. */ - if (len < 3 * sizeof (long)) + if (object != TARGET_OBJECT_MEMORY) return 0; /* We could keep this file open and cache it - possibly one per thread. That requires some juggling, but is even faster. */ sprintf (filename, "/proc/%d/mem", PIDGET (inferior_ptid)); - fd = open (filename, O_RDONLY | O_LARGEFILE); + fd = open (filename, (readbuf ? O_RDONLY : O_WRONLY) | O_LARGEFILE); if (fd == -1) return 0; - /* If pread64 is available, use it. It's faster if the kernel + /* If pread64 or pwrite64 is available, use it. It's faster if the kernel supports it (only one syscall), and it's 64-bit safe even on 32-bit platforms (for instance, SPARC debugging a SPARC64 application). */ + if ((readbuf != NULL +#ifdef HAVE_PREAD64 + && (pread64 (fd, readbuf, len, offset) != len) +#else + && (lseek (fd, offset, SEEK_SET) == -1 || read (fd, readbuf, len) != len) +#endif + ) + || (writebuf != NULL #ifdef HAVE_PREAD64 - if (pread64 (fd, readbuf, len, offset) != len) + && (pwrite64 (fd, writebuf, len, offset) != len) #else - if (lseek (fd, offset, SEEK_SET) == -1 || read (fd, readbuf, len) != len) + && (lseek (fd, offset, SEEK_SET) == -1 + || write (fd, writebuf, len) != len) #endif + )) ret = 0; else ret = len; @@ -4759,13 +4765,24 @@ linux_xfer_partial (struct target_ops *ops, enum target_object object, offset &= ((ULONGEST) 1 << addr_bit) - 1; } - xfer = linux_proc_xfer_partial (ops, object, annex, readbuf, writebuf, - offset, len); + /* Use more expensive linux_proc_xfer_partial only for larger transfers. */ + if (len >= 3 * sizeof (long)) + { + xfer = linux_proc_xfer_partial (ops, object, annex, readbuf, writebuf, + offset, len); + if (xfer != 0) + return xfer; + } + + xfer = super_xfer_partial (ops, object, annex, readbuf, writebuf, + offset, len); if (xfer != 0) return xfer; - return super_xfer_partial (ops, object, annex, readbuf, writebuf, - offset, len); + /* PTRACE_* of super_xfer_partial may not work if the inferior is running. + linux_proc_xfer_partial still may work in such case. */ + return linux_proc_xfer_partial (ops, object, annex, readbuf, writebuf, + offset, len); } static void diff --git a/gdb/testsuite/gdb.base/async-breakpoint.c b/gdb/testsuite/gdb.base/async-breakpoint.c new file mode 100644 index 0000000..3cdb0c1 --- /dev/null +++ b/gdb/testsuite/gdb.base/async-breakpoint.c @@ -0,0 +1,37 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2012 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 . */ + +static volatile v; + +static int +func (void) +{ + return ++v; +} + +static volatile int stopme; + +int +main (void) +{ + int timeout = 60 * 10; + + while (!stopme && timeout-- > 0) + usleep (1000000 / 10); + + return func (); +} diff --git a/gdb/testsuite/gdb.base/async-breakpoint.exp b/gdb/testsuite/gdb.base/async-breakpoint.exp new file mode 100644 index 0000000..d2469cf --- /dev/null +++ b/gdb/testsuite/gdb.base/async-breakpoint.exp @@ -0,0 +1,59 @@ +# Copyright (C) 2012 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 . + +set testfile async-breakpoint + +# Required for non-stop. +if ![support_displaced_stepping] { + unsupported "displaced stepping" + return -1 +} + +if { [prepare_for_testing ${testfile}.exp ${testfile}] } { + return -1 +} + +gdb_test_no_output "set target-async on" + +# Required for remote targets due to: +# Cannot execute this command while the target is running. +# Required also for local mode as GDB does not insert breakpoints otherwise. +gdb_test_no_output "set non-stop on" + +if ![runto_main] then { + return 0 +} + +delete_breakpoints + +gdb_breakpoint "main" + +gdb_test "continue &" {Continuing\.} + +# FAIL was: warning: Error removing breakpoint 1 +gdb_test_no_output {delete $bpnum} + +# FAIL was: Cannot access memory at address 0x40057c +gdb_breakpoint "func" + +set test "set variable stopme=1" +gdb_test_multiple $test $test { + -re "$gdb_prompt " { + exp_continue + } + -re "Breakpoint \[0-9\]+, func \\(\\) at " { + pass $test + } +} diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp index ee66e48..557e86d 100644 --- a/gdb/testsuite/lib/gdbserver-support.exp +++ b/gdb/testsuite/lib/gdbserver-support.exp @@ -47,6 +47,9 @@ proc gdb_target_cmd { targetname serialport } { global gdb_prompt + # Do not use ending anchor for "$gdb_prompt $" as in async mode we may get + # also notification of the stopped target. + set serialport_re [string_to_regexp $serialport] for {set i 1} {$i <= 3} {incr i} { send_gdb "target $targetname $serialport\n" @@ -58,26 +61,26 @@ proc gdb_target_cmd { targetname serialport } { -re "unknown host.*$gdb_prompt" { verbose "Couldn't look up $serialport" } - -re "Couldn't establish connection to remote.*$gdb_prompt $" { + -re "Couldn't establish connection to remote.*$gdb_prompt " { verbose "Connection failed" } -re "Remote MIPS debugging.*$gdb_prompt" { verbose "Set target to $targetname" return 0 } - -re "Remote debugging using .*$serialport_re.*$gdb_prompt $" { + -re "Remote debugging using .*$serialport_re.*$gdb_prompt " { verbose "Set target to $targetname" return 0 } - -re "Remote debugging using stdio.*$gdb_prompt $" { + -re "Remote debugging using stdio.*$gdb_prompt " { verbose "Set target to $targetname" return 0 } - -re "Remote target $targetname connected to.*$gdb_prompt $" { + -re "Remote target $targetname connected to.*$gdb_prompt " { verbose "Set target to $targetname" return 0 } - -re "Connected to.*$gdb_prompt $" { + -re "Connected to.*$gdb_prompt " { verbose "Set target to $targetname" return 0 }