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 gdb/26828] SIGSEGV in follow_die_offset dwarf2/read.c:22950
Date: Thu, 21 Jan 2021 02:05:10 +0000	[thread overview]
Message-ID: <bug-26828-4717-wZjFErFyL4@http.sourceware.org/bugzilla/> (raw)
In-Reply-To: <bug-26828-4717@http.sourceware.org/bugzilla/>

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

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

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

commit de53369b2efcae78adf431437cb096c5a0728f96
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Wed Jan 20 21:04:43 2021 -0500

    gdb/dwarf: add assertion in maybe_queue_comp_unit

    The symptom that leads to this is the crash described in PR 26828:

    /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:23478:25: runtime error:
member access within null pointer of type 'struct dwarf2_cu'

    The line of the crash is the following, in follow_die_offset:

      if (target_cu != cu)
        target_cu->ancestor = cu;  <--- HERE

    The line that assign nullptr to `target_cu` is the `per_objfile->get_cu`
    call after having called maybe_queue_comp_unit:

          /* If necessary, add it to the queue and load its DIEs.  */
          if (maybe_queue_comp_unit (cu, per_cu, per_objfile, cu->language))
            load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu
(per_cu),
                                 false, cu->language);

          target_cu = per_objfile->get_cu (per_cu);  <--- HERE

    Some background: there is an invariant, documented in
    maybe_queue_comp_unit's doc, that if a CU is queued for expansion
    (present in dwarf2_per_bfd::queue), then its DIEs are loaded in memory.
    "its DIEs are loaded in memory" is a synonym for saying that a dwarf2_cu
    object exists for this CU.  Yet another way to say it is that
    `per_objfile->get_cu (per_cu)` returns something not nullptr for that
    CU.

    The crash documented in PR 26828 triggers some hard-to-reproduce
    sequence that ends up violating the invariant:

    - dwarf2_fetch_die_type_sect_off gets called for a DIE in CU A
    - The DIE in CU A requires some DIE in CU B
    - follow_die_offset calls maybe_queue_comp_unit.  maybe_queue_comp_unit
      sees CU B is not queued and its DIEs are not loaded, so it enqueues it
      and returns 1 to its caller - meaning "the DIEs are not loaded, you
      should load them" - prompting follow_die_offset to load the DIEs by
      calling load_full_comp_unit
    - Note that CU B is enqueued by maybe_queue_comp_unit even if it has
      already been expanded.  It's a bit useless (and causes trouble, see
      next patch), but that's how it works right now.
    - Since we entered the dwarf2/read code through
      dwarf2_fetch_die_type_sect_off, nothing processes the queue, so we
      exit the dwarf2/read code with CU B still lingering in the queue.

    - dwarf2_fetch_die_type_sect_off gets called for a DIE in CU A, again
    - The DIE in CU A requires some DIE in CU B, again
    - This time, maybe_queue_comp_unit sees that CU B is in the queue.
      Because of the invariant that if a CU is in the queue, its DIEs are
      loaded in the memory, it returns 0 to its caller, meaning "you don't
      need to load the DIEs!".
    - That happens to be true, so everything is fine for now.

    - Time passes, some things call dwarf2_per_objfile::age_comp_units
      enough so that CU B's age becomes past the dwarf_max_cache_age
      threshold.  age_comp_units proceeds to free CU B's DIEs.  Remember
      that CU B is still lingering in the queue (oops, the invariant just
      got violated).

    - dwarf2_fetch_die_type_sect_off gets called for a DIE in CU A, again
    - The DIE in CU A requires some DIE in CU B, again
    - maybe_queue_comp_unit sees that CU B is in the queue, so returns to
      its caller "you don't need to load the DIEs!".  However, we know at
      this point this is false.
    - follow_die_offset doesn't load the DIEs and tries to obtain the DIEs for
      CU B:

        target_cu = per_objfile->get_cu (per_cu);

      But since they are not loaded, target_cu is nullptr, and we get the
      crash mentioned above a few lines after that.

    This patch adds an assertions in maybe_queue_comp_unit to verify the
    invariant, to make sure it doesn't return a falsehood to its caller.

    The current patch doesn't fix the issue (the next patch does), but it
    makes it so we catch the problem earlier and get this assertion failure
    instead of a segmentation fault:

        /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:9100: internal-error:
            int maybe_queue_comp_unit(dwarf2_cu*, dwarf2_per_cu_data*,
dwarf2_per_objfile*, language):
            Assertion `per_objfile->get_cu (per_cu) != nullptr' failed.

    gdb/ChangeLog:

            PR gdb/26828
            * dwarf2/read.c (maybe_queue_comp_unit): Add assertion.

    Change-Id: I4e51bd7bd58773f9fadf480179cbc4bae61508fe

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

  parent reply	other threads:[~2021-01-21  2:05 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-02 10:42 [Bug gdb/26828] New: " nilsgladitz at gmail dot com
2020-11-02 13:25 ` [Bug gdb/26828] " simark at simark dot ca
2020-11-02 15:21 ` nilsgladitz at gmail dot com
2020-11-02 15:36 ` simark at simark dot ca
2020-11-03 11:36 ` nilsgladitz at gmail dot com
2020-11-03 13:37 ` simark at simark dot ca
2020-11-03 14:03 ` simark at simark dot ca
2020-11-03 14:32 ` simark at simark dot ca
2020-11-03 15:02 ` nilsgladitz at gmail dot com
2020-11-03 17:05 ` simark at simark dot ca
2020-11-03 19:45 ` nilsgladitz at gmail dot com
2020-11-03 19:52 ` simark at simark dot ca
2020-11-03 20:14 ` nilsgladitz at gmail dot com
2020-11-03 20:52 ` simark at simark dot ca
2020-11-04  7:43 ` nilsgladitz at gmail dot com
2020-11-04 16:53 ` simark at simark dot ca
2020-11-08 16:16 ` nilsgladitz at gmail dot com
2020-11-08 16:17 ` nilsgladitz at gmail dot com
2020-11-08 16:45 ` simark at simark dot ca
2020-11-10 14:15 ` simark at simark dot ca
2020-11-13 17:03 ` cvs-commit at gcc dot gnu.org
2020-11-13 17:22 ` simark at simark dot ca
2020-11-13 18:13 ` nilsgladitz at gmail dot com
2020-11-16 18:21 ` simark at simark dot ca
2020-11-17 19:13 ` simark at simark dot ca
2021-01-21  2:05 ` cvs-commit at gcc dot gnu.org [this message]
2021-02-20 19:35 ` ReD at idp dot it
2021-02-20 20:40 ` simark at simark dot ca
2021-02-23 18:39 ` cvs-commit at gcc dot gnu.org
2021-02-23 18:39 ` cvs-commit at gcc dot gnu.org
2021-02-23 23:32 ` cvs-commit at gcc dot gnu.org
2021-02-23 23:32 ` cvs-commit at gcc dot gnu.org
2021-02-23 23:32 ` simark at simark dot ca
2021-06-27 17:58 ` ahmedsayeed1982 at yahoo dot com
2021-08-10 12:45 ` ucelsanicin at yahoo dot com
2021-09-02 11:06 ` donipah907 at mtlcz dot com
2021-09-02 11:17 ` mark at klomp dot org
2021-09-06  9:08 ` focixujo at livinginsurance dot co.uk
2021-09-10 19:39 ` mehmetgelisin at aol dot com
2021-09-22 10:19 ` diheto5497 at secbuf dot com
2021-09-22 13:58 ` ReD at idp dot it
2021-09-28  1:20 ` crownfamilydentistry at hotmail dot com
2021-10-09 11:00 ` gulsenenginar at aol dot com
2021-10-17 19:48 ` vmireskazki at gmail dot com
2021-10-19  7:15 ` progonsaytu at gmail dot com
2021-10-24 10:03 ` glassmtech at ukr dot net
2021-11-24 13:44 ` allen at rockvalleymarketing dot com

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-26828-4717-wZjFErFyL4@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).