转自:http://www.cnblogs.com/mfryf/p/3493614.html内存写越界导致破环堆结构引起的崩溃问题定位经验[如报错malloc(): memory corruption或free(): invalid next size]前段时间开发的一个后端C模块上线后,线上出core,初始时,因为訪问压力不大,所以崩溃是上线3天左右出现的。当时用gdb跟进调用堆栈并检查源代码,发现出core位置的代码沒有啥问题。因为当时开发任务较重,且该模块不保存状态(崩溃重新启动不影响对外服务),所以沒有深入跟进。后来随着client版本号逐渐放量导致訪问压力上升,噩梦開始了。。。 =============== EOF ================= ==================================================== 1、一次申请超过剩余内存大小,会“Cannot allocate memory” 但是多次申请内存,总量大于内存总大小却没有报错????? 2、一次申请的内存,在不使用的情况下,free、top查看内存情况无变化 3、将内存memset清零时,free、top查看内存减少申请的大小 ================================================================ 昨天在修改自己的代码的时候,碰到了malloc函数内存分配失败,上网翻了翻,一个很可能的原因是之前的代码出现了越界操作,导致malloc分配函数所涉及的一些信息被破坏。在这个思想的指导下,今天又是郁闷了一整天,来来回回看自己的代码。又加不断的调试,终于发现自己的代码中有一个malloc分配的内存大小为0,不是自己预想的大小,而之后的代码又按预想的大小对内存进行了操作,导致了下一个malloc无法分配内存。 总结自己的问题,如果下一次再碰到这样的问题,就要查从不能分配的那个malloc函数开始往回找最近的那个能分配的malloc,出问题的代码应该就在这部分,很可能的原因就是指针越界,对未知的内存进行了操作,导致了malloc不能继续分配内存。 ================================================================= 以前分配的比这还大不代表你这次分配大内存就能成功。分配成功的前提是你进程内部有足够大的连续可用的内存 注意:前提有两个,第一是可用,第二还必须“连续” 也就是说,要是你进程内没有一块内存大于你要求的尺寸,分配就失败 ============================================================= 在C语言中, 执行到malloc程序core的时候, 一般人的第一反应是内存空间不足. 常见的代码为:
有的C编译器对没有声明的函数, 是不报错的(有的连警告都没有, C编译器认为程序员永远是正确的). 糟糕的是, C编译器默认认为函数的返回值是int类型. 如果没有加以下头文件的话:
程序把malloc的返回值强转成int, 然后再转成int*. 于是程序core了. ============================================================== 最近在代码调试过程中发现一很无解的bug,跟踪到代码发现malloc()函数总是申请空间失败,返回0地址。这类bug往往很难定位,因为前面运行正常不出错。经过仔细琢磨发现问题出现在malloc()函数前面的代码中,如果前面代码使用到memset或者memcpy等类似函数,并且在使用过程中发生地址越界,则可能导致后面的malloc申请空间失败,所以此时应检测前面的代码。 别人已经提到的类似例子: #include <stdlib.h> ============================================================== malloc失败情况 1、堆空间被越界的操作或整理操作破坏了 memset、*指针赋值2、内存碎片多,没有一块连续的内存适合申请的大小,即使内存剩余总量大于需要申请的大小也会失败。 3、在C语言中, 执行到malloc程序core的时候, 一般人的第一反应是内存空间不足. 常见的代码为:
有的C编译器对没有声明的函数, 是不报错的(有的连警告都没有, C编译器认为程序员永远是正确的). 糟糕的是, C编译器默认认为函数的返回值是int类型. 如果没有加以下头文件的话:
程序把malloc的返回值强转成int, 然后再转成int*. 于是程序core了. |
|
来自: 海漩涡 > 《knowledge》