diff options
author | Andrew Burgess <aburgess@redhat.com> | 2023-03-14 11:22:35 +0000 |
---|---|---|
committer | Andrew Burgess <aburgess@redhat.com> | 2023-04-06 14:57:32 +0100 |
commit | d2d62da62ec9c5486b19d8ffc7b4ef4070e8df7a (patch) | |
tree | 2186c1226037e7937600edd7c01b19c5592ea50d /gdb/python | |
parent | cf141dd8ccd36efe833aae3ccdb060b517cc1112 (diff) | |
download | gdb-d2d62da62ec9c5486b19d8ffc7b4ef4070e8df7a.zip gdb-d2d62da62ec9c5486b19d8ffc7b4ef4070e8df7a.tar.gz gdb-d2d62da62ec9c5486b19d8ffc7b4ef4070e8df7a.tar.bz2 |
gdb/python: have UnwindInfo.add_saved_register accept named args
Update gdb.UnwindInfo.add_saved_register to accept named keyword
arguments.
As part of this update we now use gdb_PyArg_ParseTupleAndKeywords
instead of PyArg_UnpackTuple to parse the function arguments.
By switching to gdb_PyArg_ParseTupleAndKeywords, we can now use 'O!'
as the argument format for the function's value argument. This means
that we can check the argument type (is gdb.Value) as part of the
argument processing rather than manually performing the check later in
the function. One result of this is that we now get a better error
message (at least, I think so). Previously we would get something
like:
ValueError: Bad register value
Now we get:
TypeError: argument 2 must be gdb.Value, not XXXX
It's unfortunate that the exception type changed, but I think the new
exception type actually makes more sense.
My preference for argument names is to use full words where that's not
too excessive. As such, I've updated the name of the argument from
'reg' to 'register' in the documentation, which is the argument name
I've made GDB look for here.
For existing unwinder code that doesn't throw any exceptions nothing
should change with this commit. It is possible that a user has some
code that throws and catches the ValueError, and this code will break
after this commit, but I think this is going to be sufficiently rare
that we can take the risk here.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'gdb/python')
-rw-r--r-- | gdb/python/py-unwind.c | 84 |
1 files changed, 42 insertions, 42 deletions
diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c index 409dbd3..2e13b84 100644 --- a/gdb/python/py-unwind.c +++ b/gdb/python/py-unwind.c @@ -292,7 +292,7 @@ pyuw_create_unwind_info (PyObject *pyo_pending_frame, gdb.UnwindInfo.add_saved_register (REG, VALUE) -> None. */ static PyObject * -unwind_infopy_add_saved_register (PyObject *self, PyObject *args) +unwind_infopy_add_saved_register (PyObject *self, PyObject *args, PyObject *kw) { unwind_info_object *unwind_info = (unwind_info_object *) self; pending_frame_object *pending_frame @@ -305,11 +305,15 @@ unwind_infopy_add_saved_register (PyObject *self, PyObject *args) { PyErr_SetString (PyExc_ValueError, "UnwindInfo instance refers to a stale PendingFrame"); - return NULL; + return nullptr; } - if (!PyArg_UnpackTuple (args, "previous_frame_register", 2, 2, - &pyo_reg_id, &pyo_reg_value)) - return NULL; + + static const char *keywords[] = { "register", "value", nullptr }; + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO!", keywords, + &pyo_reg_id, &value_object_type, + &pyo_reg_value)) + return nullptr; + if (!gdbpy_parse_register_id (pending_frame->gdbarch, pyo_reg_id, ®num)) return nullptr; @@ -332,43 +336,38 @@ unwind_infopy_add_saved_register (PyObject *self, PyObject *args) } } - { - struct value *value; - size_t data_size; + /* The argument parsing above guarantees that PYO_REG_VALUE will be a + gdb.Value object, as a result the value_object_to_value call should + succeed. */ + gdb_assert (pyo_reg_value != nullptr); + struct value *value = value_object_to_value (pyo_reg_value); + gdb_assert (value != nullptr); + + ULONGEST reg_size = register_size (pending_frame->gdbarch, regnum); + if (reg_size != value->type ()->length ()) + { + PyErr_Format (PyExc_ValueError, + "The value of the register returned by the Python " + "sniffer has unexpected size: %s instead of %s.", + pulongest (value->type ()->length ()), + pulongest (reg_size)); + return nullptr; + } + + gdbpy_ref<> new_value = gdbpy_ref<>::new_reference (pyo_reg_value); + bool found = false; + for (saved_reg ® : *unwind_info->saved_regs) + { + if (regnum == reg.number) + { + found = true; + reg.value = std::move (new_value); + break; + } + } + if (!found) + unwind_info->saved_regs->emplace_back (regnum, std::move (new_value)); - if (pyo_reg_value == NULL - || (value = value_object_to_value (pyo_reg_value)) == NULL) - { - PyErr_SetString (PyExc_ValueError, "Bad register value"); - return NULL; - } - data_size = register_size (pending_frame->gdbarch, regnum); - if (data_size != value->type ()->length ()) - { - PyErr_Format ( - PyExc_ValueError, - "The value of the register returned by the Python " - "sniffer has unexpected size: %u instead of %u.", - (unsigned) value->type ()->length (), - (unsigned) data_size); - return NULL; - } - } - { - gdbpy_ref<> new_value = gdbpy_ref<>::new_reference (pyo_reg_value); - bool found = false; - for (saved_reg ® : *unwind_info->saved_regs) - { - if (regnum == reg.number) - { - found = true; - reg.value = std::move (new_value); - break; - } - } - if (!found) - unwind_info->saved_regs->emplace_back (regnum, std::move (new_value)); - } Py_RETURN_NONE; } @@ -1087,7 +1086,8 @@ PyTypeObject pending_frame_object_type = static PyMethodDef unwind_info_object_methods[] = { { "add_saved_register", - unwind_infopy_add_saved_register, METH_VARARGS, + (PyCFunction) unwind_infopy_add_saved_register, + METH_VARARGS | METH_KEYWORDS, "add_saved_register (REG, VALUE) -> None\n" "Set the value of the REG in the previous frame to VALUE." }, { NULL } /* Sentinel */ |