一个从32位机器移植到64位机器时的c问题
最近工作中遇到了一个讨厌的问题,在32位机器上运行的好好的,但是在64位机器上,出现了诡异的 Segmental fault。
于是调试分析,一切似乎都很正常。开始怀疑是否由于使用了变参。因为proc不支持...形式的变参,所以,不得已自己写了一个类似printf这样的变参,和proc程序分开。这个函数如下:
?
?
rax 0x2ba3320526c0 47979918862016rbx 0x2ba331e6f5e8 47979916883432rcx 0x0 0rdx 0x0 0rsi 0x320526c0 839198400rdi 0x2ba33201c036 47979918639158?这是在get_last_error()返回以后的寄存器情况。细心的人可能已经发现问题了。get_last_error()返回值作为参数,首先放在了rax,然后被放到rsi作为参数,这是gcc x64上的变参调用时参数保存方式。而我们在rsi里看到什么了?这个值正好是rax里的低32位,这就是说,返回get_last_error()时,返回的char * ,在x64机器上应该为64位的char *,居然变成了32位的值。为什么?为什么?我们也可以看到,get_last_error()的返回值,确实是char * 啊。这种疑惑,我又做了无数的猜疑,但是突然想到一点,c语言中,如果没有函数原型的声明,那么,返回值会被默认为int型,而int在x64的机器上是32位的!肯定就是这个原因,于是打开get_last_error()这个函数的c文件,果然没有包含一个头文件,而头文件的作用,也就是声明函数原型。当然,调用语句所在的c文件,也没有用到声明get_last_error()的头文件。于是加上原型函数声明,再试,好了。纠结了近两天的问题圆满解决!
?