【问题标题】:Weird behavior of compiler - debugger编译器的奇怪行为 - 调试器
【发布时间】:2019-06-21 09:25:30
【问题描述】:

这个问题/问题与我在这里分享的上一个问题密切相关。不过……

我有一个相当大的项目,我正在执行单元测试和集成测试。不幸的是,我不能分享代码,除了小块,无论如何都要分享一个大项目。

我会尽可能地总结一下…… 类型定义如下:

typedef struct { 
s32 s32IntLimitHigh; 
s32 s32IntLimitLow; 
s32 s32RegLimitHigh; 
s32 s32RegLimitLow; 
u16 u16IntGain; 
u16 u16PropGain; 
u16 u16IntStep; 
BOOL BOOLFreeze; 
} structPIreg;

单身成员的类型从他们的名字就很清楚了。
两个数组定义如下:

structPIreg expected_VectParPI[VECT_PI_LENGTH];
structPIreg VectParPI[VECT_PI_LENGTH];

因为它是用于单元测试的,所以我有原始变量及其预期值。 数组有 8 个元素。

sizeof (VectParPI[1]) is 29 :

4*s32 + 3*u16 + 布尔 = 4*4+3*4+1 = 29
u16 在原机上是 16 位,在 x86 架构上是 32 位。

我编译,测试运行,我得到奇怪的结果。 所以我开始了一个调试会话,这里的事情变得更奇怪了。

现在,问题是这两个变量的结构大小似乎不同。 我在调试器上看到的是一致的。

我会贴两张变量观察窗口的图片让你理解。 在这个监视窗口中,我计算了 2 个数组的第二个和第一个元素之间的字节偏移量。

(char*)&VectParPI[1]-(char*)&VectParPI[0]   long    32  
(char*)&expected_VectParPI[1]-(char*)&expected_VectParPI[0] long    29  

watch windows

如您所见,偏移量是不同的。 但我想不通为什么。 在目标文件中,相同类型的两个不同变量的偏移量/大小如何不同?

更有趣的是,当我启动调试器并且 gdb 在 main 上暂停时,两个大小都是正确的(每个 29)。 比我在某处设置断点,当断点被击中时,我看到大小为 32 和 29。

内存地址怎么可能改变? 就像结构在内存中移动一样。 我就是想不通为什么....

作为我不是在做梦的“证明”,我附上了和以前一样的监视窗口。 您可以看到 eclipse/gdb 以黄色突出显示大小和偏移量,因为在某些时候它们从 29 变为 32。 够有趣的...... :)

highlighted watch window

【问题讨论】:

标签: c gcc gdb


【解决方案1】:

4*s32 + 3*u16 + 布尔 = 4*4+3*4+1 = 29

不是此结构的预期sizeof。由于填充,预期的 sizeof 为 32。

您获得29 的原因是该结构具有__attribute__((packed)),而您获得两种不同大小的事实意味着您的一些编译单元具有packed 属性,而另一些则没有。

这违反了单一定义规则和未定义的行为。

您需要找到这个packed 的来源,并使其在整个程序中保持一致。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多