轉(zhuǎn)自:http://www.cnblogs.com/mfryf/p/3493614.html內(nèi)存寫越界導(dǎo)致破環(huán)堆結(jié)構(gòu)引起的崩潰問題定位經(jīng)驗(yàn)[如報(bào)錯malloc(): memory corruption或free(): invalid next size]前段時間開發(fā)的一個后端C模塊上線后,,線上出core,初始時,,因?yàn)樵L問壓力不大,,所以崩潰是上線3天左右出現(xiàn)的。當(dāng)時用gdb跟進(jìn)調(diào)用堆棧并檢查源代碼,,發(fā)現(xiàn)出core位置的代碼沒有啥問題,。因?yàn)楫?dāng)時開發(fā)任務(wù)較重,且該模塊不保存狀態(tài)(崩潰重新啟動不影響對外服務(wù)),,所以沒有深入跟進(jìn),。后來隨著client版本號逐漸放量導(dǎo)致訪問壓力上升,,噩夢開始了。,。,。 =============== EOF ================= ==================================================== 1,、一次申請超過剩余內(nèi)存大小,會“Cannot allocate memory” 但是多次申請內(nèi)存,,總量大于內(nèi)存總大小卻沒有報(bào)錯,??,?,?? 2,、一次申請的內(nèi)存,,在不使用的情況下,free,、top查看內(nèi)存情況無變化 3,、將內(nèi)存memset清零時,free,、top查看內(nèi)存減少申請的大小 ================================================================ 昨天在修改自己的代碼的時候,,碰到了malloc函數(shù)內(nèi)存分配失敗,上網(wǎng)翻了翻,,一個很可能的原因是之前的代碼出現(xiàn)了越界操作,,導(dǎo)致malloc分配函數(shù)所涉及的一些信息被破壞。在這個思想的指導(dǎo)下,,今天又是郁悶了一整天,,來來回回看自己的代碼。又加不斷的調(diào)試,,終于發(fā)現(xiàn)自己的代碼中有一個malloc分配的內(nèi)存大小為0,,不是自己預(yù)想的大小,而之后的代碼又按預(yù)想的大小對內(nèi)存進(jìn)行了操作,,導(dǎo)致了下一個malloc無法分配內(nèi)存,。 總結(jié)自己的問題,如果下一次再碰到這樣的問題,,就要查從不能分配的那個malloc函數(shù)開始往回找最近的那個能分配的malloc,,出問題的代碼應(yīng)該就在這部分,,很可能的原因就是指針越界,對未知的內(nèi)存進(jìn)行了操作,,導(dǎo)致了malloc不能繼續(xù)分配內(nèi)存,。 ================================================================= 以前分配的比這還大不代表你這次分配大內(nèi)存就能成功。分配成功的前提是你進(jìn)程內(nèi)部有足夠大的連續(xù)可用的內(nèi)存 注意:前提有兩個,,第一是可用,,第二還必須“連續(xù)” 也就是說,要是你進(jìn)程內(nèi)沒有一塊內(nèi)存大于你要求的尺寸,,分配就失敗 ============================================================= 在C語言中, 執(zhí)行到malloc程序core的時候, 一般人的第一反應(yīng)是內(nèi)存空間不足. 常見的代碼為:
有的C編譯器對沒有聲明的函數(shù), 是不報(bào)錯的(有的連警告都沒有, C編譯器認(rèn)為程序員永遠(yuǎn)是正確的). 糟糕的是, C編譯器默認(rèn)認(rèn)為函數(shù)的返回值是int類型. 如果沒有加以下頭文件的話:
程序把malloc的返回值強(qiáng)轉(zhuǎn)成int, 然后再轉(zhuǎn)成int*. 于是程序core了. ============================================================== 最近在代碼調(diào)試過程中發(fā)現(xiàn)一很無解的bug,,跟蹤到代碼發(fā)現(xiàn)malloc()函數(shù)總是申請空間失敗,返回0地址,。這類bug往往很難定位,,因?yàn)榍懊孢\(yùn)行正常不出錯。經(jīng)過仔細(xì)琢磨發(fā)現(xiàn)問題出現(xiàn)在malloc()函數(shù)前面的代碼中,,如果前面代碼使用到memset或者memcpy等類似函數(shù),,并且在使用過程中發(fā)生地址越界,則可能導(dǎo)致后面的malloc申請空間失敗,,所以此時應(yīng)檢測前面的代碼,。 別人已經(jīng)提到的類似例子: #include <stdlib.h> ============================================================== malloc失敗情況 1、堆空間被越界的操作或整理操作破壞了 memset,、*指針賦值2、內(nèi)存碎片多,,沒有一塊連續(xù)的內(nèi)存適合申請的大小,,即使內(nèi)存剩余總量大于需要申請的大小也會失敗。 3,、在C語言中, 執(zhí)行到malloc程序core的時候, 一般人的第一反應(yīng)是內(nèi)存空間不足. 常見的代碼為:
有的C編譯器對沒有聲明的函數(shù), 是不報(bào)錯的(有的連警告都沒有, C編譯器認(rèn)為程序員永遠(yuǎn)是正確的). 糟糕的是, C編譯器默認(rèn)認(rèn)為函數(shù)的返回值是int類型. 如果沒有加以下頭文件的話:
程序把malloc的返回值強(qiáng)轉(zhuǎn)成int, 然后再轉(zhuǎn)成int*. 于是程序core了. |
|