aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Biesinger <cbiesinger@google.com>2019-08-01 17:22:28 -0500
committerChristian Biesinger <cbiesinger@google.com>2019-08-05 13:06:18 -0500
commit0b27c27d0d3060171876736f05c39f9c86a65d3e (patch)
treee9ea50193b9ee06ba7468ee9bce4440343286c51
parent4ee94178afbe062bc244d28595f86d63633a7af7 (diff)
downloadgdb-0b27c27d0d3060171876736f05c39f9c86a65d3e.zip
gdb-0b27c27d0d3060171876736f05c39f9c86a65d3e.tar.gz
gdb-0b27c27d0d3060171876736f05c39f9c86a65d3e.tar.bz2
Add block['var'] accessor
Currently we support iteration on blocks; this patch extends that to make subscript access work as well. gdb/ChangeLog: 2019-08-05 Christian Biesinger <cbiesinger@google.com> * NEWS: Mention dictionary access on blocks. * python/py-block.c (blpy_getitem): New function. (block_object_as_mapping): New struct. (block_object_type): Use new struct for tp_as_mapping field. gdb/doc/ChangeLog: 2019-08-05 Christian Biesinger <cbiesinger@google.com> * python.texi (Blocks In Python): Document dictionary access on blocks. gdb/testsuite/ChangeLog: 2019-08-05 Christian Biesinger <cbiesinger@google.com> * gdb.python/py-block.exp: Test dictionary access on blocks.
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/NEWS3
-rw-r--r--gdb/doc/ChangeLog4
-rw-r--r--gdb/doc/python.texi7
-rw-r--r--gdb/python/py-block.c45
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.python/py-block.exp5
7 files changed, 73 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index da1d636..b17b252 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
2019-08-05 Christian Biesinger <cbiesinger@google.com>
+ * NEWS: Mention dictionary access on blocks.
+ * python/py-block.c (blpy_getitem): New function.
+ (block_object_as_mapping): New struct.
+ (block_object_type): Use new struct for tp_as_mapping field.
+
+2019-08-05 Christian Biesinger <cbiesinger@google.com>
+
* objfiles.h (objfile): Add a comment describing partial symbols.
2019-08-05 Tom Tromey <tromey@adacore.com>
diff --git a/gdb/NEWS b/gdb/NEWS
index da641cb..b4c59e4 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -47,6 +47,9 @@
** gdb.Objfile has new methods 'lookup_global_symbol' and
'lookup_static_symbol' to lookup a symbol from this objfile only.
+ ** gdb.Block now supports the dictionary syntax for accessing symbols in
+ this block (e.g. block['local_variable']).
+
* New commands
| [COMMAND] | SHELL_COMMAND
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 95fd22c..6faf5f3 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,7 @@
+2019-08-05 Christian Biesinger <cbiesinger@google.com>
+
+ * python.texi (Blocks In Python): Document dictionary access on blocks.
+
2019-08-03 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* gdb.texinfo (Symbols): Document new args -dirname and -basename
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 3fdccd5..832283d 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -4722,7 +4722,12 @@ A @code{gdb.Block} is iterable. The iterator returns the symbols
should not assume that a specific block object will always contain a
given symbol, since changes in @value{GDBN} features and
infrastructure may cause symbols move across blocks in a symbol
-table.
+table. You can also use Python's @dfn{dictionary syntax} to access
+variables in this block, e.g.:
+
+@smallexample
+symbol = some_block['variable'] # symbol is of type gdb.Symbol
+@end smallexample
The following block-related functions are available in the @code{gdb}
module:
diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c
index 90140eb..4dc47ff 100644
--- a/gdb/python/py-block.c
+++ b/gdb/python/py-block.c
@@ -224,6 +224,43 @@ blpy_is_static (PyObject *self, void *closure)
Py_RETURN_FALSE;
}
+/* Given a string, returns the gdb.Symbol representing that symbol in this
+ block. If such a symbol does not exist, returns NULL with a Python
+ exception. */
+
+static PyObject *
+blpy_getitem (PyObject *self, PyObject *key)
+{
+ const struct block *block;
+
+ BLPY_REQUIRE_VALID (self, block);
+
+ gdb::unique_xmalloc_ptr<char> name = python_string_to_host_string (key);
+ if (name == nullptr)
+ return nullptr;
+
+ lookup_name_info lookup_name (name.get(), symbol_name_match_type::FULL);
+
+ /* We use ALL_BLOCK_SYMBOLS_WITH_NAME instead of block_lookup_symbol so
+ that we can look up symbols irrespective of the domain, matching the
+ iterator. It would be confusing if the iterator returns symbols you
+ can't find via getitem. */
+ struct block_iterator iter;
+ struct symbol *sym = nullptr;
+ ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
+ {
+ /* Just stop at the first match */
+ break;
+ }
+
+ if (sym == nullptr)
+ {
+ PyErr_SetObject (PyExc_KeyError, key);
+ return nullptr;
+ }
+ return symbol_to_symbol_object (sym);
+}
+
static void
blpy_dealloc (PyObject *obj)
{
@@ -440,6 +477,12 @@ static gdb_PyGetSetDef block_object_getset[] = {
{ NULL } /* Sentinel */
};
+static PyMappingMethods block_object_as_mapping = {
+ NULL,
+ blpy_getitem,
+ NULL
+};
+
PyTypeObject block_object_type = {
PyVarObject_HEAD_INIT (NULL, 0)
"gdb.Block", /*tp_name*/
@@ -453,7 +496,7 @@ PyTypeObject block_object_type = {
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
+ &block_object_as_mapping, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 236c0e2..1a2cb0b 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2019-08-05 Christian Biesinger <cbiesinger@google.com>
+
+ * gdb.python/py-block.exp: Test dictionary access on blocks.
+
2019-08-05 Simon Marchi <simon.marchi@efficios.com>
PR gdb/24863
diff --git a/gdb/testsuite/gdb.python/py-block.exp b/gdb/testsuite/gdb.python/py-block.exp
index 20d3968..6be1abe 100644
--- a/gdb/testsuite/gdb.python/py-block.exp
+++ b/gdb/testsuite/gdb.python/py-block.exp
@@ -43,6 +43,11 @@ gdb_test "python print (block)" "<gdb.Block object at $hex>" "check block not No
gdb_test "python print (block.function)" "None" "first anonymous block"
gdb_test "python print (block.start)" "${decimal}" "check start not None"
gdb_test "python print (block.end)" "${decimal}" "check end not None"
+gdb_test "python print (block\['f'\].name == 'f')" "True" "check variable access"
+gdb_test "python print (block\['nonexistent'\])" ".*KeyError: 'nonexistent'.*" \
+ "check nonexistent variable"
+gdb_test "python print (block\[42\])" ".*TypeError: Expected a string.*" \
+ "check non-string key"
# Test global/static blocks
gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0