好诡异,void*指针强转后发生诡异偏移

木千 2018-10-31 10:05:57
先上代码,操作系统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,指针在进行强转的时候还会发生偏移?大家有没有遇到过类似的问题?请大家帮忙分析一下问题产生的原因

...全文
252 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
636f6c696e 2018-11-06
  • 打赏
  • 举报
回复
那这个问题无非是踩内存导致的,建议gdb watch看下哪里被串改了
引用 6 楼 mumufan05 的回复:
[quote=引用 4 楼 colinfang2006 的回复:] 你是说类型转换后是对的?但是到调用函数内部了就有问题? [quote=引用 3 楼 mumufan05 的回复:] [quote=引用 2 楼 colinfang2006 的回复:] 你贴的代码不会有这个问题,我怀疑会不会是代码和运行的程序不匹配? 或者你可以从便宜0x50=80字节来入手,结构体大小是不是刚好是80字节 并加一些调试打印,最好是刚刚转换类型后就打印两个指针的值
这两个方法我都试过了,结构体大于80个字节,前后加printf,打印的数据没问题,但实际调用的数据还是不对,所以说很诡异,而且目前只在一台机器上有这个问题,其他机器都没事,怀疑是硬件问题,但具体怎么回事想不明白[/quote][/quote] 不是,用printf打印是对的,但用gdb看就是错的[/quote]
jdgdf566 2018-11-06
  • 打赏
  • 举报
回复
需要重新构建项目
赵4老师 2018-11-05
  • 打赏
  • 举报
回复
学会使用数据断点。
ckc 2018-11-05
  • 打赏
  • 举报
回复
把所有的obj文件删除,全部重新编译一次看看 makefile写的不好有时候会有这个问题
真相重于对错 2018-11-02
  • 打赏
  • 举报
回复
建议看一下反汇编。
木千 2018-11-02
  • 打赏
  • 举报
回复
引用 4 楼 colinfang2006 的回复:
你是说类型转换后是对的?但是到调用函数内部了就有问题?

[quote=引用 3 楼 mumufan05 的回复:]
[quote=引用 2 楼 colinfang2006 的回复:]
你贴的代码不会有这个问题,我怀疑会不会是代码和运行的程序不匹配?
或者你可以从便宜0x50=80字节来入手,结构体大小是不是刚好是80字节
并加一些调试打印,最好是刚刚转换类型后就打印两个指针的值

这两个方法我都试过了,结构体大于80个字节,前后加printf,打印的数据没问题,但实际调用的数据还是不对,所以说很诡异,而且目前只在一台机器上有这个问题,其他机器都没事,怀疑是硬件问题,但具体怎么回事想不明白[/quote][/quote]
不是,用printf打印是对的,但用gdb看就是错的
林多 2018-11-02
  • 打赏
  • 举报
回复
确实诡异呀,同求答案。
smwhotjay 2018-11-02
  • 打赏
  • 举报
回复
用printf打印是对的,但用gdb看就是错的
你相信哪个是对的?
Saleayas 2018-11-02
  • 打赏
  • 举报
回复
我感觉你你的函数破坏了堆栈的原因。 你尝试不要调用里面的函数,直接检测试试看。 或者把断点设置在进入 EvoSdtpFieldsGetBCD 函数之前。
木千 2018-11-01
  • 打赏
  • 举报
回复
引用 2 楼 colinfang2006 的回复:
你贴的代码不会有这个问题,我怀疑会不会是代码和运行的程序不匹配?
或者你可以从便宜0x50=80字节来入手,结构体大小是不是刚好是80字节
并加一些调试打印,最好是刚刚转换类型后就打印两个指针的值

这两个方法我都试过了,结构体大于80个字节,前后加printf,打印的数据没问题,但实际调用的数据还是不对,所以说很诡异,而且目前只在一台机器上有这个问题,其他机器都没事,怀疑是硬件问题,但具体怎么回事想不明白
636f6c696e 2018-11-01
  • 打赏
  • 举报
回复
你贴的代码不会有这个问题,我怀疑会不会是代码和运行的程序不匹配? 或者你可以从便宜0x50=80字节来入手,结构体大小是不是刚好是80字节 并加一些调试打印,最好是刚刚转换类型后就打印两个指针的值
636f6c696e 2018-11-01
  • 打赏
  • 举报
回复
你是说类型转换后是对的?但是到调用函数内部了就有问题?
引用 3 楼 mumufan05 的回复:
[quote=引用 2 楼 colinfang2006 的回复:] 你贴的代码不会有这个问题,我怀疑会不会是代码和运行的程序不匹配? 或者你可以从便宜0x50=80字节来入手,结构体大小是不是刚好是80字节 并加一些调试打印,最好是刚刚转换类型后就打印两个指针的值
这两个方法我都试过了,结构体大于80个字节,前后加printf,打印的数据没问题,但实际调用的数据还是不对,所以说很诡异,而且目前只在一台机器上有这个问题,其他机器都没事,怀疑是硬件问题,但具体怎么回事想不明白[/quote]
云山大侠 2018-10-31
  • 打赏
  • 举报
回复
道行太浅,还真没看出什么毛病。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧