This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] MI notification on register changes


On Wed, Nov 07, 2012 at 11:54:09AM -0700, Tom Tromey wrote:
> >>>>> "Marc" == Marc Khouzam <marc.khouzam@ericsson.com> writes:
> 
> Marc> Since GDB allows the frontend to try to avoid a full
> Marc> refresh by giving extra information in its notifications,
> Marc> the idea of continuing with that approach seemed the right one.
> Marc> For instance, GDB could have a single =breakpoints-changed
> Marc> notif which would trigger a full refresh a breakpoints.
> Marc> Same for variable objects (see -var-update).  Even
> Marc> =threads-changed (although this may be a little more
> Marc> justified if we think about it more deeply).
> 
> In some cases, like breakpoints, gdb has perfect information.
> In these situations, sending small changes is easy and efficient.
>
> For memory or registers, I think the PR established pretty clearly that
> gdb doesn't have perfect information, or at the very least, that trying
> to compute it perfectly would be a lot of work, and so it is preferable
> to avoid doing so if possible.

Computing perfect updates is not possible.

GDB would need to keep track of all memory locations and registers used
to create the representation of the value, and even that would not be
perfect in the presence of "external" sources of information like the
result of system calls or similar.
 
> For varobjs, gdb caches the previously sent data so that it can send
> deltas.

And this is not sufficient for proper display. Consider:

In .gdbinit (or similar):

    python

    class Printer(object):

        def __init__(self, val):
            self.val = val

        def to_string(self):
            return ["foo", "bar"][int(gdb.parse_and_eval("d"))]
           

        def display_hint(self):
            return 'string'


    def P(val):
        if str(val.type) == "struct S":
            return Printer(val)
        return None

    gdb.pretty_printers = [ P ]

    end



In main.c:

    int d;

    struct S { } s;

    int main()
    {
        d = 1;
        d = 0;
        d = 1;
        d = 0;
        d = 1;
        d = 0;
        d = 1;
        d = 0;
        d = 1;
        d = 0;
        d = 1;
    }


With "full refetch" you get alternating values for s when stepping:


    (gdb) display d
    1: d = 0
    (gdb) display s
    2: s = "foo"
    (gdb) n
    41          d = 0;
    2: s = "bar"
    1: d = 1
    (gdb) 
    42          d = 1;
    2: s = "foo"
    1: d = 0
    (gdb) 
    43          d = 0;
    2: s = "bar"
    1: d = 1
    (gdb) 
    44          d = 1;
    2: s = "foo"
    1: d = 0
    (gdb) 
    45          d = 0;
    2: s = "bar"
    1: d = 1
    (gdb) 

Using MI varobj's you can get something like that:

    (gdb) -var-create d * d
    ^done,name="d",numchild="0",value="0",type="int",has_more="0"
    (gdb) -var-create s * s
    ^done,name="s",numchild="0",value="{...}",type="struct S",has_more="0"

    (gdb) n
    ^running
    *running,thread-id="all"
    (gdb) 
    ~"39\t    d = 0;\n"
    *stopped,frame={addr="0x080483e9",...,line="39"},....

    (gdb) -var-update *
    ^done,changelist=[{name="d",in_scope="true",type_changed="false",has_more="0"}]

    (gdb) n
    ^running
    *running,thread-id="all"
    (gdb) 
    ~"40\t    d = 1;\n"
    *stopped,frame={addr="0x080483e9",...,line="40"},....

    (gdb) -var-update *
    ^done,changelist=[{name="d",in_scope="true",type_changed="false",has_more="0"}]


Only the changes to d are announced.  For the frontend there is no
indication whatsoever that the display of s would need to be updated.

The only way to get the proper alternating display is to fully refetch
everything again:

    (gdb) p s
    &"p s\n"
    ~"$1 = \"foo\"\n"
    ^done
    (gdb) p d
    &"p d\n"
    ~"$2 = 0"
    ~"\n"
    ^done

    (gdb) n
    &"n\n"
    ^running
    *running,thread-id="all"
    (gdb) 
    ~"41\t    d = 0;\n"
    *stopped,frame={addr="0x080483fd",...,line="41"},....
    (gdb) 
    p s
    &"p s\n"
    ~"$3 = \"bar\"\n"
    ^done
    (gdb) 



Andre'


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]