Ozone可以幫助用戶快速分析和查找導(dǎo)致CPU故障的軟件bug。本文解釋如何使用Ozone的調(diào)試功能,深入了解Cortex-M架構(gòu)上的這些錯(cuò)誤。
故障分析流程
我們首先基于一個(gè)示例應(yīng)用程序演示Ozone的故障分析工作流。示例應(yīng)用程序可以生成不同類型的Cortex-M故障,工程下載鏈接https://wiki.segger.com/File:CortexM_FaultTest.zip(請(qǐng)復(fù)制鏈接到瀏覽器下載)。在下圖中,示例應(yīng)用程序被下載到SEGGER Cortex-M trace參考板,調(diào)試工具使用J-Trace PRO。程序執(zhí)行到函數(shù)_NoThumbFunc中,PC位于跳轉(zhuǎn)到地址0的指令處,由于在地址0處是一條Thumb指令,繼續(xù)執(zhí)行程序?qū)?dǎo)致Cortex-M CPU故障?;謴?fù)程序執(zhí)行,看看Ozone是如何處理故障。
目標(biāo)異常對(duì)話框
點(diǎn)擊GO后,程序執(zhí)行中斷,Ozone彈出目標(biāo)異常對(duì)話框:
目標(biāo)異常對(duì)話框描述了CPU故障及其系統(tǒng)寄存器上下文。本例中,SHCSR寄存器的USGFAULTACT位表示發(fā)生了一個(gè)Cortex-M UsageFault異常。寄存器UFSR提供了發(fā)生的UsageFault異常的具體類型。示例中,INVSTATE位被置位,表示指令在無(wú)效的CPU狀態(tài)下執(zhí)行。USGFAULTENA字段表示啟用了UsageFault處理程序,否則異常將升級(jí)為HardFault。異常寄存器上下文的解釋與特定體系結(jié)構(gòu)相關(guān),Ozone旨在通過(guò)異常描述顯示盡可能多的處理信息,當(dāng)程序執(zhí)行停止并且目標(biāo)處于異常狀態(tài)時(shí),會(huì)顯示目標(biāo)異常對(duì)話框。
向量捕獲
當(dāng)調(diào)試會(huì)話開(kāi)始時(shí),Ozone設(shè)置捕獲所有Cortex-M故障向量,在程序進(jìn)入錯(cuò)誤處理程序時(shí)立即中斷執(zhí)行,也使Ozone能夠在故障進(jìn)入時(shí)立即彈出目標(biāo)異常對(duì)話框??梢酝ㄟ^(guò)Ozone的Break&Tracepoints窗口設(shè)置或清除某個(gè)向量捕獲。Ozone也提供命令Break.SetVectorCatch以編程方式設(shè)置目標(biāo)的向量捕獲狀態(tài)。例如,該命令可以用來(lái)修改Ozone在調(diào)試會(huì)話開(kāi)始時(shí)的默認(rèn)vector catch 的行為,該命令在項(xiàng)目腳本函數(shù)OnProjectLoad中使用。
調(diào)試窗口
使用Ozone的調(diào)試窗口來(lái)進(jìn)一步了解故障。
Call Stack窗口表示目標(biāo)處于UsageFault異常狀態(tài)。該窗口還指出故障源自函數(shù)_NoThumbFunc。在Call Stack窗口中選擇_NoThumbFunc調(diào)用幀,Ozone的調(diào)用幀感知調(diào)試窗口將輸出切換到所選幀的執(zhí)行上下文。Local Data窗口表明在_NoThumbFunc函數(shù)中執(zhí)行了一個(gè)到地址0的跳轉(zhuǎn),導(dǎo)致CPU在ARM狀態(tài)下執(zhí)行Thumb指令。查看Ozone的寄存器窗口,寄存器UFSR確認(rèn)CPU已經(jīng)發(fā)出INVSTATE UsageFault。這是Ozone基本故障分析工作流程。
嵌套的異常
Ozone可以提供關(guān)于Cortex-M上嵌套異常和嵌套故障的準(zhǔn)確信息。為了演示這一點(diǎn),讓我們繼續(xù)調(diào)試前一節(jié)的示例應(yīng)用程序。我們現(xiàn)在用一條未定義的指令覆蓋UsageFault處理程序的單個(gè)分支指令:
在跳過(guò)0x8000384地址的未定義指令后,Ozone的目標(biāo)異常對(duì)話框再次彈出:
對(duì)話框通知搶占了UsageFault異常的為HardFault異常。除了寄存器字段INVSTATE之外,還設(shè)置了字段UNDEFINSTR。這表明在調(diào)用路徑中發(fā)生了兩種類型的UsageFault異常。HFSR寄存器字段FORCED進(jìn)一步表明UNDEFINSTR異常已經(jīng)升級(jí)為HardFault。
由于Cortex-M CPU現(xiàn)在正在處理嵌套異常,Ozone的Call Stack窗口相應(yīng)更新:
在多個(gè)堆棧上嵌套異常
關(guān)于嵌套異常的信息可以占用兩個(gè)堆棧,如下一個(gè)示例所示,在這種情況下,Ozone能夠提供準(zhǔn)確的調(diào)用堆棧和本地?cái)?shù)據(jù)信息。本例中,程序執(zhí)行已停止在調(diào)用堆棧5級(jí)的SVC指令上:
在執(zhí)行SVC調(diào)用之后,在處理程序模式下執(zhí)行了一個(gè)附加的函數(shù)調(diào)用路徑。應(yīng)用程序現(xiàn)在停止在load加載指令上,該指令即將從無(wú)效地址0x100000加載:
此時(shí),Ozone的Call Stack窗口表明堆棧交換已經(jīng)發(fā)生。從表列stack Used中堆棧使用值0的位置,用戶可以看到:
上面的調(diào)用幀,包括SVC_Handler都在主棧上。
下面的調(diào)用幀,包括SVCall Exception)位于進(jìn)程堆棧上。
當(dāng)前使用了40字節(jié)的主堆棧和88字節(jié)的進(jìn)程堆棧。
注意,Ozone用尖括號(hào)括起了特定于目標(biāo)的調(diào)用幀。繼續(xù)執(zhí)行程序,看看Ozone是如何處理即將發(fā)生的故障。程序恢復(fù)執(zhí)行后,立即彈出目標(biāo)異常對(duì)話框,指示HardFault異常:
由于沒(méi)有啟用BusFault異常處理程序,Cortex-M將BusFault異常升級(jí)為HardFault。寄存器字段PRECISERR表示發(fā)生了精確的BusFault異常。字段BFARVALID表示錯(cuò)誤的load/store指令的內(nèi)存訪問(wèn)地址可用。Ozone將所有這些信息集成到目標(biāo)異常對(duì)話框頂部區(qū)域中的異常描述中。字段SVCALLACT進(jìn)一步表明,一個(gè)SVC處理程序已被當(dāng)前異常搶占。
關(guān)閉目標(biāo)異常對(duì)話框,使用Ozone的調(diào)試窗口進(jìn)一步調(diào)查故障。
如上圖所示,Ozone的調(diào)用幀感知調(diào)試窗口提供了故障的清晰圖像:Local data窗口顯示了解引用數(shù)據(jù)指針的無(wú)效值。Call Stack窗口顯示完整的程序執(zhí)行路徑,跟蹤多個(gè)嵌套異常和CPU堆棧。用戶可以在register窗口中查詢到相同信息。
使用Trace分析故障
在不精確的故障場(chǎng)景中,當(dāng)Cortex-M內(nèi)核無(wú)法提供故障指令的精確PC時(shí),可以使用Ozone的trace窗口來(lái)快速識(shí)別故障指令,確定更復(fù)雜故障的原因,特別是不精確的故障。
如上圖所示,使用Ozone的回溯特性,可以很容易地將不精確的BusFault異常追溯到出錯(cuò)的存儲(chǔ)指令。
Ozone是一塊面向嵌入式應(yīng)用程序的調(diào)試器。使用Ozone,可以在C/ C++ /Rust源代碼和匯編級(jí)別調(diào)試嵌入式應(yīng)用。Ozone與J-Link和J-Trace緊密集成,提供豐富的調(diào)試分析功能。
-
寄存器
+關(guān)注
關(guān)注
31文章
5343瀏覽量
120348 -
cpu
+關(guān)注
關(guān)注
68文章
10863瀏覽量
211744 -
應(yīng)用程序
+關(guān)注
關(guān)注
37文章
3268瀏覽量
57704 -
Cortex-M
+關(guān)注
關(guān)注
2文章
229瀏覽量
29761
原文標(biāo)題:如何使用Ozone分析Cortex-M異常
文章出處:【微信號(hào):麥克泰技術(shù),微信公眾號(hào):麥克泰技術(shù)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論