This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2] Fix gdb crash when trying to print the address of a synthetic pointer.


Changes in v2:
 * Added a test case to cover this.

Trying to print the address of a synthetic pointer (such as a C++ reference
after O3 optimization) will cause gdb to crash with the following message:

../gdb/dwarf2loc.c:1625: internal-error: Should not be able to create a lazy value with an enclosing type

This patch fixes that by doing a check for synthetic pointers in value_addr
and printing an error message.

Ok to commit?

gdb/ChangeLog:
2015-06-14  Martin Galvan  <martin.galvan@tallertechnologies.com>

	* valops.c (value_addr): Don't try to get the address
	of a synthetic pointer.

gdb/testsuite/ChangeLog:
2015-06-14  Martin Galvan  <martin.galvan@tallertechnologies.com>

	* synthetic-pointer-reference.exp: New file.
	* synthetic-pointer-reference.cc: New file.
---
 .../gdb.dwarf2/synthetic-pointer-reference.cc      | 32 ++++++++++++++++++
 .../gdb.dwarf2/synthetic-pointer-reference.exp     | 39 ++++++++++++++++++++++
 gdb/valops.c                                       |  6 ++++
 3 files changed, 77 insertions(+)
 create mode 100644 gdb/testsuite/gdb.dwarf2/synthetic-pointer-reference.cc
 create mode 100644 gdb/testsuite/gdb.dwarf2/synthetic-pointer-reference.exp

diff --git a/gdb/testsuite/gdb.dwarf2/synthetic-pointer-reference.cc b/gdb/testsuite/gdb.dwarf2/synthetic-pointer-reference.cc
new file mode 100644
index 0000000..36d775e
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/synthetic-pointer-reference.cc
@@ -0,0 +1,32 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright (C) 2015 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/>.  */
+
+#include <stdio.h>
+
+static void function(int& arg)
+{
+    /* We do this to ensure that neither function nor arg are optimized out */
+    printf("%d\n", arg);
+}
+
+int main()
+{
+    int var = 42;
+    function(var);
+
+    return 0;
+}
diff --git a/gdb/testsuite/gdb.dwarf2/synthetic-pointer-reference.exp b/gdb/testsuite/gdb.dwarf2/synthetic-pointer-reference.exp
new file mode 100644
index 0000000..9e327f8
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/synthetic-pointer-reference.exp
@@ -0,0 +1,39 @@
+# Copyright (C) 2015 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/>.
+# This file is part of the gdb testsuite.
+
+# Test taking the address of a synthetic pointer created from a C++ reference.
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile .cc
+
+set options {debug c++ optimize=-O3}
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile $options]} {
+    return -1
+}
+
+runto_main
+
+# If we tried to set a breakpoint and then 'continue' up to it, the program
+# would exit without us hitting it because of the optimizations performed
+# by gcc. We must advance using 'next' and 'step' instead.
+
+gdb_test "next" ".*" "next"
+gdb_test "step" ".*function.*arg=<synthetic pointer>.*" \
+         "stepped inside 'function'; 'arg' is a synthetic pointer"
+gdb_test "print &arg" "Attempt to take address of a synthetic pointer." \
+         "Can't take the address of a synthetic pointer"
diff --git a/gdb/valops.c b/gdb/valops.c
index 66c63c1..1174a5e 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1474,6 +1474,12 @@ value_addr (struct value *arg1)
   struct value *arg2;
   struct type *type = check_typedef (value_type (arg1));
 
+  /* The TYPE_CODE_REF path below causes gdb to crash for synthetic pointers
+     created from C++ references. Catch those cases here. */
+  if (value_bits_synthetic_pointer (arg1, value_embedded_offset (arg1),
+				    TARGET_CHAR_BIT * TYPE_LENGTH (type)))
+      error (_("Attempt to take address of a synthetic pointer."));
+
   if (TYPE_CODE (type) == TYPE_CODE_REF)
     {
       /* Copy the value, but change the type from (T&) to (T*).  We
-- 
2.4.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]