I am working on a project where I need to parse the DWARF output of a compiler. I am working a Debian x64 (windows WSL) with GCC 8.3.0.
I face a compiler behaviour that I think might be a bug, but I am unsure if there's a subtlety I don't get.
I order to pack a structure, I use the following directive : #pragma pack(push,1)
. I think that GCC doesn't produce the right debugging symbol when the following conditions occurs (but not limited to them):
- struct declaration in .h file
- pragma directive in the .cpp file only, before the include
- instance of struct delcared in the cpp file
Here's a structure :
struct StructD
{
unsigned int bitfieldA : 1;
unsigned int bitfieldB : 9;
unsigned int bitfieldC : 3;
unsigned int bitfieldD;
};
And here's a piece of code to test it:
file1StructDInstance.bitfieldA = 1;
file1StructDInstance.bitfieldB = 0b100111011;
file1StructDInstance.bitfieldC = 0b11;
file1StructDInstance.bitfieldD = 0b101001101;
unsigned char* ptr = (unsigned char*)(&file1StructDInstance);
printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
Scenario 1 - No pragma
If I do not use the pragma anywhere, my struct is 32bits aligned and the debugging symbol matches. The software output is like this: 77 0e 00 00 4d 01 00 00
.
<2><150>: Abbrev Number: 3 (DW_TAG_member)
<151> DW_AT_name : (indirect string, offset: 0xc2): bitfieldD
<155> DW_AT_decl_file : 2
<156> DW_AT_decl_line : 33
<157> DW_AT_decl_column : 15
<158> DW_AT_type : <0x83>
<15c> DW_AT_data_member_location: 4
The debugging sumbol report that bitfieldD
is at the 4th byte in the structure, no bit offset. Which is right.
Scenario 2 - Pragma before struct declaration
If I put the pragma at the top of the .h file , I get this software output :
77 0e 4d 01 00 00 00 00
And the debugging symbol is as follow
<2><150>: Abbrev Number: 3 (DW_TAG_member)
<151> DW_AT_name : (indirect string, offset: 0xc2): bitfieldD
<155> DW_AT_decl_file : 2
<156> DW_AT_decl_line : 33
<157> DW_AT_decl_column : 15
<158> DW_AT_type : <0x83>
<15c> DW_AT_data_member_location: 2
So bitfieldD
is at byte 2 without offset, which is again right and matches the memory layout.
Scenario 3 - Pragma in .cpp, but omitted in .h
When I put the pragma in the .cpp file, before the include of the .h file that define StructD
, but I omit to put the pragma in the .h file, I get a mismatch between the compiled code and the debugging symbol.
software output : 77 0e 00 00 4d 01 00 00
And debugging symbol
<2><150>: Abbrev Number: 3 (DW_TAG_member)
<151> DW_AT_name : (indirect string, offset: 0xc2): bitfieldD
<155> DW_AT_decl_file : 2
<156> DW_AT_decl_line : 33
<157> DW_AT_decl_column : 15
<158> DW_AT_type : <0x83>
<15c> DW_AT_data_member_location: 2
Now the debugging symbols says that bitfieldD
is at byte #2, but clearly the software put it at byte #4. I recognize that the usage of the pragma might not be proper, but I would expect GCC to produce debugging symbols that matches the generated code.
Is this a bug in GCC or am I misunderstanding how DWARF works?