public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
From: "cvs-commit at gcc dot gnu.org" <sourceware-bugzilla@sourceware.org>
To: gdb-prs@sourceware.org
Subject: [Bug exp/26875] Incorrect value printed for address of first element of zero-length array
Date: Wed, 09 Dec 2020 21:34:25 +0000	[thread overview]
Message-ID: <bug-26875-4717-AwTqoEFAsf@http.sourceware.org/bugzilla/> (raw)
In-Reply-To: <bug-26875-4717@http.sourceware.org/bugzilla/>

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

--- Comment #15 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The gdb-10-branch branch has been updated by Simon Marchi
<simark@sourceware.org>:

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

commit 138084b24811c191a85c919116d839a8bd89d57c
Author: Simon Marchi <simon.marchi@efficios.com>
Date:   Wed Dec 9 13:52:12 2020 -0500

    gdb: fix value_subscript when array upper bound is not known

    Since commit 7c6f27129631 ("gdb: make get_discrete_bounds check for
    non-constant range bounds"), subscripting  flexible array member fails:

        struct no_size
        {
          int n;
          int items[];
        };

        (gdb) p *ns
        $1 = {n = 3, items = 0x5555555592a4}
        (gdb) p ns->items[0]
        Cannot access memory at address 0xfffe555b733a0164
        (gdb) p *((int *) 0x5555555592a4)
        $2 = 101  <--- we would expect that
        (gdb) p &ns->items[0]
        $3 = (int *) 0xfffe5559ee829a24  <--- wrong address

    Since the flexible array member (items) has an unspecified size, the array
type
    created for it in the DWARF doesn't have dimensions (this is with gcc
9.3.0,
    Ubuntu 20.04):

        0x000000a4:   DW_TAG_array_type
                        DW_AT_type [DW_FORM_ref4]       (0x00000038 "int")
                        DW_AT_sibling [DW_FORM_ref4]    (0x000000b3)

        0x000000ad:     DW_TAG_subrange_type
                          DW_AT_type [DW_FORM_ref4]     (0x00000031 "long
unsigned int")

    This causes GDB to create a range type (TYPE_CODE_RANGE) with a defined
    constant low bound (dynamic_prop with kind PROP_CONST) and an undefined
    high bound (dynamic_prop with kind PROP_UNDEFINED).

    value_subscript gets both bounds of that range using
    get_discrete_bounds.  Before commit 7c6f27129631, get_discrete_bounds
    didn't check the kind of the dynamic_props and would just blindly read
    them as if they were PROP_CONST.  It would return 0 for the high bound,
    because we zero-initialize the range_bounds structure.  And it didn't
    really matter in this case, because the returned high bound wasn't used
    in the end.

    Commit 7c6f27129631 changed get_discrete_bounds to return a failure if
    either the low or high bound is not a constant, to make sure we don't
    read a dynamic prop that isn't a PROP_CONST as a PROP_CONST.  This
    change made get_discrete_bounds start to return a failure for that
    range, and as a result would not set *lowp and *highp.  And since
    value_subscript doesn't check get_discrete_bounds' return value, it just
    carries on an uses an uninitialized value for the low bound.  If
    value_subscript did check the return value of get_discrete_bounds, we
    would get an error message instead of a bogus value.  But it would still
    be a bug, as we wouldn't be able to print the flexible array member's
    elements.

    Looking at value_subscript, we see that the low bound is always needed,
    but the high bound is only needed if !c_style.  So, change
    value_subscript to use get_discrete_low_bound and
    get_discrete_high_bound separately.  This fixes the case described
    above, where the low bound is known but the high bound isn't (and is not
    needed).  This restores the original behavior without accessing a
    dynamic_prop in a wrong way.

    A test is added.  In addition to the case described above, a case with
    an array member of size 0 is added, which is a GNU C extension that
    existed before flexible array members were introduced.  That case
    currently fails when compiled with gcc <= 8.  gcc <= 8 produces DWARF
    similar to the one shown above, while gcc 9 adds a DW_AT_count of 0 in
    there, which makes the high bound known.  A case where an array member
    of size 0 is the only member of the struct is also added, as that was
    how PR 28675 was originally reported, and it's an interesting corner
    case that I think could trigger other funny bugs.

    Question about the implementation: in value_subscript, I made it such
    that if the low or high bound is unknown, we fall back to zero.  That
    effectively makes it the same as it was before 7c6f27129631.  But should
    we instead error() out?

    gdb/ChangeLog:

            PR 26875, PR 26901
            * gdbtypes.c (get_discrete_low_bound): Make non-static.
            (get_discrete_high_bound): Make non-static.
            * gdbtypes.h (get_discrete_low_bound): New declaration.
            (get_discrete_high_bound): New declaration.
            * valarith.c (value_subscript): Only fetch high bound if
            necessary.

    gdb/testsuite/ChangeLog:

            PR 26875, PR 26901
            * gdb.base/flexible-array-member.c: New test.
            * gdb.base/flexible-array-member.exp: New test.

    Change-Id: I832056f80e6c56f621f398b4780d55a3a1e299d7

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

  parent reply	other threads:[~2020-12-09 21:34 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-13  9:32 [Bug exp/26875] New: " vries at gcc dot gnu.org
2020-11-13 10:33 ` [Bug exp/26875] " vries at gcc dot gnu.org
2020-11-13 10:53 ` vries at gcc dot gnu.org
2020-11-13 14:47 ` vries at gcc dot gnu.org
2020-11-13 16:52 ` vries at gcc dot gnu.org
2020-11-14 11:45 ` vries at gcc dot gnu.org
2020-11-14 12:04 ` vries at gcc dot gnu.org
2020-11-20 18:00 ` simark at simark dot ca
2020-11-20 18:03 ` simark at simark dot ca
2020-11-20 18:07 ` simark at simark dot ca
2020-11-20 18:17 ` simark at simark dot ca
2020-11-20 22:16 ` vries at gcc dot gnu.org
2020-11-20 22:25 ` simark at simark dot ca
2020-11-23 16:25 ` simark at simark dot ca
2020-12-09 18:53 ` cvs-commit at gcc dot gnu.org
2020-12-09 21:34 ` cvs-commit at gcc dot gnu.org [this message]
2020-12-09 22:11 ` simark at simark dot ca
2021-10-13 14:22 ` vries at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-26875-4717-AwTqoEFAsf@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=gdb-prs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).