问题描述
我正在做一个项目,我需要解析编译器的 DWARF 输出。我正在使用带有 GCC 8.3.0 的 Debian x64 (windows WSL)。
我遇到了一个编译器行为,我认为这可能是一个错误,但我不确定是否有我不明白的微妙之处。
为了打包结构,我使用以下指令:#pragma pack(push,1)
。我认为 GCC 在出现以下情况时(但不限于)不会产生正确的调试符号:
这是一个结构:
struct StructD
{
unsigned int bitfieldA : 1;
unsigned int bitfieldB : 9;
unsigned int bitfieldC : 3;
unsigned int bitfieldD;
};
这里有一段代码来测试它:
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]);
场景 1 - 无编译指示
如果我不在任何地方使用编译指示,我的结构是 32 位对齐的并且调试符号匹配。软件输出是这样的: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
调试 sumbol 报告 bitfieldD
在结构中的第 4 个字节,没有位偏移。哪个是对的。
场景 2 - 结构体声明前的编译指示
如果我把编译指示放在 .h 文件的顶部,我会得到这个软件输出:
77 0e 4d 01 00 00 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: 2
所以 bitfieldD
在没有偏移量的字节 2 处,这又是正确的,并且与内存布局相匹配。
场景 3 - .cpp 中的编译指示,但在 .h 中省略
当我将 pragma 放在 .cpp 文件中时,在包含定义 StructD
的 .h 文件之前,但我省略将 pragma 放在 .h 文件中时,我在编译的代码和调试符号。
软件输出: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: 2
现在调试符号说 bitfieldD
在字节 #2,但很明显软件把它放在字节 #4。我认识到 pragma 的用法可能不正确,但我希望 GCC 生成与生成的代码匹配的调试符号。
这是 GCC 中的错误还是我误解了 DWARF 的工作原理?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)