2012-03-14 Siva Chandra <sivachandra@google.com>
Python scripting: Add new method Value.referenced_value to gdb.Value which can dereference pointer as well as reference values. * NEWS: Add entry under 'Python scripting' about the new method Value.referenced_value on gdb.Value objects. * python/py-value.c (valpy_referenced_value): New function defining a new method on gdb.Value objects which can dereference pointer and reference values. * testsuite/gdb.python/py-value.cc: Add test case for testing the methodology exposing C++ values to Python. * testsuite/gdb.python/py-value-cc.exp: Add tests testing the methodology exposing C++ values to Python. * testsuite/gdb.python/Makefile.in: Add py-value-cc to EXECUTABLES. * docs/gdb.texinfo (Python API/Values From Inferior): Add description about the new method Value.referenced_value. Add description on how Value.dereference is different (and similar) to Value.referenced_value.
This commit is contained in:
parent
0c83539f7e
commit
7b282c5acc
9 changed files with 233 additions and 1 deletions
|
@ -1,3 +1,14 @@
|
||||||
|
2012-03-22 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
|
Python scripting: Add new method Value.referenced_value to
|
||||||
|
gdb.Value which can dereference pointer as well as reference
|
||||||
|
values.
|
||||||
|
* NEWS: Add entry under 'Python scripting' about the new method
|
||||||
|
Value.referenced_value on gdb.Value objects.
|
||||||
|
* python/py-value.c (valpy_referenced_value): New function
|
||||||
|
defining a new method on gdb.Value objects which can dereference
|
||||||
|
pointer and reference values.
|
||||||
|
|
||||||
2012-03-22 Siva Chandra Reddy <sivachandra@google.com>
|
2012-03-22 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
* MAINTAINERS (Write After Approval): Add myself to the list.
|
* MAINTAINERS (Write After Approval): Add myself to the list.
|
||||||
|
|
3
gdb/NEWS
3
gdb/NEWS
|
@ -25,6 +25,9 @@
|
||||||
frame in order to compute its value, and the latter computes the
|
frame in order to compute its value, and the latter computes the
|
||||||
symbol's value.
|
symbol's value.
|
||||||
|
|
||||||
|
** A new method 'referenced_value' on gdb.Value objects which can
|
||||||
|
dereference pointer as well as C++ reference values.
|
||||||
|
|
||||||
* GDBserver now supports stdio connections.
|
* GDBserver now supports stdio connections.
|
||||||
E.g. (gdb) target remote | ssh myhost gdbserver - hello
|
E.g. (gdb) target remote | ssh myhost gdbserver - hello
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2012-03-22 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
|
* gdb.texinfo (Python API/Values From Inferior): Add description
|
||||||
|
about the new method Value.referenced_value. Add description on
|
||||||
|
how Value.dereference is different (and similar) to
|
||||||
|
Value.referenced_value.
|
||||||
|
|
||||||
2012-03-19 Jan Kratochvil <jan.kratochvil@redhat.com>
|
2012-03-19 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
* gdb.texinfo (File Options): Describe --init-command=FILE, -ix and
|
* gdb.texinfo (File Options): Describe --init-command=FILE, -ix and
|
||||||
|
|
|
@ -22136,6 +22136,79 @@ bar = foo.dereference ()
|
||||||
|
|
||||||
The result @code{bar} will be a @code{gdb.Value} object holding the
|
The result @code{bar} will be a @code{gdb.Value} object holding the
|
||||||
value pointed to by @code{foo}.
|
value pointed to by @code{foo}.
|
||||||
|
|
||||||
|
A similar function @code{Value.referenced_value} exists which also
|
||||||
|
returns @code{gdb.Value} objects corresonding to the values pointed to
|
||||||
|
by pointer values (and additionally, values referenced by reference
|
||||||
|
values). However, the behavior of @code{Value.dereference}
|
||||||
|
differs from @code{Value.referenced_value} by the fact that the
|
||||||
|
behavior of @code{Value.dereference} is identical to applying the C
|
||||||
|
unary operator @code{*} on a given value. For example, consider a
|
||||||
|
reference to a pointer @code{ptrref}, declared in your C@t{++} program
|
||||||
|
as
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
typedef int *intptr;
|
||||||
|
...
|
||||||
|
int val = 10;
|
||||||
|
intptr ptr = &val;
|
||||||
|
intptr &ptrref = ptr;
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
Though @code{ptrref} is a reference value, one can apply the method
|
||||||
|
@code{Value.dereference} to the @code{gdb.Value} object corresponding
|
||||||
|
to it and obtain a @code{gdb.Value} which is identical to that
|
||||||
|
corresponding to @code{val}. However, if you apply the method
|
||||||
|
@code{Value.referenced_value}, the result would be a @code{gdb.Value}
|
||||||
|
object identical to that corresponding to @code{ptr}.
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
py_ptrref = gdb.parse_and_eval ("ptrref")
|
||||||
|
py_val = py_ptrref.dereference ()
|
||||||
|
py_ptr = py_ptrref.referenced_value ()
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
The @code{gdb.Value} object @code{py_val} is identical to that
|
||||||
|
corresponding to @code{val}, and @code{py_ptr} is identical to that
|
||||||
|
corresponding to @code{ptr}. In general, @code{Value.dereference} can
|
||||||
|
be applied whenever the C unary operator @code{*} can be applied
|
||||||
|
to the corresponding C value. For those cases where applying both
|
||||||
|
@code{Value.dereference} and @code{Value.referenced_value} is allowed,
|
||||||
|
the results obtained need not be identical (as we have seen in the above
|
||||||
|
example). The results are however identical when applied on
|
||||||
|
@code{gdb.Value} objects corresponding to pointers (@code{gdb.Value}
|
||||||
|
objects with type code @code{TYPE_CODE_PTR}) in a C/C@t{++} program.
|
||||||
|
@end defun
|
||||||
|
|
||||||
|
@defun Value.referenced_value ()
|
||||||
|
For pointer or reference data types, this method returns a new
|
||||||
|
@code{gdb.Value} object corresponding to the value referenced by the
|
||||||
|
pointer/reference value. For pointer data types,
|
||||||
|
@code{Value.dereference} and @code{Value.referenced_value} produce
|
||||||
|
identical results. The difference between these methods is that
|
||||||
|
@code{Value.dereference} cannot get the values referenced by reference
|
||||||
|
values. For example, consider a reference to an @code{int}, declared
|
||||||
|
in your C@t{++} program as
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
int val = 10;
|
||||||
|
int &ref = val;
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
then applying @code{Value.dereference} to the @code{gdb.Value} object
|
||||||
|
corresponding to @code{ref} will result in an error, while applying
|
||||||
|
@code{Value.referenced_value} will result in a @code{gdb.Value} object
|
||||||
|
identical to that corresponding to @code{val}.
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
py_ref = gdb.parse_and_eval ("ref")
|
||||||
|
er_ref = py_ref.dereference () # Results in error
|
||||||
|
py_val = py_ref.referenced_value () # Returns the referenced value
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
The @code{gdb.Value} object @code{py_val} is identical to that
|
||||||
|
corresponding to @code{val}.
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
@defun Value.dynamic_cast (type)
|
@defun Value.dynamic_cast (type)
|
||||||
|
|
|
@ -192,6 +192,47 @@ valpy_dereference (PyObject *self, PyObject *args)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given a value of a pointer type or a reference type, return the value
|
||||||
|
referenced. The difference between this function and valpy_dereference is
|
||||||
|
that the latter applies * unary operator to a value, which need not always
|
||||||
|
result in the value referenced. For example, for a value which is a reference
|
||||||
|
to an 'int' pointer ('int *'), valpy_dereference will result in a value of
|
||||||
|
type 'int' while valpy_referenced_value will result in a value of type
|
||||||
|
'int *'. */
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
valpy_referenced_value (PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
volatile struct gdb_exception except;
|
||||||
|
PyObject *result = NULL;
|
||||||
|
|
||||||
|
TRY_CATCH (except, RETURN_MASK_ALL)
|
||||||
|
{
|
||||||
|
struct value *self_val, *res_val;
|
||||||
|
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
|
||||||
|
|
||||||
|
self_val = ((value_object *) self)->value;
|
||||||
|
switch (TYPE_CODE (check_typedef (value_type (self_val))))
|
||||||
|
{
|
||||||
|
case TYPE_CODE_PTR:
|
||||||
|
res_val = value_ind (self_val);
|
||||||
|
break;
|
||||||
|
case TYPE_CODE_REF:
|
||||||
|
res_val = coerce_ref (self_val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error(_("Trying to get the referenced value from a value which is "
|
||||||
|
"neither a pointer nor a reference."));
|
||||||
|
}
|
||||||
|
|
||||||
|
result = value_to_value_object (res_val);
|
||||||
|
do_cleanups (cleanup);
|
||||||
|
}
|
||||||
|
GDB_PY_HANDLE_EXCEPTION (except);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return "&value". */
|
/* Return "&value". */
|
||||||
static PyObject *
|
static PyObject *
|
||||||
valpy_get_address (PyObject *self, void *closure)
|
valpy_get_address (PyObject *self, void *closure)
|
||||||
|
@ -1379,6 +1420,8 @@ Cast the value to the supplied type, as if by the C++\n\
|
||||||
reinterpret_cast operator."
|
reinterpret_cast operator."
|
||||||
},
|
},
|
||||||
{ "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
|
{ "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
|
||||||
|
{ "referenced_value", valpy_referenced_value, METH_NOARGS,
|
||||||
|
"Return the value referenced by a TYPE_CODE_REF or TYPE_CODE_PTR value." },
|
||||||
{ "lazy_string", (PyCFunction) valpy_lazy_string,
|
{ "lazy_string", (PyCFunction) valpy_lazy_string,
|
||||||
METH_VARARGS | METH_KEYWORDS,
|
METH_VARARGS | METH_KEYWORDS,
|
||||||
"lazy_string ([encoding] [, length]) -> lazy_string\n\
|
"lazy_string ([encoding] [, length]) -> lazy_string\n\
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
2012-03-22 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
|
* gdb.python/py-value.cc: Add test case for testing the
|
||||||
|
methodology exposing C++ values to Python.
|
||||||
|
* gdb.python/py-value-cc.exp: Add tests testing the methodology
|
||||||
|
exposing C++ values to Python.
|
||||||
|
* gdb.python/Makefile.in: Add py-value-cc to EXECUTABLES.
|
||||||
|
|
||||||
2012-03-19 Jan Kratochvil <jan.kratochvil@redhat.com>
|
2012-03-19 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
Siddhesh Poyarekar <siddhesh@redhat.com>
|
Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ EXECUTABLES = py-type py-value py-prettyprint py-template py-block \
|
||||||
py-symbol py-mi py-breakpoint py-inferior py-infthread \
|
py-symbol py-mi py-breakpoint py-inferior py-infthread \
|
||||||
py-shared python lib-types py-events py-evthreads py-frame \
|
py-shared python lib-types py-events py-evthreads py-frame \
|
||||||
py-mi py-pp-maint py-progspace py-section-script py-objfile \
|
py-mi py-pp-maint py-progspace py-section-script py-objfile \
|
||||||
py-finish-breakpoint py-finish-breakpoint2
|
py-finish-breakpoint py-finish-breakpoint2 py-value-cc
|
||||||
|
|
||||||
MISCELLANEOUS = py-shared-sl.sl py-events-shlib.so py-events-shlib-nodebug.so
|
MISCELLANEOUS = py-shared-sl.sl py-events-shlib.so py-events-shlib-nodebug.so
|
||||||
|
|
||||||
|
|
48
gdb/testsuite/gdb.python/py-value-cc.exp
Normal file
48
gdb/testsuite/gdb.python/py-value-cc.exp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
# Copyright (C) 2012 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. It tests the mechanism
|
||||||
|
# exposing values to Python.
|
||||||
|
|
||||||
|
if { [skip_cplus_tests] } { continue }
|
||||||
|
|
||||||
|
set testfile "py-value"
|
||||||
|
set srcfile ${testfile}.cc
|
||||||
|
set binfile ${objdir}/${subdir}/${testfile}
|
||||||
|
|
||||||
|
if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Skip all tests if Python scripting is not enabled.
|
||||||
|
if { [skip_python_tests] } { continue }
|
||||||
|
|
||||||
|
if ![runto_main] {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_breakpoint [gdb_get_line_number "Break here."]
|
||||||
|
gdb_continue_to_breakpoint "Break here" ".*Break here.*"
|
||||||
|
|
||||||
|
gdb_test "python print str(gdb.parse_and_eval(\"a\").type)" "const A &"
|
||||||
|
gdb_test "python print str(gdb.parse_and_eval(\"a\").referenced_value().type)" "const A"
|
||||||
|
gdb_test "python print str(gdb.parse_and_eval(\"int_ref\").type)" "int &"
|
||||||
|
gdb_test "python print str(gdb.parse_and_eval(\"int_ref\").referenced_value().type)" "int"
|
||||||
|
gdb_test "python print str(gdb.parse_and_eval(\"int_ref\").referenced_value())" "10"
|
||||||
|
|
||||||
|
gdb_test "python print str(gdb.parse_and_eval(\"int_ptr_ref\").dereference().type)" "int"
|
||||||
|
gdb_test "python print str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().type)" "int_ptr"
|
||||||
|
gdb_test "python print str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().dereference())" "10"
|
||||||
|
gdb_test "python print str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().referenced_value())" "10"
|
39
gdb/testsuite/gdb.python/py-value.cc
Normal file
39
gdb/testsuite/gdb.python/py-value.cc
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2012 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/>. */
|
||||||
|
|
||||||
|
class A {
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int *int_ptr;
|
||||||
|
|
||||||
|
int
|
||||||
|
func (const A &a)
|
||||||
|
{
|
||||||
|
int val = 10;
|
||||||
|
int &int_ref = val;
|
||||||
|
int_ptr ptr = &val;
|
||||||
|
int_ptr &int_ptr_ref = ptr;
|
||||||
|
|
||||||
|
return 0; /* Break here. */
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
A obj;
|
||||||
|
return func (obj);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue