以前查找這種錯誤時比較盲目,就是在程序中縷着流程一步步的查找,逐個屏蔽進行排除,在程序隔一段加個while(1),以及通過串口發出錯誤狀態日誌等……這些方法都效率低下,不易查找。相比之下,查看堆棧的方法更加實用,效率也高。
在HardFault_Handler中的while(1)設置斷點,然後運行,給它觸發HardFault_Handler的條件,然後到斷點處之後,查看watch窗口中的Call Stack+Local,也就是堆棧以及局部變量,程序執行到哪一句發生的錯誤,以及當時各個壓棧的函數的各個局部變量的值一目瞭然,這裏記錄了死者臨死前的五分鐘到底對自己做了什麼傻事……
如下圖,就是對一個地址爲NULL的空指針 p 進行解引用操作造成的HardFault_Handler錯誤
Call Stack+Local窗口內顯示了發生錯誤之前的程序狀態,當然,這只是導致程序錯誤的直接原因,有時候想要找到根源還是要繼續花好大的一番功夫的,累積性的,概率性的死機(比如昨天……找BUG的這一慘痛經歷,這裏就不多說了,說多了全是眼淚……),但是至少是提供了一個瓜藤,你需要做的就是順藤摸瓜了~把這個BUG消滅掉!
同樣的方法還可以擴展到其他編程環境中。各位看客舉一反三即可。(截圖中是Keil)總之就是一句話:查看錯誤發生時的堆棧情況。
同樣,在visual studio中:
同樣,在這裏用對空指針進行解引用操作這種錯誤作爲例子,同樣通過查看調用堆棧方式以及局部變量來確定錯誤的位置(當然,沒人會像我截圖中那樣使用,這裏只是想凸顯一下壓棧以及確定錯誤位置的過程),接下來的工作同樣是順藤摸瓜。
當然,這只是發生HardFault_Handler錯誤的一種情況而已,像其他還有堆棧溢出,除數爲0之類的也會發生該錯誤。歡迎補充。
還是那句話,不存在不存在BUG的程序,別說Hello World!