public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
* [Bug gdb/26693] New: [gdb-10] regression: loading dwarf info crashes the debugger
@ 2020-10-01 14:26 mihails.strasuns at intel dot com
  2020-10-08 16:32 ` [Bug gdb/26693] " simark at simark dot ca
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: mihails.strasuns at intel dot com @ 2020-10-01 14:26 UTC (permalink / raw)
  To: gdb-prs

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

            Bug ID: 26693
           Summary: [gdb-10] regression: loading dwarf info crashes the
                    debugger
           Product: gdb
           Version: 10.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: gdb
          Assignee: unassigned at sourceware dot org
          Reporter: mihails.strasuns at intel dot com
  Target Milestone: ---

To reproduce:

1) Download and unpack this libtbb build:
https://github.com/oneapi-src/oneTBB/releases/tag/v2020.3
2) Open the distribured shared library in the debugger: gdb -q
/path/to/unpacked/tbb/lib/intel64/gcc4.8/libtbb.so

On current gdb-10 release candidate branch the debugger crashes immediately
when loading the library.

Regression was bisected to the following commit:

7188ed02d2a7e3fce00a0214e70457c5ef56df6b Replace dwarf2_per_cu_data::cu
backlink with per-objfile map

>From an initial investigation it looks like two distinct dwarf2_cu objects are
being created for the same CU and one of them does not have a die hash table
initialized, which causes a segmentation fault eventually when used.

Note: it is not clear yet what exact compiler output is causing this - the very
same library works when recompiled manually on my system, only github binary
release crashes. Trying to learn what build env was used for the latter.

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug gdb/26693] [gdb-10] regression: loading dwarf info crashes the debugger
  2020-10-01 14:26 [Bug gdb/26693] New: [gdb-10] regression: loading dwarf info crashes the debugger mihails.strasuns at intel dot com
@ 2020-10-08 16:32 ` simark at simark dot ca
  2020-10-08 16:32 ` simark at simark dot ca
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: simark at simark dot ca @ 2020-10-08 16:32 UTC (permalink / raw)
  To: gdb-prs

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

Simon Marchi <simark at simark dot ca> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |simark at simark dot ca

--- Comment #1 from Simon Marchi <simark at simark dot ca> ---
Ok, so the problem indeed seem to be that:

1. We create a first reader containing a new dwarf2_cu to read partial symbols,
in process_psymtab_comp_unit
2. At this point:

#1  0x000055555d4cea0d in partial_die_full_name (pdi=0x62100033d880,
cu=0x615000025380) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8443
#2  0x000055555d4ceec1 in add_partial_symbol (pdi=0x62100033d880,
cu=0x615000025380) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8471
#3  0x000055555d4d1ed4 in add_partial_subprogram (pdi=0x62100033d880,
lowpc=0x7fffffffc5b0, highpc=0x7fffffffc5d0, set_addrmap=0, cu=0x615000025380)
at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8739
#4  0x000055555d4cc7a4 in scan_partial_symbols (first_die=0x621000321510,
lowpc=0x7fffffffc5b0, highpc=0x7fffffffc5d0, set_addrmap=0, cu=0x615000025380)
at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8232
#5  0x000055555d4c2f87 in process_psymtab_comp_unit_reader
(reader=0x7fffffffc6a0, info_ptr=0x7fffde57fda5 "\002std",
comp_unit_die=0x621000319d10, pretend_language=language_minimal) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7616
#6  0x000055555d4c4b74 in process_psymtab_comp_unit (this_cu=0x62100021fe30,
per_objfile=0x613000009f80, want_partial_unit=false,
pretend_language=language_minimal) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7714

... we realize that we'll need to load full symbols.  See this comment in
partial_die_full_name:

  /* If this is a template instantiation, we can not work out the
     template arguments from partial DIEs.  So, unfortunately, we have
     to go through the full DIEs.  At least any work we do building
     types here will be reused if full symbols are loaded later.  */

3. We make a dummy die_info that references (DW_FORM_ref_addr) the full DIE we
are interested in, and call follow_die_ref on it. In follow_die_offset, it ends
up calling load_full_comp_unit.
4. load_full_comp_unit creates a second reader.  In the working case, it finds
that we have an existing dwarf2_cu for this_cu.  In the failing case, it
doesn't find one, so the reader creates a brand new dwarf2_cu.
5. The dies and die_hash get created in that second dwarf2_cu, which gets
thrown out.
6. Back to the caller in follow_die_offset, it expects that load_full_comp_unit
will have filled target_cu->dies and target_cu->die_hash.  But nope, because
load_full_comp_unit did that in a separate dwarf2_cu instead of the same as
target_cu points to.

Normally, load_full_comp_unit should see that we have an existing dwarf2_cu for
"this_cu" already and use it.

Pre-regression, it worked because the dwarf2_cu matching a dwarf2_per_cu_data
was saved in the dwarf2_per_cu_data directly.  So load_full_comp_unit would
find it there.

Now, we look up the objfile with:

  per_objfile->get_cu (per_cu)

However, at this point, the first dwarf2_cu was not saved in per_objfile yet,
so we don't find it.

In follow_die_offset, we already have the dwarf2_cu that we know matches the
per_cu.  So we could just pass it down to load_full_comp_unit.  I'll attach a
patch that does that, it fixes the crash for me (although I didn't check for
other regressions yet).

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug gdb/26693] [gdb-10] regression: loading dwarf info crashes the debugger
  2020-10-01 14:26 [Bug gdb/26693] New: [gdb-10] regression: loading dwarf info crashes the debugger mihails.strasuns at intel dot com
  2020-10-08 16:32 ` [Bug gdb/26693] " simark at simark dot ca
@ 2020-10-08 16:32 ` simark at simark dot ca
  2020-10-08 17:20 ` simark at simark dot ca
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: simark at simark dot ca @ 2020-10-08 16:32 UTC (permalink / raw)
  To: gdb-prs

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

--- Comment #2 from Simon Marchi <simark at simark dot ca> ---
Created attachment 12893
  --> https://sourceware.org/bugzilla/attachment.cgi?id=12893&action=edit
Proposed patch v1

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug gdb/26693] [gdb-10] regression: loading dwarf info crashes the debugger
  2020-10-01 14:26 [Bug gdb/26693] New: [gdb-10] regression: loading dwarf info crashes the debugger mihails.strasuns at intel dot com
  2020-10-08 16:32 ` [Bug gdb/26693] " simark at simark dot ca
  2020-10-08 16:32 ` simark at simark dot ca
@ 2020-10-08 17:20 ` simark at simark dot ca
  2020-10-09  3:36 ` simark at simark dot ca
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: simark at simark dot ca @ 2020-10-08 17:20 UTC (permalink / raw)
  To: gdb-prs

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

Simon Marchi <simark at simark dot ca> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|---                         |10.1

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug gdb/26693] [gdb-10] regression: loading dwarf info crashes the debugger
  2020-10-01 14:26 [Bug gdb/26693] New: [gdb-10] regression: loading dwarf info crashes the debugger mihails.strasuns at intel dot com
                   ` (2 preceding siblings ...)
  2020-10-08 17:20 ` simark at simark dot ca
@ 2020-10-09  3:36 ` simark at simark dot ca
  2020-10-12 18:06 ` mihails.strasuns at intel dot com
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: simark at simark dot ca @ 2020-10-09  3:36 UTC (permalink / raw)
  To: gdb-prs

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

Simon Marchi <simark at simark dot ca> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
  Attachment #12893|0                           |1
        is obsolete|                            |

--- Comment #3 from Simon Marchi <simark at simark dot ca> ---
Created attachment 12894
  --> https://sourceware.org/bugzilla/attachment.cgi?id=12894&action=edit
Proposed patch v2 - now with a test!

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug gdb/26693] [gdb-10] regression: loading dwarf info crashes the debugger
  2020-10-01 14:26 [Bug gdb/26693] New: [gdb-10] regression: loading dwarf info crashes the debugger mihails.strasuns at intel dot com
                   ` (3 preceding siblings ...)
  2020-10-09  3:36 ` simark at simark dot ca
@ 2020-10-12 18:06 ` mihails.strasuns at intel dot com
  2020-10-22 14:46 ` cvs-commit at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: mihails.strasuns at intel dot com @ 2020-10-12 18:06 UTC (permalink / raw)
  To: gdb-prs

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

--- Comment #4 from Mihails Strasuns <mihails.strasuns at intel dot com> ---
The fix works for me in the original repro case. Can't verify any side effects
yet, because I have found a new regression in gdb-10 branch after the fix
unblocked it - will submit that soon.

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug gdb/26693] [gdb-10] regression: loading dwarf info crashes the debugger
  2020-10-01 14:26 [Bug gdb/26693] New: [gdb-10] regression: loading dwarf info crashes the debugger mihails.strasuns at intel dot com
                   ` (4 preceding siblings ...)
  2020-10-12 18:06 ` mihails.strasuns at intel dot com
@ 2020-10-22 14:46 ` cvs-commit at gcc dot gnu.org
  2020-10-22 14:50 ` cvs-commit at gcc dot gnu.org
  2020-10-22 14:55 ` simark at simark dot ca
  7 siblings, 0 replies; 9+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2020-10-22 14:46 UTC (permalink / raw)
  To: gdb-prs

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

--- Comment #5 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=4a636814934b4403baeffbf29af44ed3a3cb2962

commit 4a636814934b4403baeffbf29af44ed3a3cb2962
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Thu Oct 22 10:27:39 2020 -0400

    gdb/dwarf: fix reading subprogram with DW_AT_specification (PR gdb/26693)

    Fix a regression introduced by commit 7188ed02d2a7 ("Replace
    dwarf2_per_cu_data::cu backlink with per-objfile map").

    This patch targets both master and gdb-10-branch, since this is a
    regression from GDB 9.

    Analysis
    --------

    The DWARF generated by the included test case looks like:

        0x0000000b: DW_TAG_compile_unit
                      DW_AT_language [DW_FORM_sdata]    (4)

        0x0000000d:   DW_TAG_base_type
                        DW_AT_name [DW_FORM_string]     ("int")
                        DW_AT_byte_size [DW_FORM_data1] (0x04)
                        DW_AT_encoding [DW_FORM_sdata]  (5)

        0x00000014:   DW_TAG_subprogram
                        DW_AT_name [DW_FORM_string]     ("apply")

        0x0000001b:   DW_TAG_subprogram
                        DW_AT_specification [DW_FORM_ref4]      (0x00000014
"apply")
                        DW_AT_low_pc [DW_FORM_addr]     (0x0000000000001234)
                        DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000020)

        0x00000030:     DW_TAG_template_type_parameter
                          DW_AT_name [DW_FORM_string]   ("T")
                          DW_AT_type [DW_FORM_ref4]     (0x0000000d "int")

        0x00000037:     NULL

        0x00000038:   NULL

    Simply loading the file in GDB makes it crash:

        $ ./gdb -nx --data-directory=data-directory
testsuite/outputs/gdb.dwarf2/pr26693/pr26693
        [1]    15188 abort (core dumped)  ./gdb -nx
--data-directory=data-directory

    The crash happens here, where htab (a dwarf2_cu::die_hash field) is
    unexpectedly NULL while generating partial symbols:

        #0  0x000055555fa28188 in htab_find_with_hash (htab=0x0,
element=0x7fffffffbfa0, hash=27) at
/home/simark/src/binutils-gdb/libiberty/hashtab.c:591
        #1  0x000055555cb4eb2e in follow_die_offset (sect_off=(unknown: 27),
offset_in_dwz=0, ref_cu=0x7fffffffc110) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:22951
        #2  0x000055555cb4edfb in follow_die_ref (src_die=0x0,
attr=0x7fffffffc130, ref_cu=0x7fffffffc110) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:22968
        #3  0x000055555caa48c5 in partial_die_full_name (pdi=0x621000157e70,
cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8441
        #4  0x000055555caa4d79 in add_partial_symbol (pdi=0x621000157e70,
cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8469
        #5  0x000055555caa7d8c in add_partial_subprogram (pdi=0x621000157e70,
lowpc=0x7fffffffc5c0, highpc=0x7fffffffc5e0, set_addrmap=1, cu=0x615000023f80)
at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8737
        #6  0x000055555caa265c in scan_partial_symbols
(first_die=0x621000157e00, lowpc=0x7fffffffc5c0, highpc=0x7fffffffc5e0,
set_addrmap=1, cu=0x615000023f80) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8230
        #7  0x000055555ca98e3f in process_psymtab_comp_unit_reader
(reader=0x7fffffffc6b0, info_ptr=0x60600009650d "\003int",
comp_unit_die=0x621000157d10, pretend_language=language_minimal) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7614
        #8  0x000055555ca9aa2c in process_psymtab_comp_unit
(this_cu=0x621000155510, per_objfile=0x613000009f80, want_partial_unit=false,
pretend_language=language_minimal) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7712
        #9  0x000055555caa051a in dwarf2_build_psymtabs_hard
(per_objfile=0x613000009f80) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8073

    The special thing about this DWARF is that the subprogram at 0x1b is a
    template specialization described with DW_AT_specification, and has no
    DW_AT_name in itself.  To compute the name of this subprogram,
    partial_die_full_name needs to load the full DIE for this partial DIE.
    The name is generated from the templated function name and the actual
    tempalate parameter values of the specialization.

    To load the full DIE, partial_die_full_name creates a dummy DWARF
    attribute of form DW_FORM_ref_addr that points to our subprogram's DIE,
    and calls follow_die_ref on it.  This eventually causes
    load_full_comp_unit to be called for the exact same CU we are currently
    making partial symbols for:

        #0  load_full_comp_unit (this_cu=0x621000155510,
per_objfile=0x613000009f80, skip_partial=false,
pretend_language=language_minimal) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:9238
        #1  0x000055555cb4e943 in follow_die_offset (sect_off=(unknown: 27),
offset_in_dwz=0, ref_cu=0x7fffffffc110) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:22942
        #2  0x000055555cb4edfb in follow_die_ref (src_die=0x0,
attr=0x7fffffffc130, ref_cu=0x7fffffffc110) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:22968
        #3  0x000055555caa48c5 in partial_die_full_name (pdi=0x621000157e70,
cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8441
        #4  0x000055555caa4d79 in add_partial_symbol (pdi=0x621000157e70,
cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8469
        #5  0x000055555caa7d8c in add_partial_subprogram (pdi=0x621000157e70,
lowpc=0x7fffffffc5c0, highpc=0x7fffffffc5e0, set_addrmap=1, cu=0x615000023f80)
at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8737
        #6  0x000055555caa265c in scan_partial_symbols
(first_die=0x621000157e00, lowpc=0x7fffffffc5c0, highpc=0x7fffffffc5e0,
set_addrmap=1, cu=0x615000023f80) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8230
        #7  0x000055555ca98e3f in process_psymtab_comp_unit_reader
(reader=0x7fffffffc6b0, info_ptr=0x60600009650d "\003int",
comp_unit_die=0x621000157d10, pretend_language=language_minimal) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7614
        #8  0x000055555ca9aa2c in process_psymtab_comp_unit
(this_cu=0x621000155510, per_objfile=0x613000009f80, want_partial_unit=false,
pretend_language=language_minimal) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7712
        #9  0x000055555caa051a in dwarf2_build_psymtabs_hard
(per_objfile=0x613000009f80) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8073

    load_full_comp_unit creates a cutu_reader for the CU.  Since a dwarf2_cu
    object already exists for the CU, load_full_comp_unit is expected to
    find it and pass it to cutu_reader, so that cutu_reader doesn't create
    a new dwarf2_cu for the CU.

    And this is the difference between before and after the regression.
    Before commit 7188ed02d2a7, the dwarf2_per_cu_data -> dwarf2_cu link was
    a simple pointer in dwarf2_per_cu_data.  This pointer was set up when
    starting the read the partial symbols.  So it was already available at
    that point where load_full_comp_unit gets called.  Post-7188ed02d2a7,
    this link is per-objfile, kept in the dwarf2_per_objfile::m_dwarf2_cus
    hash map.  The entry is only put in the hash map once the partial
    symbols have been successfully read, when cutu_reader::keep is called.
    Therefore, it is _not_ set at the point load_full_comp_unit is called.

    As a consequence, a new dwarf2_cu object gets created and initialized by
    load_full_comp_unit (including initializing that dwarf2_cu::die_hash
    field).  Meanwhile, the dwarf2_cu object created and used by the callers
    up the stack does not get initialized for full symbol reading, and the
    dwarf2_cu::die_hash field stays unexpectedly NULL.

    Solution
    --------

    Since the caller of load_full_comp_unit knows about the existing
    dwarf2_cu object for the CU we are reading (the one load_full_comp_unit
    is expected to find), we can simply make it pass it down, instead of
    having load_full_comp_unit look up the per-objfile map.

    load_full_comp_unit therefore gets a new `existing_cu` parameter.  All
    other callers get updated to pass `per_objfile->get_cu (per_cu)`, so the
    behavior shouldn't change for them, compared to the current HEAD.

    A test is added, which is the bare minimum to reproduce the issue.

    Notes
    -----

    The original problem was reproduced by downloading

       
https://github.com/oneapi-src/oneTBB/releases/download/v2020.3/tbb-2020.3-lin.tgz

    and loading libtbb.so in GDB.  This code was compiled with the Intel
    C/C++ compiler.  I was not able to reproduce the issue using GCC, I
    think because GCC puts a DW_AT_name in the specialized subprogram, so
    there's no need for partial_die_full_name to load the full DIE of the
    subprogram, and the faulty code doesn't execute.

    gdb/ChangeLog:

            PR gdb/26693
            * dwarf2/read.c (load_full_comp_unit): Add existing_cu
            parameter.
            (load_cu): Pass existing CU.
            (process_imported_unit_die): Likewise.
            (follow_die_offset): Likewise.

    gdb/testsuite/ChangeLog:

            PR gdb/26693
            * gdb.dwarf2/template-specification-full-name.exp: New test.

    Change-Id: I57c8042f96c45f15797a3848e4d384181c56bb44

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug gdb/26693] [gdb-10] regression: loading dwarf info crashes the debugger
  2020-10-01 14:26 [Bug gdb/26693] New: [gdb-10] regression: loading dwarf info crashes the debugger mihails.strasuns at intel dot com
                   ` (5 preceding siblings ...)
  2020-10-22 14:46 ` cvs-commit at gcc dot gnu.org
@ 2020-10-22 14:50 ` cvs-commit at gcc dot gnu.org
  2020-10-22 14:55 ` simark at simark dot ca
  7 siblings, 0 replies; 9+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2020-10-22 14:50 UTC (permalink / raw)
  To: gdb-prs

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

--- Comment #6 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=4c02be1198613b582744f90e5a2e3425dcf22c81

commit 4c02be1198613b582744f90e5a2e3425dcf22c81
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Thu Oct 22 10:27:39 2020 -0400

    gdb/dwarf: fix reading subprogram with DW_AT_specification (PR gdb/26693)

    Fix a regression introduced by commit 7188ed02d2a7 ("Replace
    dwarf2_per_cu_data::cu backlink with per-objfile map").

    This patch targets both master and gdb-10-branch, since this is a
    regression from GDB 9.

    Analysis
    --------

    The DWARF generated by the included test case looks like:

        0x0000000b: DW_TAG_compile_unit
                      DW_AT_language [DW_FORM_sdata]    (4)

        0x0000000d:   DW_TAG_base_type
                        DW_AT_name [DW_FORM_string]     ("int")
                        DW_AT_byte_size [DW_FORM_data1] (0x04)
                        DW_AT_encoding [DW_FORM_sdata]  (5)

        0x00000014:   DW_TAG_subprogram
                        DW_AT_name [DW_FORM_string]     ("apply")

        0x0000001b:   DW_TAG_subprogram
                        DW_AT_specification [DW_FORM_ref4]      (0x00000014
"apply")
                        DW_AT_low_pc [DW_FORM_addr]     (0x0000000000001234)
                        DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000020)

        0x00000030:     DW_TAG_template_type_parameter
                          DW_AT_name [DW_FORM_string]   ("T")
                          DW_AT_type [DW_FORM_ref4]     (0x0000000d "int")

        0x00000037:     NULL

        0x00000038:   NULL

    Simply loading the file in GDB makes it crash:

        $ ./gdb -nx --data-directory=data-directory
testsuite/outputs/gdb.dwarf2/pr26693/pr26693
        [1]    15188 abort (core dumped)  ./gdb -nx
--data-directory=data-directory

    The crash happens here, where htab (a dwarf2_cu::die_hash field) is
    unexpectedly NULL while generating partial symbols:

        #0  0x000055555fa28188 in htab_find_with_hash (htab=0x0,
element=0x7fffffffbfa0, hash=27) at
/home/simark/src/binutils-gdb/libiberty/hashtab.c:591
        #1  0x000055555cb4eb2e in follow_die_offset (sect_off=(unknown: 27),
offset_in_dwz=0, ref_cu=0x7fffffffc110) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:22951
        #2  0x000055555cb4edfb in follow_die_ref (src_die=0x0,
attr=0x7fffffffc130, ref_cu=0x7fffffffc110) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:22968
        #3  0x000055555caa48c5 in partial_die_full_name (pdi=0x621000157e70,
cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8441
        #4  0x000055555caa4d79 in add_partial_symbol (pdi=0x621000157e70,
cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8469
        #5  0x000055555caa7d8c in add_partial_subprogram (pdi=0x621000157e70,
lowpc=0x7fffffffc5c0, highpc=0x7fffffffc5e0, set_addrmap=1, cu=0x615000023f80)
at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8737
        #6  0x000055555caa265c in scan_partial_symbols
(first_die=0x621000157e00, lowpc=0x7fffffffc5c0, highpc=0x7fffffffc5e0,
set_addrmap=1, cu=0x615000023f80) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8230
        #7  0x000055555ca98e3f in process_psymtab_comp_unit_reader
(reader=0x7fffffffc6b0, info_ptr=0x60600009650d "\003int",
comp_unit_die=0x621000157d10, pretend_language=language_minimal) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7614
        #8  0x000055555ca9aa2c in process_psymtab_comp_unit
(this_cu=0x621000155510, per_objfile=0x613000009f80, want_partial_unit=false,
pretend_language=language_minimal) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7712
        #9  0x000055555caa051a in dwarf2_build_psymtabs_hard
(per_objfile=0x613000009f80) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8073

    The special thing about this DWARF is that the subprogram at 0x1b is a
    template specialization described with DW_AT_specification, and has no
    DW_AT_name in itself.  To compute the name of this subprogram,
    partial_die_full_name needs to load the full DIE for this partial DIE.
    The name is generated from the templated function name and the actual
    tempalate parameter values of the specialization.

    To load the full DIE, partial_die_full_name creates a dummy DWARF
    attribute of form DW_FORM_ref_addr that points to our subprogram's DIE,
    and calls follow_die_ref on it.  This eventually causes
    load_full_comp_unit to be called for the exact same CU we are currently
    making partial symbols for:

        #0  load_full_comp_unit (this_cu=0x621000155510,
per_objfile=0x613000009f80, skip_partial=false,
pretend_language=language_minimal) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:9238
        #1  0x000055555cb4e943 in follow_die_offset (sect_off=(unknown: 27),
offset_in_dwz=0, ref_cu=0x7fffffffc110) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:22942
        #2  0x000055555cb4edfb in follow_die_ref (src_die=0x0,
attr=0x7fffffffc130, ref_cu=0x7fffffffc110) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:22968
        #3  0x000055555caa48c5 in partial_die_full_name (pdi=0x621000157e70,
cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8441
        #4  0x000055555caa4d79 in add_partial_symbol (pdi=0x621000157e70,
cu=0x615000023f80) at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8469
        #5  0x000055555caa7d8c in add_partial_subprogram (pdi=0x621000157e70,
lowpc=0x7fffffffc5c0, highpc=0x7fffffffc5e0, set_addrmap=1, cu=0x615000023f80)
at /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8737
        #6  0x000055555caa265c in scan_partial_symbols
(first_die=0x621000157e00, lowpc=0x7fffffffc5c0, highpc=0x7fffffffc5e0,
set_addrmap=1, cu=0x615000023f80) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8230
        #7  0x000055555ca98e3f in process_psymtab_comp_unit_reader
(reader=0x7fffffffc6b0, info_ptr=0x60600009650d "\003int",
comp_unit_die=0x621000157d10, pretend_language=language_minimal) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7614
        #8  0x000055555ca9aa2c in process_psymtab_comp_unit
(this_cu=0x621000155510, per_objfile=0x613000009f80, want_partial_unit=false,
pretend_language=language_minimal) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:7712
        #9  0x000055555caa051a in dwarf2_build_psymtabs_hard
(per_objfile=0x613000009f80) at
/home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8073

    load_full_comp_unit creates a cutu_reader for the CU.  Since a dwarf2_cu
    object already exists for the CU, load_full_comp_unit is expected to
    find it and pass it to cutu_reader, so that cutu_reader doesn't create
    a new dwarf2_cu for the CU.

    And this is the difference between before and after the regression.
    Before commit 7188ed02d2a7, the dwarf2_per_cu_data -> dwarf2_cu link was
    a simple pointer in dwarf2_per_cu_data.  This pointer was set up when
    starting the read the partial symbols.  So it was already available at
    that point where load_full_comp_unit gets called.  Post-7188ed02d2a7,
    this link is per-objfile, kept in the dwarf2_per_objfile::m_dwarf2_cus
    hash map.  The entry is only put in the hash map once the partial
    symbols have been successfully read, when cutu_reader::keep is called.
    Therefore, it is _not_ set at the point load_full_comp_unit is called.

    As a consequence, a new dwarf2_cu object gets created and initialized by
    load_full_comp_unit (including initializing that dwarf2_cu::die_hash
    field).  Meanwhile, the dwarf2_cu object created and used by the callers
    up the stack does not get initialized for full symbol reading, and the
    dwarf2_cu::die_hash field stays unexpectedly NULL.

    Solution
    --------

    Since the caller of load_full_comp_unit knows about the existing
    dwarf2_cu object for the CU we are reading (the one load_full_comp_unit
    is expected to find), we can simply make it pass it down, instead of
    having load_full_comp_unit look up the per-objfile map.

    load_full_comp_unit therefore gets a new `existing_cu` parameter.  All
    other callers get updated to pass `per_objfile->get_cu (per_cu)`, so the
    behavior shouldn't change for them, compared to the current HEAD.

    A test is added, which is the bare minimum to reproduce the issue.

    Notes
    -----

    The original problem was reproduced by downloading

       
https://github.com/oneapi-src/oneTBB/releases/download/v2020.3/tbb-2020.3-lin.tgz

    and loading libtbb.so in GDB.  This code was compiled with the Intel
    C/C++ compiler.  I was not able to reproduce the issue using GCC, I
    think because GCC puts a DW_AT_name in the specialized subprogram, so
    there's no need for partial_die_full_name to load the full DIE of the
    subprogram, and the faulty code doesn't execute.

    gdb/ChangeLog:

            PR gdb/26693
            * dwarf2/read.c (load_full_comp_unit): Add existing_cu
            parameter.
            (load_cu): Pass existing CU.
            (process_imported_unit_die): Likewise.
            (follow_die_offset): Likewise.

    gdb/testsuite/ChangeLog:

            PR gdb/26693
            * gdb.dwarf2/template-specification-full-name.exp: New test.

    Change-Id: I57c8042f96c45f15797a3848e4d384181c56bb44

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug gdb/26693] [gdb-10] regression: loading dwarf info crashes the debugger
  2020-10-01 14:26 [Bug gdb/26693] New: [gdb-10] regression: loading dwarf info crashes the debugger mihails.strasuns at intel dot com
                   ` (6 preceding siblings ...)
  2020-10-22 14:50 ` cvs-commit at gcc dot gnu.org
@ 2020-10-22 14:55 ` simark at simark dot ca
  7 siblings, 0 replies; 9+ messages in thread
From: simark at simark dot ca @ 2020-10-22 14:55 UTC (permalink / raw)
  To: gdb-prs

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

Simon Marchi <simark at simark dot ca> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #7 from Simon Marchi <simark at simark dot ca> ---
Fixed.

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

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-10-22 14:55 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-01 14:26 [Bug gdb/26693] New: [gdb-10] regression: loading dwarf info crashes the debugger mihails.strasuns at intel dot com
2020-10-08 16:32 ` [Bug gdb/26693] " simark at simark dot ca
2020-10-08 16:32 ` simark at simark dot ca
2020-10-08 17:20 ` simark at simark dot ca
2020-10-09  3:36 ` simark at simark dot ca
2020-10-12 18:06 ` mihails.strasuns at intel dot com
2020-10-22 14:46 ` cvs-commit at gcc dot gnu.org
2020-10-22 14:50 ` cvs-commit at gcc dot gnu.org
2020-10-22 14:55 ` simark at simark dot ca

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).