diff options
author | Siva Chandra Reddy <sivachandra@sourceware.org> | 2012-03-22 08:10:44 +0000 |
---|---|---|
committer | Siva Chandra Reddy <sivachandra@sourceware.org> | 2012-03-22 08:10:44 +0000 |
commit | 7b282c5acc13f099b11a670de50fd52a0d81ea40 (patch) | |
tree | e5bac62553f4956c81aeeb122242d209be04e978 | |
parent | 0c83539f7ebce5901201956bebd1bef925e5c5f4 (diff) | |
download | gdb-7b282c5acc13f099b11a670de50fd52a0d81ea40.zip gdb-7b282c5acc13f099b11a670de50fd52a0d81ea40.tar.gz gdb-7b282c5acc13f099b11a670de50fd52a0d81ea40.tar.bz2 |
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.
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/NEWS | 3 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 73 | ||||
-rw-r--r-- | gdb/python/py-value.c | 43 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/Makefile.in | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-value-cc.exp | 48 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-value.cc | 39 |
9 files changed, 233 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3380c2b..7c653be 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,16 @@ 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> + * MAINTAINERS (Write After Approval): Add myself to the list. 2012-03-21 Kevin Buettner <kevinb@redhat.com> @@ -25,6 +25,9 @@ frame in order to compute its value, and the latter computes the 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. E.g. (gdb) target remote | ssh myhost gdbserver - hello diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 92e3e1b..ff7786f 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -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> * gdb.texinfo (File Options): Describe --init-command=FILE, -ix and diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 677af3b..dbf1a71 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -22136,6 +22136,79 @@ bar = foo.dereference () The result @code{bar} will be a @code{gdb.Value} object holding the 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 @defun Value.dynamic_cast (type) diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index 44443e0..58513d8 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -192,6 +192,47 @@ valpy_dereference (PyObject *self, PyObject *args) 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". */ static PyObject * 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." }, { "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, METH_VARARGS | METH_KEYWORDS, "lazy_string ([encoding] [, length]) -> lazy_string\n\ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0c05576..32d5289 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -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> Siddhesh Poyarekar <siddhesh@redhat.com> diff --git a/gdb/testsuite/gdb.python/Makefile.in b/gdb/testsuite/gdb.python/Makefile.in index 5890191..cf9c142 100644 --- a/gdb/testsuite/gdb.python/Makefile.in +++ b/gdb/testsuite/gdb.python/Makefile.in @@ -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-shared python lib-types py-events py-evthreads py-frame \ 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 diff --git a/gdb/testsuite/gdb.python/py-value-cc.exp b/gdb/testsuite/gdb.python/py-value-cc.exp new file mode 100644 index 0000000..0388613 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-value-cc.exp @@ -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" diff --git a/gdb/testsuite/gdb.python/py-value.cc b/gdb/testsuite/gdb.python/py-value.cc new file mode 100644 index 0000000..65a784c --- /dev/null +++ b/gdb/testsuite/gdb.python/py-value.cc @@ -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); +} |