Bug 46123 - [4.5/4.6 Regression] ICE: in output_aranges, at dwarf2out.c:11531 with -feliminate-dwarf2-dups -g
Summary: [4.5/4.6 Regression] ICE: in output_aranges, at dwarf2out.c:11531 with -felim...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 4.6.0
: P2 normal
Target Milestone: 4.5.2
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2010-10-21 22:39 UTC by Zdenek Sojka
Modified: 2010-12-11 04:34 UTC (History)
4 users (show)

See Also:
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Build:
Known to work:
Known to fail: 4.5.2, 4.6.0
Last reconfirmed: 2010-10-22 02:15:03


Attachments
reduced testcase (81 bytes, text/plain)
2010-10-21 22:39 UTC, Zdenek Sojka
Details
gcc46-pr46123.patch (1.02 KB, patch)
2010-11-18 13:13 UTC, Jakub Jelinek
Details | Diff
generated assembler (1.58 KB, text/plain)
2010-12-04 06:28 UTC, Dave Korn
Details
preprocessed source (293 bytes, text/plain)
2010-12-04 06:28 UTC, Dave Korn
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Zdenek Sojka 2010-10-21 22:39:43 UTC
Created attachment 22111 [details]
reduced testcase

Compiler output (trunk):
$ gcc -feliminate-dwarf2-dups -g -std=c++0x pr46123.C 
pr46123.C:8:1: internal compiler error: in output_aranges, at dwarf2out.c:11531
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

Compiler output (4.5):
$ gcc -feliminate-dwarf2-dups -g -std=c++0x pr46123.C         
pr46123.C:8:1: internal compiler error: in output_pubnames, at dwarf2out.c:10887
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

Tested revisions:
r165768 - crash
4.5 r165781 - crash
4.4 r165754 - doesn't recognise lambdas
Comment 1 Zdenek Sojka 2010-10-21 23:27:52 UTC
The same ICE happens with g++.old-deja/g++.other/mangle3.C:
$ gcc g++.old-deja/g++.other/mangle3.C -g -feliminate-dwarf2-dups
g++.old-deja/g++.other/mangle3.C:42:1: internal compiler error: in output_aranges, at dwarf2out.c:11531
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

That testcase doesn't use lambdas, so it probably isn't lambda-specific.
Comment 2 H.J. Lu 2010-10-22 02:15:03 UTC
It is caused by revision 151185:

http://gcc.gnu.org/ml/gcc-cvs/2009-08/msg00868.html
Comment 3 Jakub Jelinek 2010-11-18 13:13:57 UTC
Created attachment 22446 [details]
gcc46-pr46123.patch

Ugh, this is very ugly.  gen_subprogram_die sometimes decides to reuse old_die
which was DW_AT_declaration and can be deeply nested in type children, which breaks -feliminate-dwarf2-dups as well as -gdwarf-4 if those are moved to separate CUs (either the comdat ones or .debug_types).
The patch fixes this by not reusing the old die if doing one or another way of
duplicate removals (perhaps could do an extra check if the old_die is actually in a tree that is going to be moved, which wouldn't be that hard to do for break_out_includes, but would be uglier for .debug_types).  Or we could do it always.  Unfortunately just doing that leads to crashes, because context_die is NULL and dwarf2out_finish doesn't want to see limbo DIEs with type contexts, so the patch also uses comp_unit_die () in that case.

Jason/Cary, what do you think?
Comment 4 ccoutant 2010-11-19 02:17:27 UTC
> Ugh, this is very ugly.  gen_subprogram_die sometimes decides to reuse old_die
> which was DW_AT_declaration and can be deeply nested in type children, which
> breaks -feliminate-dwarf2-dups as well as -gdwarf-4 if those are moved to
> separate CUs (either the comdat ones or .debug_types).
> The patch fixes this by not reusing the old die if doing one or another way of
> duplicate removals (perhaps could do an extra check if the old_die is actually
> in a tree that is going to be moved, which wouldn't be that hard to do for
> break_out_includes, but would be uglier for .debug_types).  Or we could do it
> always.  Unfortunately just doing that leads to crashes, because context_die is
> NULL and dwarf2out_finish doesn't want to see limbo DIEs with type contexts, so
> the patch also uses comp_unit_die () in that case.

When would context_die == NULL in a case where it would not be OK to
reuse the old_die? Wouldn't it be sufficient to force the new die only
if context_die != NULL?

-cary
Comment 5 Jakub Jelinek 2010-11-19 07:36:03 UTC
context_die == NULL happens exactly on the g++.old-deja/g++.other/mangle3.C testcase, i.e. on an inline method of a type contained in another inline method of another type.
The reason why context_die is NULL is because on this inner method decl_function_scope returns non-NULL - while the inner method is contained in a type, not in a function, that type is contained in a function.
The reusing happens only if is_cu_die (old_die->parent) or context_die == NULL
and for is_cu_die (old_die->parent) it should never be a problem.

I guess a different fix would be not to use decl_function_scope in deciding whether to clear context_die, but use another function, which would return NULL as soon as we switch from a FUNCTION_DECL to a type while traversing the contexts.
Comment 6 Jason Merrill 2010-12-03 16:56:59 UTC
Author: jason
Date: Fri Dec  3 16:56:53 2010
New Revision: 167436

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=167436
Log:
	PR debug/46123
	* dwarf2out.c (gen_tagged_type_die): Don't put local types in
	a declaration DIE.

Added:
    trunk/gcc/testsuite/g++.dg/debug/dwarf2/pr46123.C
    trunk/gcc/testsuite/g++.dg/debug/pr46123.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/dwarf2out.c
    trunk/gcc/testsuite/ChangeLog
Comment 7 Jason Merrill 2010-12-03 20:08:32 UTC
Author: jason
Date: Fri Dec  3 20:08:28 2010
New Revision: 167441

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=167441
Log:
	PR debug/46123
	* dwarf2out.c (gen_type_die_with_usage): Don't put local types in
	a declaration DIE.

Added:
    branches/gcc-4_5-branch/gcc/testsuite/g++.dg/debug/dwarf2/pr46123.C
    branches/gcc-4_5-branch/gcc/testsuite/g++.dg/debug/pr46123.C
Modified:
    branches/gcc-4_5-branch/gcc/ChangeLog
    branches/gcc-4_5-branch/gcc/dwarf2out.c
    branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
Comment 8 Jason Merrill 2010-12-03 20:09:50 UTC
Fixed.
Comment 9 Dave Korn 2010-12-04 06:26:55 UTC
The testcase is failing for me on i686-pc-cygwin:

spawn /gnu/gcc/obj-pr40125/gcc/testsuite/g++/../../g++ -B/gnu/gcc/obj-pr40125/gcc/testsuite/g++/../../ /gnu/gcc/gcc-patched/gcc/testsuite/g++.dg/debug/pr46123.C -nostdinc++ -I/gnu/gcc/obj-pr40125/i686-pc-cygwin/libstdc++-v3/include/i686-pc-cygwin -I/gnu/gcc/obj-pr40125/i686-pc-cygwin/libstdc++-v3/include -I/gnu/gcc/gcc-patched/libstdc++-v3/libsupc++ -I/gnu/gcc/gcc-patched/libstdc++-v3/include/backward -I/gnu/gcc/gcc-patched/libstdc++-v3/testsuite/util -fmessage-length=0 -gdwarf-2 -g -feliminate-dwarf2-dups -S -o pr46123.s 
/gnu/gcc/gcc-patched/gcc/testsuite/g++.dg/debug/pr46123.C:47:1: internal compiler error: in output_aranges, at dwarf2out.c:11678

 It happens here, 

(gdb) bt
#0  0x007c7c70 in fancy_abort (
    file=0xe22afc "/gnu/gcc/gcc-patched/gcc/dwarf2out.c", line=11678,
    function=0xe284b4 "output_aranges")
    at /gnu/gcc/gcc-patched/gcc/diagnostic.c:101
#1  0x0066b9c1 in dwarf2out_finish (
    filename=0x59bccaa "/gnu/gcc/gcc-patched/gcc/testsuite/g++.dg/debug/pr46123.
C") at /gnu/gcc/gcc-patched/gcc/dwarf2out.c:1109

... in dwarf2out.c, where output_aranges() has been inlined into dwarf2out_finish:

  /* It is necessary not to output these entries if the sections were
     not used; if the sections were not used, the length will be 0 and
     the address may end up as 0 if the section is discarded by ld
     --gc-sections, leaving an invalid (0, 0) entry that can be
     confused with the terminator.  */
  if (text_section_used)
    {
      dw2_asm_output_addr (DWARF2_ADDR_SIZE, text_section_label, "Address");
      dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label,
			    text_section_label, "Length");
    }
  if (cold_text_section_used)
    {
      dw2_asm_output_addr (DWARF2_ADDR_SIZE, cold_text_section_label,
			   "Address");
      dw2_asm_output_delta (DWARF2_ADDR_SIZE, cold_end_label,
			    cold_text_section_label, "Length");
    }

  for (i = 0; i < arange_table_in_use; i++)
    {
      dw_die_ref die = arange_table[i];

      /* We shouldn't see aranges for DIEs outside of the main CU.  */
      gcc_assert (die->die_mark);

  This assertion triggers on the second address range in the table:

(gdb) p arange_table[0][0]
$2 = {die_id = {die_symbol = 0x0, die_type_node = 0x0},
  die_attr = 0x7ff01400, die_parent = 0x7feb1980, die_child = 0x7feb1b00,
  die_sib = 0x7feb19e0, die_definition = 0x0, die_offset = 98,
  die_abbrev = 4, die_mark = 0, die_perennial_p = 0, decl_id = 1705,
  die_tag = DW_TAG_subprogram}
(gdb) p arange_table[1][0]
$3 = {die_id = {die_symbol = 0x0, die_type_node = 0x0},
  die_attr = 0x7ff816c0, die_parent = 0x7feb0360, die_child = 0x7feb1e00,
  die_sib = 0x7feb2340, die_definition = 0x0, die_offset = 78,
  die_abbrev = 9, die_mark = 1, die_perennial_p = 0, decl_id = 1697,
  die_tag = DW_TAG_subprogram}
(gdb) p arange_table[2]
$4 = (dw_die_ref) 0x0
(gdb)

  Any ideas what this could mean?
Comment 10 Dave Korn 2010-12-04 06:28:04 UTC
Created attachment 22625 [details]
generated assembler

This is the assembler output that has been generated up to the point when it ICEs.
Comment 11 Dave Korn 2010-12-04 06:28:48 UTC
Created attachment 22626 [details]
preprocessed source
Comment 12 Jason Merrill 2010-12-11 01:20:14 UTC
I can't reproduce this failure with a cross-compiler and the preprocessed source.  Does it still fail for you?
Comment 13 Dave Korn 2010-12-11 04:34:07 UTC
Didn't crop up in my latest testrun (based on r.167484 / 20101206), so whatever it was seems to have gone away.