This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH v2] Fix gdb crash when trying to print the address of a synthetic pointer.
- From: Martin Galvan <martin dot galvan at tallertechnologies dot com>
- To: gdb-patches at sourceware dot org, palves at redhat dot com
- Date: Sun, 14 Jun 2015 01:48:43 -0300
- Subject: [PATCH v2] Fix gdb crash when trying to print the address of a synthetic pointer.
- Authentication-results: sourceware.org; auth=none
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