一、粗略瞭解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的發生,只能說有點驚險。
參考鏈接: