gdb/python: allow Frame.read_var to accept named arguments
This commit allows Frame.read_var to accept named arguments, and also improves (I think) some of the error messages emitted when values of the wrong type are passed to this function. The read_var method takes two arguments, one a variable, which is either a gdb.Symbol or a string, while the second, optional, argument is always a gdb.Block. I'm now using 'O!' as the format specifier for the second argument, which allows the argument type to be checked early on. Currently, if the second argument is of the wrong type then we get this error: (gdb) python print(gdb.selected_frame().read_var("a1", "xxx")) Traceback (most recent call last): File "<string>", line 1, in <module> RuntimeError: Second argument must be block. Error while executing Python code. (gdb) After this commit, we now get an error like this: (gdb) python print(gdb.selected_frame().read_var("a1", "xxx")) Traceback (most recent call last): File "<string>", line 1, in <module> TypeError: argument 2 must be gdb.Block, not str Error while executing Python code. (gdb) Changes are: 1. Exception type is TypeError not RuntimeError, this is unfortunate as user code _could_ be relying on this, but I think the improvement is worth the risk, user code relying on the exact exception type is likely to be pretty rare, 2. New error message gives argument position and expected argument type, as well as the type that was passed. If the first argument, the variable, has the wrong type then the previous exception was already a TypeError, however, I've updated the text of the exception to more closely match the "standard" error message we see above. If the first argument has the wrong type then before this commit we saw this: (gdb) python print(gdb.selected_frame().read_var(123)) Traceback (most recent call last): File "<string>", line 1, in <module> TypeError: Argument must be a symbol or string. Error while executing Python code. (gdb) And after we see this: (gdb) python print(gdb.selected_frame().read_var(123)) Traceback (most recent call last): File "<string>", line 1, in <module> TypeError: argument 1 must be gdb.Symbol or str, not int Error while executing Python code. (gdb) For existing code that doesn't use named arguments and doesn't rely on exceptions, there will be no changes after this commit. Reviewed-By: Tom Tromey <tom@tromey.com>
This commit is contained in:
parent
02c7fce1ad
commit
d344cef4bf
2 changed files with 49 additions and 13 deletions
|
@ -475,15 +475,18 @@ frapy_find_sal (PyObject *self, PyObject *args)
|
|||
gdb.Symbol. The block argument must be an instance of gdb.Block. Returns
|
||||
NULL on error, with a python exception set. */
|
||||
static PyObject *
|
||||
frapy_read_var (PyObject *self, PyObject *args)
|
||||
frapy_read_var (PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
frame_info_ptr frame;
|
||||
PyObject *sym_obj, *block_obj = NULL;
|
||||
struct symbol *var = NULL; /* gcc-4.3.2 false warning. */
|
||||
const struct block *block = NULL;
|
||||
|
||||
if (!PyArg_ParseTuple (args, "O|O", &sym_obj, &block_obj))
|
||||
return NULL;
|
||||
static const char *keywords[] = { "variable", "block", nullptr };
|
||||
if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O|O!", keywords,
|
||||
&sym_obj, &block_object_type,
|
||||
&block_obj))
|
||||
return nullptr;
|
||||
|
||||
if (PyObject_TypeCheck (sym_obj, &symbol_object_type))
|
||||
var = symbol_object_to_symbol (sym_obj);
|
||||
|
@ -495,15 +498,13 @@ frapy_read_var (PyObject *self, PyObject *args)
|
|||
if (!var_name)
|
||||
return NULL;
|
||||
|
||||
if (block_obj)
|
||||
if (block_obj != nullptr)
|
||||
{
|
||||
/* This call should only fail if the type of BLOCK_OBJ is wrong,
|
||||
and we ensure the type is correct when we parse the arguments,
|
||||
so we can just assert the return value is not nullptr. */
|
||||
block = block_object_to_block (block_obj);
|
||||
if (!block)
|
||||
{
|
||||
PyErr_SetString (PyExc_RuntimeError,
|
||||
_("Second argument must be block."));
|
||||
return NULL;
|
||||
}
|
||||
gdb_assert (block != nullptr);
|
||||
}
|
||||
|
||||
try
|
||||
|
@ -533,8 +534,9 @@ frapy_read_var (PyObject *self, PyObject *args)
|
|||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString (PyExc_TypeError,
|
||||
_("Argument must be a symbol or string."));
|
||||
PyErr_Format (PyExc_TypeError,
|
||||
_("argument 1 must be gdb.Symbol or str, not %s"),
|
||||
Py_TYPE (sym_obj)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -787,7 +789,7 @@ Return the frame called by this frame." },
|
|||
{ "find_sal", frapy_find_sal, METH_NOARGS,
|
||||
"find_sal () -> gdb.Symtab_and_line.\n\
|
||||
Return the frame's symtab and line." },
|
||||
{ "read_var", frapy_read_var, METH_VARARGS,
|
||||
{ "read_var", (PyCFunction) frapy_read_var, METH_VARARGS | METH_KEYWORDS,
|
||||
"read_var (variable) -> gdb.Value.\n\
|
||||
Return the value of the variable in this frame." },
|
||||
{ "select", frapy_select, METH_NOARGS,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue