Fix crash when setting breakpoint condition
authorTom Tromey <tromey@adacore.com>
Thu, 30 May 2019 20:13:10 +0000 (14:13 -0600)
committerTom Tromey <tromey@adacore.com>
Wed, 19 Jun 2019 12:06:02 +0000 (06:06 -0600)
gdb could crash when setting a breakpoint condition on a breakpoint
when using the Ada language.  The problem occurred because the
ada_evaluate_subexp would try to evaluate the array to compute its
attributes, but evaluating can't really be done at this time.

This patch fixes the problem by arranging not to try to evaluate in
EVAL_AVOID_SIDE_EFFECTS mode when computing an attribute.

Tested on x86-64 Fedora 29.  Because this is Ada-specific, and because
Joel approved it internally, I am checking it in.

gdb/ChangeLog
2019-06-19  Tom Tromey  <tromey@adacore.com>

* ada-lang.c (ada_evaluate_subexp) <case OP_ATR_FIRST>: Handle
EVAL_AVOID_SIDE_EFFECTS specially.

gdb/testsuite/ChangeLog
2019-06-19  Tom Tromey  <tromey@adacore.com>

* gdb.ada/length_cond.exp: New file.
* gdb.ada/length_cond/length_cond.adb: New file.
* gdb.ada/length_cond/pck.adb: New file.
* gdb.ada/length_cond/pck.ads: New file.

gdb/ChangeLog
gdb/ada-lang.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.ada/length_cond.exp [new file with mode: 0644]
gdb/testsuite/gdb.ada/length_cond/length_cond.adb [new file with mode: 0644]
gdb/testsuite/gdb.ada/length_cond/pck.adb [new file with mode: 0644]
gdb/testsuite/gdb.ada/length_cond/pck.ads [new file with mode: 0644]

index 55650974cd951009fa46976caa575da83c8aceb2..c40b7d4574efa8593e76eb3353e13366a012a1aa 100644 (file)
@@ -1,3 +1,8 @@
+2019-06-19  Tom Tromey  <tromey@adacore.com>
+
+       * ada-lang.c (ada_evaluate_subexp) <case OP_ATR_FIRST>: Handle
+       EVAL_AVOID_SIDE_EFFECTS specially.
+
 2019-06-19  Tom Tromey  <tromey@adacore.com>
 
        * source-cache.c (highlighter): New global.
index bf17c67f4d0f7c6bb155da9ab66f074f27640fbf..1e996557b6eee3526eede56547c2ae1cc7368d80 100644 (file)
@@ -11055,8 +11055,34 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
 
         if (noside == EVAL_SKIP)
           goto nosideret;
+       else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+         {
+           if (type_arg == NULL)
+             type_arg = value_type (arg1);
+
+            if (ada_is_constrained_packed_array_type (type_arg))
+             type_arg = decode_constrained_packed_array_type (type_arg);
 
-        if (type_arg == NULL)
+           if (!discrete_type_p (type_arg))
+             {
+               switch (op)
+                 {
+                 default:          /* Should never happen.  */
+                   error (_("unexpected attribute encountered"));
+                 case OP_ATR_FIRST:
+                 case OP_ATR_LAST:
+                   type_arg = ada_index_type (type_arg, tem,
+                                              ada_attribute_name (op));
+                   break;
+                 case OP_ATR_LENGTH:
+                   type_arg = builtin_type (exp->gdbarch)->builtin_int;
+                   break;
+                 }
+             }
+
+           return value_zero (type_arg, not_lval);
+         }
+        else if (type_arg == NULL)
           {
             arg1 = ada_coerce_ref (arg1);
 
@@ -11073,9 +11099,6 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
                  type = builtin_type (exp->gdbarch)->builtin_int;
              }
 
-            if (noside == EVAL_AVOID_SIDE_EFFECTS)
-              return allocate_value (type);
-
             switch (op)
               {
               default:          /* Should never happen.  */
@@ -11133,9 +11156,6 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp,
                  type = builtin_type (exp->gdbarch)->builtin_int;
              }
 
-            if (noside == EVAL_AVOID_SIDE_EFFECTS)
-              return allocate_value (type);
-
             switch (op)
               {
               default:
index 71ac0ce153c9878fbb31cb0edb6a024cda7e2222..8454b00755c0b00fe181db087b774a44b4055c85 100644 (file)
@@ -1,3 +1,10 @@
+2019-06-19  Tom Tromey  <tromey@adacore.com>
+
+       * gdb.ada/length_cond.exp: New file.
+       * gdb.ada/length_cond/length_cond.adb: New file.
+       * gdb.ada/length_cond/pck.adb: New file.
+       * gdb.ada/length_cond/pck.ads: New file.
+
 2019-06-18  Tom de Vries  <tdevries@suse.de>
 
        * boards/fission.exp (debug_flags): Add "-fuse-ld=gold".
diff --git a/gdb/testsuite/gdb.ada/length_cond.exp b/gdb/testsuite/gdb.ada/length_cond.exp
new file mode 100644 (file)
index 0000000..53e9187
--- /dev/null
@@ -0,0 +1,44 @@
+# Copyright 2019 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 <http://www.gnu.org/licenses/>.
+
+load_lib "ada.exp"
+
+standard_ada_testfile length_cond
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable debug] != "" } {
+  return -1
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "BREAKPOINT" ${testdir}/length_cond.adb]
+gdb_breakpoint length_cond.adb:$bp_location message
+
+# Resolving the conditional expression would cause a crash, so it's
+# enough to just set the conditions.
+
+foreach var {loc enum_val int_val} {
+    foreach attr {first last} {
+       gdb_test_no_output "cond 1 $var'$attr > 15"
+    }
+}
+
+gdb_test_no_output "cond 1 loc'length > 15"
+
+foreach attr {first last length} {
+    foreach val {1 2} {
+       gdb_test_no_output "cond 1 my_array'${attr}($val) > 15"
+    }
+}
diff --git a/gdb/testsuite/gdb.ada/length_cond/length_cond.adb b/gdb/testsuite/gdb.ada/length_cond/length_cond.adb
new file mode 100644 (file)
index 0000000..7b563c3
--- /dev/null
@@ -0,0 +1,37 @@
+--  Copyright 2019 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 <http://www.gnu.org/licenses/>.
+
+with Pck;
+
+procedure Length_Cond is
+   type Enum is (One, Two, Three);
+   Enum_Val : Enum := Three;
+
+   type My_Int is range -23 .. 23;
+   Int_Val : My_Int := 0;
+
+   type My_Array is array (0..1, 0..1) of Boolean;
+   Array_Val : My_Array := ((True, False), (False, True));
+
+   procedure p (s : String) is
+      loc : String := s & ".";
+   begin
+      Pck.Do_Nothing (loc);            --  BREAKPOINT
+   end p;
+begin
+   for I in 1 .. 25 loop
+      p ((1 .. I => 'X'));
+   end loop;
+end Length_Cond;
diff --git a/gdb/testsuite/gdb.ada/length_cond/pck.adb b/gdb/testsuite/gdb.ada/length_cond/pck.adb
new file mode 100644 (file)
index 0000000..79bbe59
--- /dev/null
@@ -0,0 +1,21 @@
+--  Copyright 2019 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 <http://www.gnu.org/licenses/>.
+
+package body Pck is
+   procedure Do_Nothing (A : String) is
+   begin
+      null;
+   end Do_Nothing;
+end Pck;
diff --git a/gdb/testsuite/gdb.ada/length_cond/pck.ads b/gdb/testsuite/gdb.ada/length_cond/pck.ads
new file mode 100644 (file)
index 0000000..433b389
--- /dev/null
@@ -0,0 +1,18 @@
+--  Copyright 2019 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 <http://www.gnu.org/licenses/>.
+
+package Pck is
+   procedure Do_Nothing (A : String);
+end Pck;