你的浏览器不支持canvas

void类型指针强转后发生诡异偏移

Date: Author: zhangn

本文章采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。转载请注明来自zhangn的云笔记

先上代码,操作系统centos6.5,gcc版本4.4.7 20120313,纯C代码

int EvoSdtpImsiMIExt(void *arg, void *user)
{
    (void)user;
    EvoCallInfo *evi = (EvoCallInfo *)arg;
    uint32_t imsi_len   = EvoSdtpFieldsGetBCD(evi, 0, imsi);
}

EvoCallInfo是一个自定义的结构体,在外部malloc了一块内存,通过void 指针进行函数传递,在EvoSdtpImsiMIExt再强转回EvoCallInfo ,然后再用该指针调用EvoSdtpFieldsGetBCD函数,然后在EvoSdtpFieldsGetBCD中使用该结构。
那么问题来啦
在EvoSdtpFieldsGetBCD函数中一调用EvoCallInfo指针程序就挂掉了
然后定位了问题产生的原因,问题出现在EvoCallInfo evi = (EvoCallInfo _)arg;这一句上,将void 类型的arg指针强专成EvoCallInfo_类型的evi时,指针变量值发生诡异的位移,每次都向前位移了0x50个字节
下图是gdb调试信息,堆栈位于EvoSdtpImsiMIExt函数
在这里插入图片描述

在EvoSdtpFieldsGetBCD堆栈中,如果使用函数传进来的指针程序就挂掉,强行查看正确地址内存数据并没有问题
下图是gdb调试信息,堆栈位于EvoSdtpFieldsGetBCD函数
在这里插入图片描述

变量evi和eci有一个错误输入,大家忽略这个细节

如果不用中间变量中转,直接使用arg调用函数就没问题,下面是可以运行的代码

int EvoSdtpImsiMIExt(void *arg, void *user)
{
    (void)user;
    uint32_t imsi_len   = EvoSdtpFieldsGetBCD((EvoCallInfo *)arg, 0, imsi);
}

一直想不通为什么会产生这个bug,指针在进行强转的时候还会发生偏移?大家有没有遇到过类似的问题?请大家帮忙分析一下问题产生的原因


对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。