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

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.
This commit is contained in:
Jan Vrany 2018-07-31 10:15:44 +01:00 committed by Simon Marchi
parent 472fa5eec2
commit 5abe0f0cc7
6 changed files with 223 additions and 0 deletions

View File

@ -1,3 +1,8 @@
2018-07-31 Jan Vrany <jan.vrany@fit.cvut.cz>
* varobj.c (varobj_get_path_expr_parent): Report an error if
parent is a dynamic varobj.
2018-07-31 Simon Marchi <simon.marchi@ericsson.com>
* gnulib/aclocal.m4: Re-generate.

View File

@ -1,3 +1,9 @@
2018-07-31 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-07-30 Sergio Durigan Junior <sergiodj@redhat.com>
* lib/gdbserver-support.exp (gdbserver_start): Match any kind of

View File

@ -0,0 +1,62 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright (C) 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 */
}

View File

@ -0,0 +1,88 @@
# Copyright (C) 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"

View File

@ -0,0 +1,57 @@
# Copyright (C) 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)

View File

@ -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;
}