gdb/python: new function to add values into GDB's history

The guile API has (history-append! <value>) to add values into GDB's
history list.  There is currently no equivalent in the Python API.

This commit adds gdb.add_history(<value>) to the Python API, this
function takes <value> a gdb.Value (or anything that can be passed to
the constructor of gdb.Value), and adds the value it represents to
GDB's history list.  The index of the newly added value is returned.
This commit is contained in:
Andrew Burgess 2021-07-30 12:56:34 +01:00
parent 3f1a2892e1
commit 540bf37b25
6 changed files with 77 additions and 0 deletions

View file

@ -10,6 +10,13 @@ maint show backtrace-on-fatal-signal
fatal signal. This only supported on some platforms where the
backtrace and backtrace_symbols_fd functions are available.
* Python API
** New function gdb.add_history(), which takes a gdb.Value object
and adds the value it represents to GDB's history list. An
integer, the index of the new item in the history list, is
returned.
*** Changes in GDB 11
* The 'set disassembler-options' command now supports specifying options

View file

@ -346,6 +346,20 @@ If no exception is raised, the return value is always an instance of
@code{gdb.Value} (@pxref{Values From Inferior}).
@end defun
@defun gdb.add_history (value)
Takes @var{value}, an instance of @code{gdb.Value} (@pxref{Values From
Inferior}), and appends the value this object represents to
@value{GDBN}'s value history (@pxref{Value History}), and return an
integer, its history number. If @var{value} is not a
@code{gdb.Value}, it is is converted using the @code{gdb.Value}
constructor. If @var{value} can't be converted to a @code{gdb.Value}
then a @code{TypeError} is raised.
When a command implemented in Python prints a single @code{gdb.Value}
as its result, then placing the value into the history will allow the
user convenient access to those values via CLI history facilities.
@end defun
@findex gdb.convenience_variable
@defun gdb.convenience_variable (name)
Return the value of the convenience variable (@pxref{Convenience

View file

@ -1960,6 +1960,33 @@ gdbpy_history (PyObject *self, PyObject *args)
return value_to_value_object (res_val);
}
/* Add a gdb.Value into GDB's history, and return (as an integer) the
position of the newly added value. */
PyObject *
gdbpy_add_history (PyObject *self, PyObject *args)
{
PyObject *value_obj;
if (!PyArg_ParseTuple (args, "O", &value_obj))
return nullptr;
struct value *value = convert_value_from_python (value_obj);
if (value == nullptr)
return nullptr;
try
{
int idx = record_latest_value (value);
return gdb_py_object_from_longest (idx).release ();
}
catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
return nullptr;
}
/* Return the value of a convenience variable. */
PyObject *
gdbpy_convenience_variable (PyObject *self, PyObject *args)

View file

@ -412,6 +412,7 @@ extern enum ext_lang_rc gdbpy_get_matching_xmethod_workers
PyObject *gdbpy_history (PyObject *self, PyObject *args);
PyObject *gdbpy_add_history (PyObject *self, PyObject *args);
PyObject *gdbpy_convenience_variable (PyObject *self, PyObject *args);
PyObject *gdbpy_set_convenience_variable (PyObject *self, PyObject *args);
PyObject *gdbpy_breakpoints (PyObject *, PyObject *);

View file

@ -2076,6 +2076,8 @@ PyMethodDef python_GdbMethods[] =
{
{ "history", gdbpy_history, METH_VARARGS,
"Get a value from history" },
{ "add_history", gdbpy_add_history, METH_VARARGS,
"Add a value to the value history list" },
{ "execute", (PyCFunction) execute_gdb_command, METH_VARARGS | METH_KEYWORDS,
"execute (command [, from_tty] [, to_string]) -> [String]\n\
Evaluate command, a string, as a gdb CLI command. Optionally returns\n\

View file

@ -575,6 +575,31 @@ proc test_value_from_buffer {} {
"attempt to construct value with string as type"
}
# Test the gdb.add_history API.
proc test_add_to_history {} {
# Add a gdb.Value to the value history list.
gdb_test_no_output "python idx = gdb.add_history(gdb.Value(42))" \
"add value 42 to the history list"
gdb_test "python print (\"$%d = %s\" % (idx, gdb.history (idx)))" \
" = 42" "print value 42 from the history list"
set idx [get_python_valueof "idx" "**DEFAULT**" "get idx for value 42"]
gdb_test "print \$${idx}" " = 42"
# Add something to the history list that can be converted into a
# gdb.Value.
gdb_test_no_output "python idx = gdb.add_history(84)" \
"add value to 84 to the history list"
gdb_test "python print (\"$%d = %s\" % (idx, gdb.history (idx)))" \
" = 84" "print value 84 from the history list"
set idx [get_python_valueof "idx" "**DEFAULT**" "get idx for value 84"]
gdb_test "print \$${idx}" " = 84"
# Try adding something that can't be converted to a gdb.Value,
# this should give an error.
gdb_test "python idx = gdb.add_history(gdb.GdbError(\"an error\"))" \
"TypeError: Could not convert Python object: .*"
}
# Build C version of executable. C++ is built later.
if { [build_inferior "${binfile}" "c"] < 0 } {
return -1
@ -594,6 +619,7 @@ test_objfiles
test_parse_and_eval
test_value_hash
test_float_conversion
test_add_to_history
# The following tests require execution.