[v5] Fix segfault when invoking -var-info-path-expression on a dynamic varobj

Message ID 20180702192047.18384-1-jan.vrany@fit.cvut.cz
State New, archived
Headers

Commit Message

Jan Vrany July 2, 2018, 7:20 p.m. UTC
  Invoking -var-info-path-expression on a dynamic varobj lead either in wrong
(nonsense) result or to a segmentation fault in cplus_describe_child().
This was caused by the fact that varobj_get_path_expr() called
cplus_path_expr_of_child() ignoring the fact the parent of the variable
is dynamic. Then, cplus_describe_child() accessed the underlaying C type
members by index, causing (i) either wrong (nonsense) expression being
returned (since dynamic child may be completely arbibtrary value)
or (ii) segmentation fault (in case the index higher than number of
underlaying C type members.

This fixes the problem by checking whether a varobj is a child of a dynamic
varobj and, if so, reporting an error as described in documentation.

gdb/ChangeLog:

	* varobj.c (varobj_get_path_expr_parent): Report an error if
	parent is a dynamic varobj.

gdb/testsuite/Changelog:

	* gdb.python/py-mi-var-info-path-expression.c: New file.
	* gdb.python/py-mi-var-info-path-expression.py: New file.
	* gdb.python/py-mi-var-info-path-expression.exp: New file.
---
 gdb/ChangeLog                                 |  5 ++
 gdb/testsuite/ChangeLog                       |  6 ++
 .../py-mi-var-info-path-expression.c          | 62 +++++++++++++
 .../py-mi-var-info-path-expression.exp        | 88 +++++++++++++++++++
 .../py-mi-var-info-path-expression.py         | 57 ++++++++++++
 gdb/varobj.c                                  |  5 ++
 6 files changed, 223 insertions(+)
 create mode 100644 gdb/testsuite/gdb.python/py-mi-var-info-path-expression.c
 create mode 100644 gdb/testsuite/gdb.python/py-mi-var-info-path-expression.exp
 create mode 100644 gdb/testsuite/gdb.python/py-mi-var-info-path-expression.py
  

Comments

Jan Vrany July 25, 2018, 12:33 p.m. UTC | #1
Polite ping.

On Mon, 2018-07-02 at 20:20 +0100, Jan Vrany wrote:
> Invoking -var-info-path-expression on a dynamic varobj lead either in wrong
> (nonsense) result or to a segmentation fault in cplus_describe_child().
> This was caused by the fact that varobj_get_path_expr() called
> cplus_path_expr_of_child() ignoring the fact the parent of the variable
> is dynamic. Then, cplus_describe_child() accessed the underlaying C type
> members by index, causing (i) either wrong (nonsense) expression being
> returned (since dynamic child may be completely arbibtrary value)
> or (ii) segmentation fault (in case the index higher than number of
> underlaying C type members.
> 
> This fixes the problem by checking whether a varobj is a child of a dynamic
> varobj and, if so, reporting an error as described in documentation.
> 
> gdb/ChangeLog:
> 
> 	* varobj.c (varobj_get_path_expr_parent): Report an error if
> 	parent is a dynamic varobj.
> 
> gdb/testsuite/Changelog:
> 
> 	* gdb.python/py-mi-var-info-path-expression.c: New file.
> 	* gdb.python/py-mi-var-info-path-expression.py: New file.
> 	* gdb.python/py-mi-var-info-path-expression.exp: New file.
> ---
>  gdb/ChangeLog                                 |  5 ++
>  gdb/testsuite/ChangeLog                       |  6 ++
>  .../py-mi-var-info-path-expression.c          | 62 +++++++++++++
>  .../py-mi-var-info-path-expression.exp        | 88 +++++++++++++++++++
>  .../py-mi-var-info-path-expression.py         | 57 ++++++++++++
>  gdb/varobj.c                                  |  5 ++
>  6 files changed, 223 insertions(+)
>  create mode 100644 gdb/testsuite/gdb.python/py-mi-var-info-path-expression.c
>  create mode 100644 gdb/testsuite/gdb.python/py-mi-var-info-path-
> expression.exp
>  create mode 100644 gdb/testsuite/gdb.python/py-mi-var-info-path-expression.py
> 
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> index 80626191c9..625c42af36 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,8 @@
> +2018-06-04  Jan Vrany  <jan.vrany@fit.cvut.cz>
> +
> +	* varobj.c (varobj_get_path_expr_parent): Report an error if
> +	parent is a dynamic varobj.
> +
>  2018-06-28  Petr Tesarik  <ptesarik@suse.cz>
>  
>  	* symfile.c (add_symbol_file_command, _initialize_symfile): Add
> diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
> index f93eb97d97..0d30ab2793 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,9 @@
> +2018-06-04  Jan Vrany  <jan.vrany@fit.cvut.cz>
> +
> +	* gdb.python/py-mi-var-info-path-expression.c: New file.
> +	* gdb.python/py-mi-var-info-path-expression.py: New file.
> +	* gdb.python/py-mi-var-info-path-expression.exp: New file.
> +
>  2018-06-28  Richard Bunt  <richard.bunt@arm.com>
>  
>  	* gdb.base/watchpoint-hw-attach.c (main): Remove unneeded
> diff --git a/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.c
> b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.c
> new file mode 100644
> index 0000000000..9d6ff126dd
> --- /dev/null
> +++ b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.c
> @@ -0,0 +1,62 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright (C) 1999-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 <http://www.gnu.org/licenses/>.  */
> +
> +enum cons_type
> +{
> +  type_atom = 0,
> +  type_cons = 1
> +};
> +
> +struct atom
> +{
> +  int ival;
> +};
> +
> +struct cons
> +{
> +  enum cons_type type;
> +  union
> +  {
> +    struct atom atom;
> +    struct cons *slots[2];
> +  };
> +};
> +
> +#define nil ((struct cons*)0);
> +
> +int
> +main ()
> +{
> +  struct cons c1, c2, c3, c4;
> +
> +  c1.type = type_cons;
> +  c1.slots[0] = &c4;
> +  c1.slots[1] = &c2;
> +
> +  c2.type = type_cons;
> +  c2.slots[0] = nil;
> +  c2.slots[1] = &c3;
> +
> +  c3.type = type_cons;
> +  c3.slots[0] = nil;
> +  c3.slots[1] = nil;
> +
> +  c4.type = type_atom;
> +  c4.atom.ival = 13;
> +
> +  return 0;			/* next line */
> +}
> diff --git a/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.exp
> b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.exp
> new file mode 100644
> index 0000000000..b14572f524
> --- /dev/null
> +++ b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.exp
> @@ -0,0 +1,88 @@
> +# Copyright (C) 2008-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 <http://www.gnu.org/licenses/>.
> +
> +# Tests whether -var-info-path-expression fails as documented when
> +# invoked on a dynamic varobj.
> +
> +load_lib mi-support.exp
> +set MIFLAGS "-i=mi"
> +
> +gdb_exit
> +if {[mi_gdb_start]} {
> +    continue
> +}
> +
> +#
> +# Start here
> +#
> +standard_testfile
> +
> +if {[gdb_compile "$srcdir/$subdir/$srcfile" $binfile executable {debug}] !=
> "" } {
> +    return -1
> +}
> +
> +mi_gdb_test "source ${srcdir}/${subdir}/${testfile}.py" \
> +  ".*\\^done" \
> +  "load python file"
> +
> +mi_gdb_test "-enable-pretty-printing" \
> +  "\\^done" \
> +  "-enable-pretty-printing"
> +
> +mi_gdb_test "set python print-stack full" \
> +  ".*\\^done" \
> +  "set python print-stack full"
> +
> +
> +mi_run_to_main
> +
> +
> +mi_continue_to_line [gdb_get_line_number "next line" ${srcfile}] \
> +  "step to breakpoint"
> +
> +mi_gdb_test "-var-create c1 * &c1" \
> +   "\\^done.*" \
> +   "-var-create c1 * &c1"
> +
> +mi_gdb_test "-var-info-path-expression c1" \
> +  "\\^done,path_expr=\"&c1\"" \
> +  "-var-info-path-expression c1"
> +
> +mi_gdb_test "-var-list-children c1" \
> +  "\\^done,numchild=\"2\",children=.child=\{name=\"c1.car\".*child=\{name=\"c
> 1.cdr\".*" \
> +  "-var-list-children c1"
> +
> +mi_gdb_test "-var-info-path-expression c1.cdr" \
> +  "\\^error,msg=\".*\"" \
> +  "-var-info-path-expression c1.cdr"
> +
> +mi_gdb_test "-var-list-children c1.cdr" \
> +  "\\^done,numchild=\"2\",children=.child=\{name=\"c1.cdr.car\".*child=\{name
> =\"c1.cdr.cdr\".*" \
> +  "-var-list-children c1.cdr"
> +
> +mi_gdb_test "-var-info-path-expression c1.cdr.cdr" \
> +  "\\^error,msg=\".*\"" \
> +  "-var-info-path-expression c1.cdr.cdr"
> +
> +mi_gdb_test "-var-list-children c1.car" \
> +  "\\^done,numchild=\"1\",children=.child=\{name=\"c1.car.atom\".*" \
> +  "-var-list-children c1.car"
> +
> +mi_gdb_test "-var-list-children c1.car.atom" \
> +  "\\^done,numchild=\"1\",children=.child=\{name=\"c1.car.atom.ival\".*" \
> +  "-var-list-children c1.car.atom"
> +
> +mi_gdb_test "-var-info-path-expression c1.car.atom.ival" \
> +  "\\^error,msg=\".*\"" \
> +  "-var-info-path-expression c1.car.atom.ival"
> diff --git a/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.py
> b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.py
> new file mode 100644
> index 0000000000..c2f5897180
> --- /dev/null
> +++ b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.py
> @@ -0,0 +1,57 @@
> +# Copyright (C) 2008-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 <http://www.gnu.org/licenses/>.
> +
> +import sys
> +import gdb
> +import gdb.types
> +
> +# Following is for Python 3 compatibility...
> +if sys.version_info[0] > 2:
> +    long = int
> +
> +
> +class cons_pp(object):
> +  def __init__(self, val):
> +    self._val = val
> +
> +  def to_string(self):
> +    if long(self._val) == 0:
> +      return "nil"
> +    elif long(self._val['type']) == 0:
> +      return "( . )"
> +    else:
> +      return "%d" % self._val['atom']['ival']
> +
> +  def children(self):
> +    if long(self._val) == 0:
> +      return []
> +    elif long(self._val['type']) == 0:
> +      return [
> +        ('atom', self._val['atom'])
> +      ]
> +    else:
> +      return [
> +        ('car' ,  self._val["slots"][0]),
> +        ('cdr' ,  self._val["slots"][1]),
> +      ]
> +
> +def cons_pp_lookup(val):
> +  if str(val.type) == 'struct cons *':
> +    return cons_pp(val)
> +  else:
> +    return None
> +
> +del gdb.pretty_printers[1:]
> +gdb.pretty_printers.append(cons_pp_lookup)
> diff --git a/gdb/varobj.c b/gdb/varobj.c
> index 02441410e8..af607963b4 100644
> --- a/gdb/varobj.c
> +++ b/gdb/varobj.c
> @@ -948,6 +948,11 @@ varobj_get_path_expr_parent (const struct varobj *var)
>    while (!is_root_p (parent) && !is_path_expr_parent (parent))
>      parent = parent->parent;
>  
> +  /* Computation of full rooted expression for children of dynamic
> +     varobjs is not supported.  */
> +  if (varobj_is_dynamic_p (parent))
> +    error (_("Invalid variable object (child of a dynamic varobj)"));
> +
>    return parent;
>  }
>
  
Tom Tromey July 30, 2018, 4:48 p.m. UTC | #2
>>>>> "Jan" == Jan Vrany <jan.vrany@fit.cvut.cz> writes:

Thanks for the patch.

>> +   Copyright (C) 1999-2018 Free Software Foundation, Inc.

>> +# Copyright (C) 2008-2018 Free Software Foundation, Inc.

>> +# Copyright (C) 2008-2018 Free Software Foundation, Inc.

These dates look weird.  I assume you copied the headers from elsewhere
-- a time-honored tradition.  However if the files don't substantially
share anything with other files, I think just 2018 should suffice.

This is ok with this either fixed, or if there's some overlap, an email
to that effect.

Tom
  
Simon Marchi July 30, 2018, 7:53 p.m. UTC | #3
On 2018-07-30 12:48 PM, Tom Tromey wrote:
>>>>>> "Jan" == Jan Vrany <jan.vrany@fit.cvut.cz> writes:
> 
> Thanks for the patch.
> 
>>> +   Copyright (C) 1999-2018 Free Software Foundation, Inc.
> 
>>> +# Copyright (C) 2008-2018 Free Software Foundation, Inc.
> 
>>> +# Copyright (C) 2008-2018 Free Software Foundation, Inc.
> 
> These dates look weird.  I assume you copied the headers from elsewhere
> -- a time-honored tradition.  However if the files don't substantially
> share anything with other files, I think just 2018 should suffice.
> 
> This is ok with this either fixed, or if there's some overlap, an email
> to that effect.
> 
> Tom
> 

Just noting that Jan doesn't have push access, so I can take care of pushing
the patch once he answers about the copyright years.

Simon
  
Jan Vrany July 31, 2018, 9:14 a.m. UTC | #4
On Mon, 2018-07-30 at 10:48 -0600, Tom Tromey wrote:
> > > +   Copyright (C) 1999-2018 Free Software Foundation, Inc.
> > > +# Copyright (C) 2008-2018 Free Software Foundation, Inc.
> > > +# Copyright (C) 2008-2018 Free Software Foundation, Inc.
> 
> These dates look weird.  I assume you copied the headers from elsewhere
> -- a time-honored tradition.  However if the files don't substantially
> share anything with other files, I think just 2018 should suffice.
> 

Oops, you're right, I just copy-pasted the header from other files and
forgot to fix. I'd say these files are completely new, though indeed
I took an inspiration from other files to see how to write a test. 


> This is ok with this either fixed, or if there's some overlap, an email
> to that effect.

Fixed patch will follow shortly.

Thanks, Jan
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 80626191c9..625c42af36 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@ 
+2018-06-04  Jan Vrany  <jan.vrany@fit.cvut.cz>
+
+	* varobj.c (varobj_get_path_expr_parent): Report an error if
+	parent is a dynamic varobj.
+
 2018-06-28  Petr Tesarik  <ptesarik@suse.cz>
 
 	* symfile.c (add_symbol_file_command, _initialize_symfile): Add
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index f93eb97d97..0d30ab2793 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@ 
+2018-06-04  Jan Vrany  <jan.vrany@fit.cvut.cz>
+
+	* gdb.python/py-mi-var-info-path-expression.c: New file.
+	* gdb.python/py-mi-var-info-path-expression.py: New file.
+	* gdb.python/py-mi-var-info-path-expression.exp: New file.
+
 2018-06-28  Richard Bunt  <richard.bunt@arm.com>
 
 	* gdb.base/watchpoint-hw-attach.c (main): Remove unneeded
diff --git a/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.c b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.c
new file mode 100644
index 0000000000..9d6ff126dd
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.c
@@ -0,0 +1,62 @@ 
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright (C) 1999-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 <http://www.gnu.org/licenses/>.  */
+
+enum cons_type
+{
+  type_atom = 0,
+  type_cons = 1
+};
+
+struct atom
+{
+  int ival;
+};
+
+struct cons
+{
+  enum cons_type type;
+  union
+  {
+    struct atom atom;
+    struct cons *slots[2];
+  };
+};
+
+#define nil ((struct cons*)0);
+
+int
+main ()
+{
+  struct cons c1, c2, c3, c4;
+
+  c1.type = type_cons;
+  c1.slots[0] = &c4;
+  c1.slots[1] = &c2;
+
+  c2.type = type_cons;
+  c2.slots[0] = nil;
+  c2.slots[1] = &c3;
+
+  c3.type = type_cons;
+  c3.slots[0] = nil;
+  c3.slots[1] = nil;
+
+  c4.type = type_atom;
+  c4.atom.ival = 13;
+
+  return 0;			/* next line */
+}
diff --git a/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.exp b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.exp
new file mode 100644
index 0000000000..b14572f524
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.exp
@@ -0,0 +1,88 @@ 
+# Copyright (C) 2008-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 <http://www.gnu.org/licenses/>.
+
+# Tests whether -var-info-path-expression fails as documented when
+# invoked on a dynamic varobj.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if {[mi_gdb_start]} {
+    continue
+}
+
+#
+# Start here
+#
+standard_testfile
+
+if {[gdb_compile "$srcdir/$subdir/$srcfile" $binfile executable {debug}] != "" } {
+    return -1
+}
+
+mi_gdb_test "source ${srcdir}/${subdir}/${testfile}.py" \
+  ".*\\^done" \
+  "load python file"
+
+mi_gdb_test "-enable-pretty-printing" \
+  "\\^done" \
+  "-enable-pretty-printing"
+
+mi_gdb_test "set python print-stack full" \
+  ".*\\^done" \
+  "set python print-stack full"
+
+
+mi_run_to_main
+
+
+mi_continue_to_line [gdb_get_line_number "next line" ${srcfile}] \
+  "step to breakpoint"
+
+mi_gdb_test "-var-create c1 * &c1" \
+   "\\^done.*" \
+   "-var-create c1 * &c1"
+
+mi_gdb_test "-var-info-path-expression c1" \
+  "\\^done,path_expr=\"&c1\"" \
+  "-var-info-path-expression c1"
+
+mi_gdb_test "-var-list-children c1" \
+  "\\^done,numchild=\"2\",children=.child=\{name=\"c1.car\".*child=\{name=\"c1.cdr\".*" \
+  "-var-list-children c1"
+
+mi_gdb_test "-var-info-path-expression c1.cdr" \
+  "\\^error,msg=\".*\"" \
+  "-var-info-path-expression c1.cdr"
+
+mi_gdb_test "-var-list-children c1.cdr" \
+  "\\^done,numchild=\"2\",children=.child=\{name=\"c1.cdr.car\".*child=\{name=\"c1.cdr.cdr\".*" \
+  "-var-list-children c1.cdr"
+
+mi_gdb_test "-var-info-path-expression c1.cdr.cdr" \
+  "\\^error,msg=\".*\"" \
+  "-var-info-path-expression c1.cdr.cdr"
+
+mi_gdb_test "-var-list-children c1.car" \
+  "\\^done,numchild=\"1\",children=.child=\{name=\"c1.car.atom\".*" \
+  "-var-list-children c1.car"
+
+mi_gdb_test "-var-list-children c1.car.atom" \
+  "\\^done,numchild=\"1\",children=.child=\{name=\"c1.car.atom.ival\".*" \
+  "-var-list-children c1.car.atom"
+
+mi_gdb_test "-var-info-path-expression c1.car.atom.ival" \
+  "\\^error,msg=\".*\"" \
+  "-var-info-path-expression c1.car.atom.ival"
diff --git a/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.py b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.py
new file mode 100644
index 0000000000..c2f5897180
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-mi-var-info-path-expression.py
@@ -0,0 +1,57 @@ 
+# Copyright (C) 2008-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 <http://www.gnu.org/licenses/>.
+
+import sys
+import gdb
+import gdb.types
+
+# Following is for Python 3 compatibility...
+if sys.version_info[0] > 2:
+    long = int
+
+
+class cons_pp(object):
+  def __init__(self, val):
+    self._val = val
+
+  def to_string(self):
+    if long(self._val) == 0:
+      return "nil"
+    elif long(self._val['type']) == 0:
+      return "( . )"
+    else:
+      return "%d" % self._val['atom']['ival']
+
+  def children(self):
+    if long(self._val) == 0:
+      return []
+    elif long(self._val['type']) == 0:
+      return [
+        ('atom', self._val['atom'])
+      ]
+    else:
+      return [
+        ('car' ,  self._val["slots"][0]),
+        ('cdr' ,  self._val["slots"][1]),
+      ]
+
+def cons_pp_lookup(val):
+  if str(val.type) == 'struct cons *':
+    return cons_pp(val)
+  else:
+    return None
+
+del gdb.pretty_printers[1:]
+gdb.pretty_printers.append(cons_pp_lookup)
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 02441410e8..af607963b4 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -948,6 +948,11 @@  varobj_get_path_expr_parent (const struct varobj *var)
   while (!is_root_p (parent) && !is_path_expr_parent (parent))
     parent = parent->parent;
 
+  /* Computation of full rooted expression for children of dynamic
+     varobjs is not supported.  */
+  if (varobj_is_dynamic_p (parent))
+    error (_("Invalid variable object (child of a dynamic varobj)"));
+
   return parent;
 }