[紧急]貌似跟字符串、数组越界、堆栈内存溢出相关的疯狂崩溃问题

HengStar 2009-04-17 04:33:20
最近项目出现了一些怪异的问题,服务器崩溃的很频繁,大概描述一下情况,根据这么多天的观察发现每次崩溃都是跟内存和字符串相关的,我是从崩溃时生成的dmp文件中的堆栈信息中看到的,前面大部分都在malloc函数里面崩溃,但是当时内存使用才50~60%左右,所以可以排除内存空间不足的情况,然后就想到数组越界问题,把sprintf和strcpy函数都加入了长度越界检测和相关修正后,仍然没有解决问题,从最新的dmp文件堆栈信息里面看到崩溃处大概是在strcmp处的参数二地址问题,从dmp中看到的该参数的地址是0x00000007(以前也有0x00000013等之类的情况),显然不是一个合法的内存区域,不知道是不是dmp文件记录问题,以前也出现过不少类似的问题,该地址是通过上一层的函数的参数传递过来,而传递过来的是一个字符串字面值常量“G_INFO2”,难道还是因为数组越界改写了该地址,还是因为线程堆栈溢出导致?有没有什么好的办法能检测到具体出问题的位置,或是还有什么其它的可能性会导致这样的结果?请高手赐教!希望能尽快解决...非常感谢!
...全文
619 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
whhvc 2009-04-19
  • 打赏
  • 举报
回复
先申请一块大内存,然后重载内存申请函数,重大内存中获取内存,便于查找问题
sh365 2009-04-19
  • 打赏
  • 举报
回复
有没有拷贝出现越界到时数据覆盖?
xunhangchengwen 2009-04-18
  • 打赏
  • 举报
回复
UP
Chenzhouyi 2009-04-18
  • 打赏
  • 举报
回复
up!
fly_new 2009-04-17
  • 打赏
  • 举报
回复
目前来看,应该是内存越界之类的比较大。看你用的操作系统和编译器,这种问题没什么可怕的。
1。如果是你说的栈数据越界,比如memcopy之类的越界,比如你用VC(这个家伙常见点也号来)。你当前函数A调用memcpy,并发生局部变量越界,那memcpy退出就成问题,因为很大可能返回地址和保存的ebp寄存器破坏了,可能直接飞了。如果是某些嵌入式编译器,那A函数退出的时候就会出现问题,你只用检查A函数就可以了;

2。栈溢出,如果你用windows之类的程序,是会报警的,通常在哪个函数溢出就在那里报警。如果你的操作系统不自动告警,并且你可以自由访问栈空间的话,你在任务起来之前,把栈的所有数据清0或者ff,反正你认识就可以,然后当出现异常时,你想办法查看是否有任务的栈满过。当然这个在大型os上有点难度,因为你在任务起来之前访问栈有点难度。不过大型的os,栈溢出通常会告警的。

3。也是我觉得可能最大的,你使用堆的时候,越界了。这个问题要彻底定位稍微麻烦点,因为很可能是事后才知道,又不能打断点。你需要做的就是,自己写函数,把malloc和free封装了。利用一些操作系统和自己写的特性。我给你下面一些办法:
(1)可以规定释放后的内存,全部清0,或者其他无效值;
(2)或者释放后的入参,全部给清0,那free需要传入一个指向指针的指针;
(3)或者你自己在每次分配内存时,在给程序的内存后面打上标记,每次释放的时候检查这个标志,如果标志不在了,那马上报告异常,可以第一时间知道谁的内存错误;
(4)同时,在申请内存或者释放内存的同时,记下文件和行号;
(5)如果你的操作系统有虚拟空间的说法,并且有类似内存锁定的功能,那你可以把malloc封装。让每次分配的内存必须是一个页的整数倍;不足一页的部分,从页末开始向前分;当内存释放时,你把曾经分配出去的内存置为“不可访问”;如果一有人去访问就会出现段错误。

大体说了几个常见的办法,但是说的不清楚,有空可以慢慢交流。不知道能不能帮助你解决问题。一般说来,大型工程里,都会有封装操作系统的,如果有这一层,那你们做起来很方便,如果没有,你需要自己写代码去定位。
i95890347 2009-04-17
  • 打赏
  • 举报
回复
先思考一下看看。。。
liliangbao 2009-04-17
  • 打赏
  • 举报
回复
up!
zgjxwl 2009-04-17
  • 打赏
  • 举报
回复
帮gong顶顶~~~
osala 2009-04-17
  • 打赏
  • 举报
回复
我来列一下,可能出现的错误,也是我经常遇到的。

1.访问系统数据区,尤其是往系统保护的内存地址写数据

2.内存越界(数组越界,变量类型不一致等) 访问到不属于你的内存区域

3.内存重复释放,出现double free时,通常是由于这种情况所致。

4.内存泄露,分配的内存忘了释放。

5.给一个指针以0地址,使用了无效指针,或者对一个空指针进行操作




sherrik 2009-04-17
  • 打赏
  • 举报
回复
帮顶
xiaocha 2009-04-17
  • 打赏
  • 举报
回复
从最新的dmp文件堆栈信息里面看到崩溃处大概是在strcmp处的参数二地址问题,从dmp中看到的该参数的地址是0x00000007......,
该地址是通过上一层的函数的参数传递过来,而传递过来的是一个字符串字面值常量“G_INFO2”,

这样看来,就是strcmp所在函数,strcmp调用前出现了越界,仔细查一下代码,
考虑到参数和局部变量在内存的位置关系,重点关注有指针前移可能的代码。
aomeng 2009-04-17
  • 打赏
  • 举报
回复
先dump文件搞对,应该能做到根据文件中的地址定位到哪一行,这样就好找。

代码不长的话,找个有检验的人读一下,可能就能发现问题。

挂掉多半是指针非法导致的。
HengStar 2009-04-17
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 challenge99 的回复:]
看起来好复杂


我有次遇到的问题就是数组越界, 然后把我的一个指针被修改了, 检查下指针所在的栈上的数组的操作
[/Quote]
恩,这种情况的可能性比较大的,但是假设是这种情况,那么被修改的是指向一个字符串字面值的地址,这个应该是存储在全局静态区域的,编译器的字符串池选项是开启的。
challenge99 2009-04-17
  • 打赏
  • 举报
回复
看起来好复杂


我有次遇到的问题就是数组越界, 然后把我的一个指针被修改了, 检查下指针所在的栈上的数组的操作
HengStar 2009-04-17
  • 打赏
  • 举报
回复
内存检测也只能在自己内部调试测试的时候用,实际在服务器运行的时候要优先效率的
mengde007 2009-04-17
  • 打赏
  • 举报
回复
你们没有内存检测工具吗;程序员都有的;
HengStar 2009-04-17
  • 打赏
  • 举报
回复
没办法,公司代码不能泄露的...大家帮忙分析一下可能性的情况就好~dmp文件里看到的只是非法内存访问的结果崩溃,但是造成这个情况应该是之前的操作就可能导致的,就像malloc失败一样,我就是想了解有哪些情况会导致这种情况或者有什么方式可以检测这些情况
子晞 2009-04-17
  • 打赏
  • 举报
回复
能不能贴一下strcmp看看
mengde007 2009-04-17
  • 打赏
  • 举报
回复
没有源码;大家都是空谈理论;
liliangbao 2009-04-17
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 fibbery 的回复:]
最好都使用strn*系列函数,比如:strncpy\strncmp等等,我怀疑你在strcmp时字符串结尾没有\0字符。否则该函数不应该回发生内存访问违例的情况。
[/Quote]
Up,查一查程序,在认真分析dmp~
加载更多回复(4)

69,371

社区成员

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

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