Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

COFF Debug info missing nested enumeration. #43250

Open
CarlosAlbertoEnciso opened this issue Nov 5, 2019 · 15 comments
Open

COFF Debug info missing nested enumeration. #43250

CarlosAlbertoEnciso opened this issue Nov 5, 2019 · 15 comments
Assignees
Labels
bugzilla Issues migrated from bugzilla debuginfo

Comments

@CarlosAlbertoEnciso
Copy link
Member

Bugzilla Link 43905
Version trunk
OS All
CC @dwblaikie,@gregbedwell,@JDevlieghere,@jmorse,@walkerkd,@pogo59,@rnk

Extended Description

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

@CarlosAlbertoEnciso
Copy link
Member Author

assigned to @amykhuang

@CarlosAlbertoEnciso
Copy link
Member Author

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.

@CarlosAlbertoEnciso
Copy link
Member Author

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

@CarlosAlbertoEnciso
Copy link
Member Author

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'

@CarlosAlbertoEnciso
Copy link
Member Author

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: (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'
}
}

@CarlosAlbertoEnciso
Copy link
Member Author

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)

@gregbedwell
Copy link
Collaborator

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.

@rnk
Copy link
Collaborator

rnk commented Nov 6, 2019

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.

@CarlosAlbertoEnciso
Copy link
Member Author

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.

@rnk
Copy link
Collaborator

rnk commented Nov 7, 2019

d91ed80
Thanks for the report!

@CarlosAlbertoEnciso
Copy link
Member Author

@gregbedwell
Copy link
Collaborator

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

@rnk
Copy link
Collaborator

rnk commented Jan 14, 2020

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

@rnk
Copy link
Collaborator

rnk commented Apr 10, 2020

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.

@amykhuang
Copy link
Collaborator

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

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla debuginfo
Projects
None yet
Development

No branches or pull requests

4 participants