From patchwork Thu May 10 20:40:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Brobecker X-Patchwork-Id: 27214 Received: (qmail 12290 invoked by alias); 10 May 2018 20:40:40 -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 12269 invoked by uid 89); 10 May 2018 20:40:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 10 May 2018 20:40:38 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 750201174E5; Thu, 10 May 2018 16:40:36 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id Bftgha7C4dgh; Thu, 10 May 2018 16:40:36 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 41CE01174C2; Thu, 10 May 2018 16:40:36 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id 8B2C58304F; Thu, 10 May 2018 13:40:34 -0700 (PDT) Date: Thu, 10 May 2018 13:40:34 -0700 From: Joel Brobecker To: Tom Tromey Cc: gdb-patches@sourceware.org Subject: Re: [RFA] inadvertent language switch during breakpoint_re_set_one Message-ID: <20180510204034.uxpqi3uuvvmk7koc@adacore.com> References: <1525976353-67414-1-git-send-email-brobecker@adacore.com> <87fu2z1fmf.fsf@tromey.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <87fu2z1fmf.fsf@tromey.com> User-Agent: NeoMutt/20170113 (1.7.2) > For a plain scalar you can just use scoped_restore and make_scoped_restore. Nice! Thanks Tom. New patch attached. gdb/ChangeLog: * breakpoint.c (breakpoint_re_set): Temporarily force language_mode to language_mode_manual while calling breakpoint_re_set_one. gdb/testsuite/ChangeLog: * gdb.ada/bp_fun_addr: New testcase. Tested on x86_64-linux. From 90bb7d41b87c259d09faddae174887defd87cbc9 Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Thu, 10 May 2018 13:17:52 -0500 Subject: [PATCH] inadvertent language switch during breakpoint_re_set_one Trying to insert a breakpoint using *FUNC'address with an Ada program and then running the program until reaching that breakpoint currently yields the following behavior: (gdb) break *a'address Breakpoint 1 at 0x40240c: file a.adb, line 1. (gdb) run [1] + 27222 suspended (tty output) /[...]/gdb -q simple_main Unsuspending GDB then shows it was suspended trying to report the following error: Starting program: /home/takamaka.a/brobecke/ex/simple/a Error in re-setting breakpoint 1: Unmatched single quote. Error in re-setting breakpoint 1: Unmatched single quote. Error in re-setting breakpoint 1: Unmatched single quote. [Inferior 1 (process 32470) exited normally] The "a'address" is Ada speak for function A's address ("A" by itself means the result of calling A with no arguments). The transcript above shows that we're having problems trying to parse the breakpoint location while re-setting it. As a result, we also fail to stop at the breakpoint. Normally, breakpoint locations are evaluated with the current_language being set to the language of the breakpoint. But, unfortunately for us, what happened in this case is that parse_exp_in_context_1 calls get_selected_block which eventually leads to a call to select_frame because the current_frame hadn't been set yet. select_frame then finds that our language_mode is auto, and therefore changes the current_language to match the language of the frame we just selected. In our case, the language chosen was 'c', which of course is not able to parse an Ada expression, hence the error. This patch prevents this by forcing the language_mode to manual before we call breakpoint_re_set_one. gdb/ChangeLog: * breakpoint.c (breakpoint_re_set): Temporarily force language_mode to language_mode_manual while calling breakpoint_re_set_one. gdb/testsuite/ChangeLog: * gdb.ada/bp_fun_addr: New testcase. Tested on x86_64-linux. --- gdb/breakpoint.c | 13 ++++++++++++ gdb/testsuite/gdb.ada/bp_fun_addr.exp | 35 +++++++++++++++++++++++++++++++++ gdb/testsuite/gdb.ada/bp_fun_addr/a.adb | 19 ++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 gdb/testsuite/gdb.ada/bp_fun_addr.exp create mode 100644 gdb/testsuite/gdb.ada/bp_fun_addr/a.adb diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index d1955ec..6dfa2d9 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -13881,6 +13881,19 @@ breakpoint_re_set (void) scoped_restore save_input_radix = make_scoped_restore (&input_radix); scoped_restore_current_pspace_and_thread restore_pspace_thread; + /* breakpoint_re_set_one sets the current_language to the language + of the breakpoint it is resetting (see prepare_re_set_context) + before re-evaluating the breakpoint's location. This change can + unfortunately get undone by accident if the language_mode is set + to auto, and we either switch frames, or more likely in this context, + we select the current frame. + + We prevent this by temporarily turning the language_mode to + language_mode_manual. We we restore it once all breakpoints + have been reset. */ + scoped_restore save_language_mode = make_scoped_restore (&language_mode); + language_mode = language_mode_manual; + /* Note: we must not try to insert locations until after all breakpoints have been re-set. Otherwise, e.g., when re-setting breakpoint 1, we'd insert the locations of breakpoint 2, which diff --git a/gdb/testsuite/gdb.ada/bp_fun_addr.exp b/gdb/testsuite/gdb.ada/bp_fun_addr.exp new file mode 100644 index 0000000..aa1261b --- /dev/null +++ b/gdb/testsuite/gdb.ada/bp_fun_addr.exp @@ -0,0 +1,35 @@ +# Copyright 2016-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 . + +load_lib "ada.exp" + +if { [skip_ada_tests] } { return -1 } + +standard_ada_testfile a + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} { + return -1 +} + +clean_restart ${testfile} + +gdb_test "break *a'address" \ + "Breakpoint \[0-9\]+ at.*: file .*a.adb, line \[0-9\]+." + +gdb_run_cmd +gdb_test "" \ + "Breakpoint $decimal, a \\(\\).*" \ + "Run until breakpoint at a'address" + diff --git a/gdb/testsuite/gdb.ada/bp_fun_addr/a.adb b/gdb/testsuite/gdb.ada/bp_fun_addr/a.adb new file mode 100644 index 0000000..00e2e86 --- /dev/null +++ b/gdb/testsuite/gdb.ada/bp_fun_addr/a.adb @@ -0,0 +1,19 @@ +-- Copyright 2016-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 . + +procedure A is +begin + null; +end A; -- 2.1.4