C++ free(): invalid size 問題排查過程記錄

一、粗略瞭解bug基本情況

 從截圖可看出,錯誤原因爲free():invalid size xxxxx

我去網上搜索了下這個錯誤,https://stackoverflow.com/questions/18990767/free-ptr-error-invalid-size

初步結論:動態申請的內存結構被破壞了

二、從堆棧角度看問題

 是json::JsonWriter對象內部的string變量在析構時(即~basic_string出問題),可能是此接口被內存越界寫了!!!

三、從源代碼角度看問題

從源代碼角度來看,貌似沒有啥導致函數堆棧溢出的契機,上招數,我們先試圖把問題逐步簡化下。

將代碼的邏輯簡單抽象下,如下

void FuncA()
{
    uint64_t name;
    uint32_t age;
    //json::JsonWriter 變量
    
    //調用封裝函數,內部是msgrecv和msgsend
    Execute();
    json::JsonWriter writer; //報錯信息,writer變量中的string成員在析構時報錯
}

比較有意思的是,此錯誤有幾個特點

1.在release和debug模式下不同平臺下的bug情況

平臺 debug release
intel平臺
arm平臺

這種錯誤應該是函數堆棧溢出,但是至於是如何造成堆棧溢出的,一直沒找不到原因。

四、bug產生的原因

我以前處理過的堆棧溢出,一般都是幾種情況

1.函數內數組寫越界了

2.memcpy寫越界了

3.寫文件緩存區buffer時,寫越界了

但是在代碼中調用了Execute函數,這個函數中使用了msgsnd和msgrecv函數,查看這兩個函數的man文檔,終於發現了問題

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
               int msgflg);

 msgsz:傳遞的是mtext的長度,而不是總長度,但是公司代碼傳遞的長度是總長度,導致調用函數後寫入數據的長度大於正常值(多寫了4個字節或8個字節)。

至於爲啥在intel平臺下debug和release模式下都無此bug,估計是每個函數棧的尾部會預留一部分長度來防止寫越界,而我們寫入的4個字節或8個字節剛好在函數棧預留的長度範圍內,所以沒有導致bug的發生,只能說有點驚險。

參考鏈接:

http://www.c4learn.com/c-programming/c-mistakes/pointer/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章