GDBMI_var_update.st
author Jan Vrany <jan.vrany@labware.com>
Thu, 07 Dec 2023 12:33:31 +0000
changeset 322 1b26d0a9560c
parent 272 cdd1c9ad00de
permissions -rw-r--r--
Emit and handle (custom) `-register-changed` notification This commit adds new (custom) asynchronous notification about register value being changed. Standard GDB does not notify MI clients about register value being changed when debugging (for example, by CLI command `set $rax = 1` or via Python's `Value.assign()`). This caused libgdb's register value cache being out of sync. In the past, this was partially worked around by manually emiting the notification on `GDBRegisterWithValue` APIs, but this did not (and could not) handle the case register was changed from GDB command line. To solve this problem, this commit installs a custom Python event handler that emits new GDB/MI notification - `-register-changed` - whenever a register changes after debugee is stopped. This has been enabled by upstream GDB commit 4825fd "gdb/python: implement support for sending custom MI async notifications" On libgdbs side, complete inferior state is invalidated. In theory, one could carefully invalidate only the changed `GDBRegisterWithValue` but in certain cases this could also change the backtrace (for example, if one updates stack pointer) or position in code. So it seems safer to just invalidate everything.

"
jv:libgdbs - GNU Debugger Interface Library
Copyright (C) 2015-now Jan Vrany
Copyright (C) 2022-2023 LabWare

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the 'Software'), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"
"{ Package: 'jv:libgdbs' }"

"{ NameSpace: Smalltalk }"

GDBMICommand subclass:#GDBMI_var_update
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'GDB-Commands-MI'
!

!GDBMI_var_update class methodsFor:'documentation'!

copyright
"
jv:libgdbs - GNU Debugger Interface Library
Copyright (C) 2015-now Jan Vrany
Copyright (C) 2022-2023 LabWare

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the 'Software'), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"
!

documentation
"
The `-var-update' Command
-------------------------

Synopsis
........

      -var-update [PRINT-VALUES] {NAME | '*'}

   Reevaluate the expressions corresponding to the variable object NAME
and all its direct and indirect children, and return the list of
variable objects whose values have changed; NAME must be a root
variable object.  Here, 'changed' means that the result of
`-var-evaluate-expression' before and after the `-var-update' is
different.  If `*' is used as the variable object names, all existing
variable objects are updated, except for frozen ones (*note
-var-set-frozen::).  The option PRINT-VALUES determines whether both
names and values, or just names are printed.  The possible values of
this option are the same as for `-var-list-children' (*note
-var-list-children::).  It is recommended to use the `--all-values'
option, to reduce the number of MI commands needed on each program stop.

   With the `*' parameter, if a variable object is bound to a currently
running thread, it will not be updated, without any diagnostic.

   If `-var-set-update-range' was previously used on a varobj, then
only the selected range of children will be reported.

   `-var-update' reports all the changed varobjs in a tuple named
`changelist'.

   Each item in the change list is itself a tuple holding:

`name'
     The name of the varobj.

`value'
     If values were requested for this update, then this field will be
     present and will hold the value of the varobj.

`in_scope'
     This field is a string which may take one of three values:

    `'true''
          The variable object's current value is valid.

    `'false''
          The variable object does not currently hold a valid value but
          it may hold one in the future if its associated expression
          comes back into scope.

    `'invalid''
          The variable object no longer holds a valid value.  This can
          occur when the executable file being debugged has changed,
          either through recompilation or by using the {No value for
          `GDBN'} `file' command.  The front end should normally choose
          to delete these variable objects.

     In the future new values may be added to this list so the front
     should be prepared for this possibility.  *Note GDB/MI Development
     and Front Ends: GDB/MI Development and Front Ends.

`type_changed'
     This is only present if the varobj is still valid.  If the type
     changed, then this will be the string `true'; otherwise it will be
     `false'.

     When a varobj's type changes, its children are also likely to have
     become incorrect.  Therefore, the varobj's children are
     automatically deleted when this attribute is `true'.  Also, the
     varobj's update range, when set using the `-var-set-update-range'
     command, is unset.

`new_type'
     If the varobj's type changed, then this field will be present and
     will hold the new type.

`new_num_children'
     For a dynamic varobj, if the number of children changed, or if the
     type changed, this will be the new number of children.

     The `numchild' field in other varobj responses is generally not
     valid for a dynamic varobj - it will show the number of children
     that {No value for `GDBN'} knows about, but because dynamic
     varobjs lazily instantiate their children, this will not reflect
     the number of children which may be available.

     The `new_num_children' attribute only reports changes to the
     number of children known by {No value for `GDBN'}.  This is the
     only way to detect whether an update has removed children (which
     necessarily can only happen at the end of the update range).

`displayhint'
     The display hint, if any.

`has_more'
     This is an integer value, which will be 1 if there are more
     children available outside the varobj's update range.

`dynamic'
     This attribute will be present and have the value `1' if the
     varobj is a dynamic varobj.  If the varobj is not a dynamic varobj,
     then this attribute will not be present.

`new_children'
     If new children were added to a dynamic varobj within the selected
     update range (as set by `-var-set-update-range'), then they will
     be listed in this attribute.

Example
.......

     (gdb)
     -var-assign var1 3
     ^done,value='3'
     (gdb)
     -var-update --all-values var1
     ^done,changelist=[{name='var1',value='3',in_scope='true',
     type_changed='false'}]
     (gdb)


"
! !

!GDBMI_var_update methodsFor:'accessing'!

operation
	^ 'var-update'
! !

!GDBMI_var_update methodsFor:'accessing-descriptors'!

resultDescription
    ^ (super resultDescription)
        define: #changelist as: Array of: GDBVariableObjectChange;
        yourself

    "Created: / 29-01-2018 / 20:30:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !