This is the mail archive of the gdb-prs@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]

[Bug mi/20395] -var-update gives incorrect register values for frames 1 and above


https://sourceware.org/bugzilla/show_bug.cgi?id=20395

--- Comment #1 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Andrew Burgess <aburgess@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ae45162705fb76ee534336474a67b11373209c62

commit ae45162705fb76ee534336474a67b11373209c62
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Wed Oct 18 20:07:19 2017 +0100

    gdb: PR mi/20395: Fix -var-update for registers in frames 1 and up

    This patch fixes a problem with using the MI -var-update command
    to access the values of registers in frames other than the current
    frame.  The patch includes a test that demonstrates the problem:

    * run so there are several frames on the stack
    * create a fixed varobj for $pc in each frame, #'s 1 and above
    * step one instruction, to modify the value of $pc
    * call -var-update for each of the previously created varobjs
      to verify that they are not reported as having changed.

    Without the patch, the -var-update command reported that $pc for all
    frames 1 and above had changed to the value of $pc in frame 0.

    A varobj is created as either fixed, the expression is evaluated within
    the context of a specific frame, or floating, the expression is
    evaluated within the current frame, whatever that may be.

    When a varobj is created by -var-create we set two fields of the varobj
    to track the context in which the varobj was created, these two fields
    are varobj->root->frame and var->root->valid_block.

    If a varobj is of type fixed, then, when we subsequently try to
    reevaluate the expression associated with the varobj we must determine
    if the original frame (and block) is still available, if it is not then
    the varobj can no longer be evaluated.

    The problem is that for register expressions varobj->root->valid_block
    is not set correctly.  This block tracking is done using the global
    'innermost_block' which is set in the various parser files (for example
    c-exp.y).  However, this is not set for register expressions.

    The fix then seems like it should be to just update the innermost block
    when parsing register expressions, however, that solution causes several
    test regressions.

    The problem is that in some cases we rely on the expression parsing
    code not updating the innermost block for registers, one example is
    when we parse the expression for a 'display' command.  The display
    commands treats registers like floating varobjs, but symbols are
    treated like fixed varobjs.  So 'display $reg_name' will always show
    the value of '$reg_name' even as the user moves from frame to frame,
    while 'display my_variable' will only show 'my_variable' while it is
    in the current frame and/or block, when the user moves to a new frame
    and/or block (even one with a different 'my_variable' in) then the
    display of 'my_variable' stops.  For the case of 'display', without
    the option to force fixed or floating expressions, the current
    behaviour is probably the best choice.  For the varobj system though,
    we can choose between floating and fixed, and we should try to make
    this work for registers.

    There's only one existing test case that needs to be updated, in that
    test a fixed varobj is created using a register, the MI output now
    include the thread-id in which the varobj should be evaluated, which I
    believe is correct behaviour.  I also added a new floating test case
    into the same test script, however, right now this also includes the
    thread-id in the expected output, which I believe is an existing gdb
    bug, which I plan to fix next.

    Tested on x86_64 Linux native and native-gdbserver, no regressions.

    gdb/ChangeLog:

        PR mi/20395
        * ada-exp.y (write_var_from_sym): Pass extra parameter when
        updating innermost block.
        * parse.c (innermost_block_tracker::update): Take extra type
        parameter, and check types match before updating innermost block.
        (write_dollar_variable): Update innermost block for registers.
        * parser-defs.h (enum innermost_block_tracker_type): New enum.
        (innermost_block_tracker::innermost_block_tracker): Initialise
        m_types member.
        (innermost_block_tracker::reset): Take type parameter.
        (innermost_block_tracker::update): Take type parameter, and pass
        type through as needed.
        (innermost_block_tracker::m_types): New member.
        * varobj.c (varobj_create): Pass type when reseting innermost
        block.

    gdb/testsuite/ChangeLog:

        * gdb.mi/basics.c: Add new global.
        * gdb.mi/mi-frame-regs.exp: New file.
        * gdb.mi/mi-var-create-rtti.exp: Update expected results, add new
        case.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

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