Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

COFF Debug info missing nested enumeration. #42875

Open Quuxplusone opened 5 years ago

Quuxplusone commented 5 years ago
Bugzilla Link PR43905
Status REOPENED
Importance P enhancement
Reported by Carlos Alberto Enciso (international.phantom@gmail.com)
Reported on 2019-11-05 03:53:42 -0800
Last modified on 2020-04-13 16:44:24 -0700
Version trunk
Hardware PC All
CC dblaikie@gmail.com, greg.bedwell@sony.com, jdevlieghere@apple.com, jeremy.morse.llvm@gmail.com, keith.walker@arm.com, llvm-bugs@lists.llvm.org, paul_robinson@playstation.sony.com, rnk@google.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
Given the following test case:

//------------------------------------------------------------
// enum.cpp
//------------------------------------------------------------

struct STRUCT_a {
  enum ENUM_a { One = '1', Two = '2' };
  ENUM_a Enum_a;
};
void testEnum_1() {
  STRUCT_a Struct;
}

//------------------------------------------------------------

Using the following command line options to generate debug info
(DWARF) and (COFF):

clang -c -g -O0 enum.cpp -o enum-dwarf.o
clang -c -g -O0 enum.cpp -o enum-coff.o -gcodeview --target=x86_64-windows

Looking at the output generated by llvm-dwarfdump, llvm-readobj and llvm-diva,
the COFF debug info shows the nested 'ENUM_a' in the 'STRUCT_a' scope.

llvm-dwarfdump --debug-info enum-dwarf.o
llvm-readobj --codeview enum-coff.o
Quuxplusone commented 5 years ago
Using llvm-diva with the following command:

llvm-diva --print=scopes,symbols,types --attribute=level,format,base --
sort=name enum-dwarf.o enum-coff.o

The output for both object files looks like:

Logical View:
[000]           {File} 'enum-dwarf.o' -> ELF64-x86-64

[001]             {CompileUnit} 'enum.cpp'
[002]     1         {Struct} 'STRUCT_a'
[003]     2           {Enumeration} 'ENUM_a' -> 'unsigned int'
[004]                   {Enumerator} 'One' = '0x00000031'
[004]                   {Enumerator} 'Two' = '0x00000032'
[003]     3           {Member} public 'Enum_a' -> 'ENUM_a'
[002]     5         {Function} extern not_inlined 'testEnum_1' -> ''
[003]     6           {Variable} 'Struct' -> 'STRUCT_a'
[002]               {BaseType} 'unsigned int'

Logical View:
[000]           {File} 'enum-coff.o' -> COFF-x86-64

[001]             {CompileUnit} 'enum.cpp'
[002]               {TypeAlias} 'STRUCT_a' -> 'STRUCT_a'
[002]     1         {Struct} 'STRUCT_a'
[003]     2           {Enumeration} 'ENUM_a' -> 'int'
[004]                   {Enumerator} 'One' = '0x31'
[004]                   {Enumerator} 'Two' = '0x32'
[003]                 {Member} public 'Enum_a' -> 'ENUM_a'
[002]               {BaseType} 'int'
[002]               {Function} not_inlined 'testEnum_1' -> 'void'
[003]                 {Variable} 'Struct' -> 'STRUCT_a'
[002]               {BaseType} 'void'

line-2, level-3 shows 'ENUM_a', which is correct.
Quuxplusone commented 5 years ago
But changing the test case to:

//------------------------------------------------------------
// enum.cpp
//------------------------------------------------------------

struct STRUCT_a {
  enum ENUM_a { One = '1', Two = '2' };
};
struct STRUCT_b {
  STRUCT_a::ENUM_a Enum_a;
};
void testEnum_2() {
  STRUCT_b Struct;
}

//------------------------------------------------------------

The COFF debug information does not include any definition for 'STRUCT_a',
despite 'ENUM_a' being referenced in 'STRUCT_b'.
Quuxplusone commented 5 years ago
Using llvm-diva with the following command:

llvm-diva --print=scopes,symbols --attribute=level,format,base --sort=name enum-
dwarf.o enum-coff.o

The output for both object files looks like:

Logical View:
[000]           {File} 'enum-dwarf.o' -> ELF64-x86-64

[001]             {CompileUnit} 'enum.cpp'
[002]     1         {Struct} 'STRUCT_a'
[003]     2           {Enumeration} 'ENUM_a' -> 'unsigned int'
[002]     4         {Struct} 'STRUCT_b'
[003]     5           {Member} public 'Enum_a' -> 'ENUM_a'
[002]     7         {Function} extern not_inlined 'testEnum_2' -> ''
[003]     8           {Variable} 'Struct' -> 'STRUCT_b'

Logical View:
[000]           {File} 'enum-coff.o' -> COFF-x86-64

[001]             {CompileUnit} 'enum.cpp'
[002]     4         {Struct} 'STRUCT_b'
[003]                 {Member} public 'Enum_a' -> 'ENUM_a'
[002]               {Function} not_inlined 'testEnum_2' -> 'void'
[003]                 {Variable} 'Struct' -> 'STRUCT_b'

The DWARF format shows at:
Line-1, level-2, the definition for 'STRUCT_a'
Line-2, level-3, the definition for 'ENUM_a'
Line-4, level-2, the definition for 'STRUCT_b'

The COFF format shows at:
Line-4, level-2, the definition for 'STRUCT_b'
Quuxplusone commented 5 years ago
A simplified output from llvm-readobj, showing the references to 'STRUCT_a'
and 'ENUM_a'.

  Enum (0x1005) {
    TypeLeafKind: LF_ENUM (0x1507)
    NumEnumerators: 2
    Properties [ (0x208)
      HasUniqueName (0x200)
      Nested (0x8)                         <-- Is nested
    ]
    UnderlyingType: int (0x74)
    FieldListType: <field list> (0x1004)
    Name: STRUCT_a::ENUM_a                 <-- 'STRUCT_a' its parent.
    LinkageName: .?AW4ENUM_a@STRUCT_a@@
  }
  ...
  UdtSourceLine (0x1007) {
    TypeLeafKind: LF_UDT_SRC_LINE (0x1606) <-- Source line information.
    UDT: STRUCT_a::ENUM_a (0x1005)
    SourceFile: /data/projects/tests/bugzillas/enum.cpp (0x1006)
    LineNumber: 2
  }
  ...
  FieldList (0x1008) {
    TypeLeafKind: LF_FIELDLIST (0x1203)
    DataMember {
      TypeLeafKind: LF_MEMBER (0x150D)
      AccessSpecifier: Public (0x3)
      Type: STRUCT_a::ENUM_a (0x1005)      <-- Member type, 'STRUCT_a::ENUM_a'
      FieldOffset: 0x0
      Name: Enum_a                         <-- Structure Member 'Enum_a'
    }
  }
Quuxplusone commented 5 years ago
A simplified output from llvm-dwarfdump, showing the definitions for
'STRUCT_a', 'STRUCT_b' and 'ENUM_a'

   DW_TAG_structure_type
     DW_AT_name ("STRUCT_a")             <-- STRUCT_a
     DW_AT_decl_line    (1)
     ...
     DW_TAG_enumeration_type
       ...
       DW_AT_name   ("ENUM_a")       <-- ENUM_a
       DW_AT_decl_line  (2)
       ...
   ...
   DW_TAG_structure_type
     DW_AT_name ("STRUCT_b")             <-- STRUCT_b
     DW_AT_decl_line    (4)
     ...
     DW_TAG_member
       DW_AT_name   ("Enum_a")
       DW_AT_type   (0x00000033 "ENUM_a")
       DW_AT_decl_line  (5)
Quuxplusone commented 5 years ago

For reference, llvm-diva is a local tool at Sony that we hope to contribute to the upstream LLVM project in coming months, in case anyone is confused by the references here.

Quuxplusone commented 4 years ago

I'd recommend using llvm-pdbutil dump -types over llvm-readobj -codeview in the future. The output is more readable.

Here are two related test cases:

struct Outer { enum Inner { One = '1', Two = '2' }; }; void testEnum_2() { Outer::Inner val; }


struct Outer { struct Inner { int x; }; }; void testNested() { Outer::Inner val; }

For both examples, Outer is emitted when producing DWARF, but not when producing codeview.

This happens even with -fstandalone-debug, which is clearly a bug. If we wanted to avoid emitting these with -flimit-debug, that's reasonable, but if the frontend makes them complete, the backend should emit them.

Quuxplusone commented 4 years ago

(In reply to Reid Kleckner from comment #7)

I'd recommend using llvm-pdbutil dump -types over llvm-readobj -codeview in the future. The output is more readable.

Thanks for your recommendation to use llvm-pdbutil dump -types.

Quuxplusone commented 4 years ago
https://github.com/llvm/llvm-project/commit/d91ed80e97ac9bfcfb02440874ed8b9a51c9491e
Thanks for the report!
Quuxplusone commented 4 years ago
(In reply to Reid Kleckner from comment #9)
> https://github.com/llvm/llvm-project/commit/
> d91ed80e97ac9bfcfb02440874ed8b9a51c9491e
> Thanks for the report!

It seems that your fix was reverted:

https://reviews.llvm.org/rGff3b513495c04d87799b3c5a98ddcdb6996af4f3
Quuxplusone commented 4 years ago
(In reply to Carlos Alberto Enciso from comment #10)
> It seems that your fix was reverted:
>
> https://reviews.llvm.org/rGff3b513495c04d87799b3c5a98ddcdb6996af4f3

Re-opening due to Comment 10.

@rnk: Do you remember whether this got resubmitted?  (a quick search of the
commit log suggests not, but I may have missed it).
Quuxplusone commented 4 years ago

No, it was not resubmitted, it's been on my TODO list to get back to it.

Quuxplusone commented 4 years ago

Amy, do you mind looking into this?

You can start by re-applying my change locally and then reproducing the crash that Hans ran into. The reproducer should be in https://crbug.com/1022729.

Quuxplusone commented 4 years ago

Reproduced it and apparently it crashes because of my heapallocsite change.