bug出現(xiàn)的時(shí)間點(diǎn)
- 2015-10-13 我負(fù)責(zé)的一個(gè)使用c寫的業(yè)務(wù)進(jìn)程奔潰,使用gdb查看coredump文件發(fā)現(xiàn)是在對業(yè)務(wù)包做反序列化的時(shí)候,在序列化庫里崩潰了。
- 當(dāng)時(shí)懷疑是業(yè)務(wù)包有問題,但也不能排除業(yè)務(wù)進(jìn)程踩內(nèi)存的可能,因?yàn)楹罄m(xù)這個(gè)奔潰也再?zèng)]出現(xiàn),且哪個(gè)時(shí)候排查手段也不多,故沒有深入去排查這個(gè)bug。
- 2017-04-27 這個(gè)業(yè)務(wù)奔潰了兩次和2015-10-13是一樣的堆棧。
進(jìn)程“死亡現(xiàn)場”
使用gdb細(xì)看coredump文件發(fā)現(xiàn)是在反序列化解析過程中解析失敗然后跳到清理邏輯,在釋放一個(gè)數(shù)組內(nèi)存的時(shí)候引用的了空指針從而導(dǎo)致的奔潰,庫代碼在釋放內(nèi)存時(shí)沒做空指針校驗(yàn)。
排查過程
這個(gè)時(shí)候還是不能完全排除業(yè)務(wù)進(jìn)程踩內(nèi)存導(dǎo)致業(yè)務(wù)包異常的問題,但是相比2015-10-13日我們已經(jīng)添加了一個(gè)請求和應(yīng)答稽核數(shù)據(jù),這個(gè)數(shù)據(jù)會(huì)記錄客戶端所有的請求和應(yīng)答數(shù)據(jù),通過這個(gè)數(shù)據(jù)稽核查看工具發(fā)現(xiàn)對應(yīng)有問題的業(yè)務(wù)請求的確是有問題的,那么這時(shí)我們可以確認(rèn)這個(gè)bug是由客戶端導(dǎo)致的,而不是業(yè)務(wù)進(jìn)程踩了內(nèi)存。
修復(fù)問題
- 修改反序列化庫中釋放空間的代碼,添加上空指針的檢查,規(guī)避服務(wù)端收到問題請求崩潰問題,從而導(dǎo)致業(yè)務(wù)中斷。
- 把現(xiàn)象和數(shù)據(jù)反饋給客戶端,讓客戶端去排查問題。
思考
任何系統(tǒng)做大之后,業(yè)務(wù)數(shù)據(jù)都會(huì)通過很多環(huán)節(jié)和系統(tǒng),出現(xiàn)問題很難排查,通常很有必要對業(yè)務(wù)請求做全路徑的監(jiān)控和記錄,這樣查問題時(shí)才能事半功倍。