头文件定义的类与so中同名类的大小不同导致的奇葩问题


昨天晚上临下班之际,终于把程序编译成功了。开开心心的运行,结果,遇到了神奇的bug,接下来花了n个小时去解决这个神奇的bug。

    下面是我调试的时候,对奇葩问题的截图。

                            

                        图1-奇葩问题

从图中我们可以看到,在程序的cout打印中,cmd的输出是1,但是在gdb的print打印的时候,值却是0,而且在动态库的函数中使用这个结构体时,值也是0。这就让我百思不得其解。怎么会有这么神奇的问题?为什么会这样?

    当时因为没有往这个类的结构上去想,所以一直在各种尝试,各种debug,甚至连watch的手段都用上了,怀疑中间cmd的值是不是被修改过,然而没有。

    中间尝试过把这个类头文件对应的.cpp文件单独编译成.o文件,然后链接到main中,执行的时候,正常了。才醒觉so中的类和头文件中的类肯定有差异。接下来就是把so文件对应的代码中的.h文件覆盖原来的.h文件,编译,执行,正常了。

    到此,才彻底搞明白,原来我之前的.h文件是旧的,是上一个版本的文件,而so对应的.h是新版的,仔细查看了下两个.h的差异,原来某个指定数组大小的宏的值修改了。

    今天打印了下两个类的大小差异,输出是这样的:

    CSG17Packet in .h, sizeof:61528

    CSG17Packet in so,.sizeof:131160

很显然,两个大小不同。所以在.so中的cmd和后面的所有字段值都是0,被0填充了。

    这么看起来,之前我在对象的栈上,申请了CSG17Packet对象,然后运行的时候,coredump了,查看core文件,print该类的某个成员,提示Cannot access memory at address 0x7fffed5a6d70。我以为是栈空间不足,导致出的段错误。

    使用ulimit -a看到栈的大小是(kbytes, -s) 10240,当时可能是头脑发晕,没看清楚是10M,以为是10k,就认为真是栈空间不足,所以后面又用new申请空间,然后出现了上面说的那问题。

    现在想来,当时出现错误的原因应该是栈被破坏了。.h中的类大小是61528,所以栈就这么大,但是在构造的时候,是用的.so的类大小,大小是131160,越界了。所以出现段错误。

    这个错误告诉我,遇到bug,首先要冷静,尽管昨天晚上有点感冒,但也不应该得出栈空间不足导致的段错误,从而将解决问题的方向引导向了错误的位置。反思自己。



评论

发表评论