c语言--在arm上奇怪的溢出问题

KEN123123 2015-09-30 11:01:56
我使用的开发环境是ubuntu下 arm-linux-gcc 4.5.1编译,用网上下载的Insight3加百度到的注册码写代码,共享到ubuntu下使用make编译。
现像:
一个int 型的全局变量,最大合理值一般不会超过1024(实际在那里的日志int大小不到100才对),但在那个数据在日志显示中为:
808521728(十进制),
30311000(十六进制)
我的处理办法:
在日志中多加了几行日志输出,看看是哪个地方开始出现这个数据不正常。

使用以下二个输出函数输出日志:
API_Trace 这个函数是项目里的定义函数,多地使用。
个人自己加的一个处理宏定义函数:
#define debug(format,...) API_Trace(DBG_APP_INFO,"[%s][%s][%d]:"format,__FILE__,__func__,__LINE__,__VA_ARGS__);

个人认为以上还是合理的,奇怪的事出来了,bug消失了。对,没错,就是加了这几行日志,bug消失了。


因为这是公司的代码,问题也不能重现,所以我只是想得到几个可能出现这种情况的分析,多了解了解。


问题补充:
以前我这个项目里也出现过类似的问题,加入日志信息,然后看数据哪里出错了,最后找到一个arm系统上的库函数:vsprintf,在这个函数之前,值都是正常的,到了这个函数调用,进程就死了(在我这arm上运行,如果出现段错误,是不会有提示信息的,而是直接死进程,比如:printf("%s",NULL);这行运行就直接死进程)。问题也是在我找不到解决方案的时候,没有针对这问题写了点代码,这bug就没了。
...全文
249 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
KEN123123 2015-09-30
  • 打赏
  • 举报
回复
引用 楼主 u010424970 的回复:
我使用的开发环境是ubuntu下 arm-linux-gcc 4.5.1编译,用网上下载的Insight3加百度到的注册码写代码,共享到ubuntu下使用make编译。 现像: 一个int 型的全局变量,最大合理值一般不会超过1024(实际在那里的日志int大小不到100才对),但在那个数据在日志显示中为: 808521728(十进制), 30311000(十六进制) 我的处理办法: 在日志中多加了几行日志输出,看看是哪个地方开始出现这个数据不正常。 使用以下二个输出函数输出日志: API_Trace 这个函数是项目里的定义函数,多地使用。 个人自己加的一个处理宏定义函数: #define debug(format,...) API_Trace(DBG_APP_INFO,"[%s][%s][%d]:"format,__FILE__,__func__,__LINE__,__VA_ARGS__); 个人认为以上还是合理的,奇怪的事出来了,bug消失了。对,没错,就是加了这几行日志,bug消失了。 因为这是公司的代码,问题也不能重现,所以我只是想得到几个可能出现这种情况的分析,多了解了解。 问题补充: 以前我这个项目里也出现过类似的问题,加入日志信息,然后看数据哪里出错了,最后找到一个arm系统上的库函数:vsprintf,在这个函数之前,值都是正常的,到了这个函数调用,进程就死了(在我这arm上运行,如果出现段错误,是不会有提示信息的,而是直接死进程,比如:printf("%s",NULL);这行运行就直接死进程)。问题也是在我找不到解决方案的时候,没有针对这问题写了点代码,这bug就没了。
相信大大你是没有细看我的描述,看了标题才给出这个信息,首先,至少以我了解到的,在arm上调试的信息,不能用vc 里的debug或类似linux下的gdb工具(虽然我也想学,也会其原理,但就是还没用过,都是一直以结果反推原因),公司里的人都是用输出日志来判断,而这个int变量是定义在一个很大的全局结构体上,定义上,int之前有一个512字节的char buff[]空间,buff内容是写死的,很小。 主要问题是,出现这个现象的解释是什么,我想多学习多了解下。如原文中的红色字体: 因为这是公司的代码,问题也不能重现,所以我只是想得到几个可能出现这种情况的分析,多了解了解。
jiqiang01234 2015-09-30
  • 打赏
  • 举报
回复
既然加日志无法观测错误,可以把怀疑的地方注释掉,逐步缩小范围
赵4老师 2015-09-30
  • 打赏
  • 举报
回复
越界访问。 判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
#include <time.h>
#include <stdlib.h>
#include <windows.h>
int main() {
    int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]

    srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
    while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
        b[(a=rand()%11)]=0;
        Sleep(100);
        b[(a=rand()%11)]=1;
        Sleep(100);
        b[(a=rand()%11)]=2;
        Sleep(100);
        b[(a=rand()%11)]=3;
        Sleep(100);
        b[(a=rand()%11)]=4;
        Sleep(100);
    }
    return 0;
}
KEN123123 2015-09-30
  • 打赏
  • 举报
回复
引用 2 楼 jiqiang01234 的回复:
既然加日志无法观测错误,可以把怀疑的地方注释掉,逐步缩小范围
以下是早上想回复但因网络和帐号问题没能及时回复: 这个方法本来我也想用的,我用编写代码的软件返回修改,返回到今天最新(程序是昨天编译的,今天电脑失去控制,强制重起,代码本来是软件打开的,已忘记昨天是否有过其它修改,但我个人理解是与它无关的),返回最新后,编译后,生成的程序的md5值也不一样了,现象没再现。这个确实也怪我没能保护当时的环境,刚工作不久,很多习惯、svn使用都不怎么好(如果可以也希望能有这方面的文章看看)。 下午发生的情况: 继续处理我所说的溢出情况,全局结构体gsystem里的char buff[120]后定义了一个char str[12],写入buff时,我个人一直认为是成功的,也strlen(buff)过长度小于120,使用memcpy();复制内容到buff的(memcpy第三个长度参数是没有超的),但还就是发现,buff的最后几个字符写入到了str里。 然后修改,加日志,查原因,然后,新的程序在另外一个地方运行的时候又死了,这个地方日志不足,一路奇怪之后,我就使用了make clean,再make,一切正常了。 然后,我找到了以前结的这个项目,也是我写的,在这个地方并不会写数组超出,且经测试通过,

69,374

社区成员

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

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