有趣 | 最近遇到一個狡猾的bug,復盤分享
時間:2021-08-19 16:35:15
手機看文章
掃描二維碼
隨時隨地手機看文章
[導讀]關注「嵌入式大雜燴」,星標公眾號,一起進步!最近遇到一個看似青銅、實則王者的bug。事情是這樣的,某個進程有數(shù)據(jù)解析處理、算法融合。數(shù)據(jù)來源是gps模塊,我負責這個程序的開發(fā)維護、與算法對接。下面看看從這個bug的定位、分析、解決過程,一波三折~機器之前一直正常在跑,但近兩天做了...
關注「嵌入式大雜燴」,星標公眾號,一起進步!最近遇到一個看似青銅、實則王者的bug。
事情是這樣的,某個進程有數(shù)據(jù)解析處理、算法融合。數(shù)據(jù)來源是gps模塊,我負責這個程序的開發(fā)維護、與算法對接。下面看看從這個bug的定位、分析、解決過程,一波三折~機器之前一直正常在跑,但近兩天做了一些特殊測試,發(fā)現(xiàn)機器走到某個位置之后基本上必會出現(xiàn)段錯誤,因為與位置相關的就是數(shù)據(jù)了,所以剛開始的時候我懷疑可能是數(shù)據(jù)解析出問題了。但是之前解析有長時間測試過,沒什么問題,特殊位置也有測過沒什么問題。暫時排除了數(shù)據(jù)解析的問題。
事情是這樣的,某個進程有數(shù)據(jù)解析處理、算法融合。數(shù)據(jù)來源是gps模塊,我負責這個程序的開發(fā)維護、與算法對接。下面看看從這個bug的定位、分析、解決過程,一波三折~機器之前一直正常在跑,但近兩天做了一些特殊測試,發(fā)現(xiàn)機器走到某個位置之后基本上必會出現(xiàn)段錯誤,因為與位置相關的就是數(shù)據(jù)了,所以剛開始的時候我懷疑可能是數(shù)據(jù)解析出問題了。但是之前解析有長時間測試過,沒什么問題,特殊位置也有測過沒什么問題。暫時排除了數(shù)據(jù)解析的問題。
定位問題
遇到死機問題,當然得先定位問題,才能去分析、解決問題。定位段錯誤的方法有很多:1、log打印定位
可以把所有打印調(diào)試信息打開,一些段錯誤問題可以通過打印的方法就可以大致定位到某一塊代碼出現(xiàn)問題。打印方式只是定位段錯誤的一個小嘗試而已,不要對其結果抱有太大希望。有時候確實可以很快就定位到問題的根源,但針對本次的bug,通過打印的方式定位出的結果反而給我們帶來了一些迷惑。本次的bug通過打印的方式也鎖定到了出問題的代碼,在某個算法函數(shù)里的某兩個個三角函數(shù)的算式。問題就是屏蔽掉這個算式,程序就沒出現(xiàn)段錯誤,打開這兩句代碼就必出現(xiàn)段錯誤,這讓我的注意力集中在了這個地方。但反反復復看了好多次沒發(fā)現(xiàn)這兩個算式有什么不妥的地方,而且看了前后兩層函數(shù),也沒發(fā)現(xiàn)有什么不妥。最后定位出了問題,這里確實不是問題的根源,但卻在這浪費了很多時間。應該有很多小伙伴跟我有同樣的習慣,喜歡通過打印法來查找bug,打印法基本能定位到大多數(shù)問題。但對于一些藏得很深的bug,通過打印法有時候只看到了表象,而我們有時候會被這表象給迷惑了。所以在分析問題的時候,盡量頭腦清醒些,分析遇到不太合理的地方,要不斷的推敲,不斷地推翻不合理地分析。當然,有好的定位問題的方法也很重要,下面看第二種定位段錯誤的方法:2、遠程調(diào)試
遠程GDB是一種適合嵌入式系統(tǒng)的調(diào)試手段。它使用目標機端的gdbserver和主機端的gdb調(diào)試器協(xié)同進行調(diào)試,再搭配vscode可以很方便地進行調(diào)試。vscode gdb gdbserver遠程調(diào)試的教程見:干貨 | 遠程gdb調(diào)試?遠程GDB的原理是:?有一小段駐留在目標機上的代碼,它被稱為調(diào)試樁,也稱為調(diào)試代理。調(diào)試代理負責目標機上實現(xiàn)由主機上的調(diào)試器發(fā)送過來的調(diào)試命令,例如:讀寫內(nèi)存、讀寫寄存器、設置斷點及運行被調(diào)試程序等。調(diào)試代理還要向主機調(diào)試器報告目標機上的異常事件。?啟動遠程調(diào)試,全速運行,當程序出現(xiàn)段錯誤時可以很快知道出現(xiàn)段錯誤的代碼行號。本次的這個bug也是使用這種方法來快速定位出來的。除此之外還有其它很多方法來定位段錯誤,如使用strace工具跟蹤、gdb調(diào)試core文件等方法,后續(xù)有機會再寫使用分享。
分析、解決問題
通過遠程調(diào)試的方法可以快速定位到本次的段錯誤出現(xiàn)在一個串口讀函數(shù)里的下面這一句代碼:FD_SET(fd,