From: Joel Brobecker Date: Thu, 1 Nov 2018 22:15:41 +0000 (-0700) Subject: (Ada) fix "error in expression" when using watch -location command X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e2b7af7242c99e503747a43775d94beda90cb24e;p=binutils-gdb.git (Ada) fix "error in expression" when using watch -location command The "watch -l EXPR" command with the language set to Ada currently fails with the following error: (gdb) watch -l global_var Error in expression, near ` 0x000000000062d2d8'. The error occurs because GDB internally translate the request into a watchpoint on a different expression: "* (TYPE *) ADDR" where TYPE and ADDR are the type and the address of the object returned by the expression's evaluation (resp.). So, in the example above, global_var being an integer stored at 0x000000000062d2d8, GDB tries to set a watchpoint on "* (integer *) 0x000000000062d2d8", which fails, because we try to parse this expression with Ada, when in fact it is not valid. This patch fixes the issue by implementing the la_watch_location_expression language method, using a syntax that the Ada parser recognizes ("{TYPE} ADDR"). gdb/ChangeLog: * ada-lang.c (ada_watch_location_expression): New function. (ada_language_defn): Set la_watch_location_expression to ada_watch_location_expression. gdb/testsuite/ChangeLog: * gdb.ada/watch_minus_l: New testcase. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d7cd56e88d4..a3271cccc05 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2018-11-01 Joel Brobecker + + * ada-lang.c (ada_watch_location_expression): New function. + (ada_language_defn): Set la_watch_location_expression to + ada_watch_location_expression. + 2018-11-01 Joel Brobecker * print-utils.c (int_string): Remove unnecessary trailing spaces. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 1462271a710..7ff00a01475 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -565,6 +565,17 @@ ada_print_array_index (struct value *index_value, struct ui_file *stream, fprintf_filtered (stream, " => "); } +/* la_watch_location_expression for Ada. */ + +gdb::unique_xmalloc_ptr +ada_watch_location_expression (struct type *type, CORE_ADDR addr) +{ + type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type))); + std::string name = type_to_string (type); + return gdb::unique_xmalloc_ptr + (xstrprintf ("{%s} %s", name.c_str (), core_addr_to_string (addr))); +} + /* Assuming VECT points to an array of *SIZE objects of size ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects, updating *SIZE as necessary and returning the (new) array. */ @@ -14425,7 +14436,7 @@ extern const struct language_defn ada_language_defn = { ada_print_array_index, default_pass_by_reference, c_get_string, - c_watch_location_expression, + ada_watch_location_expression, ada_get_symbol_name_matcher, /* la_get_symbol_name_matcher */ ada_iterate_over_symbols, default_search_name_hash, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 241bf80b9d6..0df75aa54f2 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-11-01 Joel Brobecker + + * gdb.ada/watch_minus_l: New testcase. + 2018-11-01 Sangamesh Mallayya * gdb.arch/aix-sighandle.c: New file. diff --git a/gdb/testsuite/gdb.ada/watch_minus_l.exp b/gdb/testsuite/gdb.ada/watch_minus_l.exp new file mode 100644 index 00000000000..b11d519ce0a --- /dev/null +++ b/gdb/testsuite/gdb.ada/watch_minus_l.exp @@ -0,0 +1,42 @@ +# 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 . + +load_lib "ada.exp" + +if { [skip_ada_tests] } { return -1 } + +standard_ada_testfile foo_ra10_006 + +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} { + return -1 +} + +clean_restart ${testfile} + +set bp_location [gdb_get_line_number "START" ${testdir}/foo_ra10_006.adb] +runto "foo_ra10_006.adb:$bp_location" + +# Insert a watchpoint on argument X + +gdb_test "watch -location pck.global_var" \ + ".*atchpoint \[0-9\]+: -location pck.global_var" + +# Continue again. We should be stopped at the (internal) breakpoint +# that we setup to delete the watchpoint as soon as the program leaves +# the watchpoint scope. + +gdb_test "continue" \ + "Continuing.*\[Ww\]atchpoint .*: .*New value = 1.*" \ + "continue with watch -location" diff --git a/gdb/testsuite/gdb.ada/watch_minus_l/foo_ra10_006.adb b/gdb/testsuite/gdb.ada/watch_minus_l/foo_ra10_006.adb new file mode 100644 index 00000000000..7914c7503da --- /dev/null +++ b/gdb/testsuite/gdb.ada/watch_minus_l/foo_ra10_006.adb @@ -0,0 +1,22 @@ +-- 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 . + +with Pck; use Pck; + +procedure Foo_RA10_006 is +begin + Global_Var := Global_Var + 1; -- START + Do_Nothing (Global_Var'Address); +end Foo_RA10_006; diff --git a/gdb/testsuite/gdb.ada/watch_minus_l/pck.adb b/gdb/testsuite/gdb.ada/watch_minus_l/pck.adb new file mode 100644 index 00000000000..dcfb3068d3b --- /dev/null +++ b/gdb/testsuite/gdb.ada/watch_minus_l/pck.adb @@ -0,0 +1,21 @@ +-- 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 . + +package body Pck is + procedure Do_Nothing (A : System.Address) is + begin + null; + end Do_Nothing; +end Pck; diff --git a/gdb/testsuite/gdb.ada/watch_minus_l/pck.ads b/gdb/testsuite/gdb.ada/watch_minus_l/pck.ads new file mode 100644 index 00000000000..bf19b165c5d --- /dev/null +++ b/gdb/testsuite/gdb.ada/watch_minus_l/pck.ads @@ -0,0 +1,22 @@ +-- 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 . + +with System; + +package Pck is + Global_Var : Integer := 0; + + procedure Do_Nothing (A : System.Address); +end Pck;