Fix register-setting response from DAP

Andry noticed that given a DAP setExpression request, where the
expression to set is a register, DAP will return the wrong value -- it
will return the old value, not the updated one.

This happens because gdb.Value.assign (which was recently added for
DAP) does not update the value.

In this patch, I chose to have the assign method update the Value
in-place.  It's also possible to have it return a new value, but this
didn't seem very useful to me.
This commit is contained in:
Tom Tromey
2023-10-04 12:58:32 -06:00
parent fd00374fc7
commit 138c7d2661
2 changed files with 29 additions and 4 deletions

View File

@@ -905,7 +905,13 @@ valpy_assign (PyObject *self_obj, PyObject *args)
try try
{ {
value_object *self = (value_object *) self_obj; value_object *self = (value_object *) self_obj;
value_assign (self->value, val); value *new_value = value_assign (self->value, val);
/* value_as_address returns a new value with the same location
as the old one. Ensure that this gdb.Value is updated to
reflect the new value. */
new_value->incref ();
self->value->decref ();
self->value = new_value;
} }
catch (const gdb_exception &except) catch (const gdb_exception &except)
{ {

View File

@@ -125,8 +125,27 @@ gdb_assert {[llength $deivals] == 2} "dei has two members"
set num [dict get $reg_scope variablesReference] set num [dict get $reg_scope variablesReference]
# The request succeeding is sufficient. # The request succeeding is sufficient.
dap_check_request_and_response "fetch first register" \ set val [dap_check_request_and_response "fetch first register" \
"variables" \ "variables" \
[format {o variablesReference [i %d] count [i 1]} $num] [format {o variablesReference [i %d] count [i 1]} $num]]
# Try setting the value to something else.
set val [dict get [lindex $val 0] body variables]
set name [dict get [lindex $val 0] name]
set val [dict get [lindex $val 0] value]
# Just make sure it is different from the original value.
set val [expr {$val ^ 7}]
# setVariable isn't implemented yet, so use the register name. Note
# that we sneak the "$" into the name, written in a slightly funny way
# to work around apparent TON limitations.
set response [dap_check_request_and_response "set first register" \
setExpression \
[format {o expression [s \$%s] value [s %d] frameId [i %d]} \
$name $val $frame_id]]
set response [lindex $response 0]
gdb_assert {[dict get $response body value] == $val} \
"setting register yields updated value"
dap_shutdown dap_shutdown