異常接管是操做系統對在運行期間發生異常的狀況進行處理的一系列動做,譬如打印異常發生時當前函數調用棧信息、 cpu現場信息、任務的堆棧狀況等。shell
異常接管做爲一種調測手段,能夠在系統發生異常時提供給用戶有用的異常信息,譬如異常的類型、發生異常時系統的狀態等,方便用戶定位分析問題。編程
Huawei LiteOS的異常接管,在系統發生異常時的處理動做是顯示異常發生時正在運行的任務信息(包括任務名、任務號、堆棧大小等),以及cpu現場等信息。函數
gcc默認將R11做爲存儲變量的通用寄存器使用,於是默認狀況下沒法使用FP的棧回溯功能。爲支持調用棧解析功能,須要在編譯參數中添加-fno-omit-frame-pointer選項,提示編譯器將R11做爲FP使用操作系統
FP寄存器指向當前執行函數的棧回溯結構。返回的FP值是指向由調用了這個當前函數的函數(父函數)創建的棧回溯結構的指針。而這個結構中的返回FP值是指向調用了父函數的函數的棧回溯結構的指針,以此類推。指針
當運行發生異常時,系統打印FP寄存器內容,用戶能夠據此追溯函數間的調用關
系,幫助定位異常的緣由。code
堆棧分析原理如圖1所示。blog
圖中不一樣顏色的寄存器表示不一樣的函數,經過FP寄存器,棧回溯到了異常函數的父函數,從而使調用關係更清楚,方便用戶定位問題。開發
在上圖1,能夠看到函數調用過程當中,棧幀寄存器的保存;所以能夠按照規律對棧進行解析就能夠推出函數調用執行關係,具體步驟以下:編譯器
異常接管爲用戶提供如下幾種異常類型:it
異常名稱 | 描述 | 值 |
---|---|---|
OS_EXCEPT_UNDEF_INSTR | 未定義的指令異常 | 1 |
OS_EXCEPT_SWI | 軟中斷異常 | 2 |
OS_EXCEPT_PREFETCH_ABORT | 預指取指令異常 | 3 |
OS_EXCEPT_DATA_ABORT | 數據停止異常 | 4 |
OS_EXCEPT_FIQ | FIQ異常 | 5 |
異常接管通常的定位步驟以下:
具體的定位方法會在編程實例中舉例說明。
使用panic 命令手動觸發了一個軟中斷異常,異常函數爲LOS_Panic,下面兩個代碼test_panic 爲觸發異常命令函數,另外一個爲異常調用棧打印信息.
uwExcType 2爲軟中斷異常。
定位步驟以下:
UINT32 test_panic(UINT32 argc, CHAR **args) { LOS_Panic("*****Trigger an exception\n"); return; }
Huawei LiteOS# panic *****Trigger an exception uwExcType = 2 puwExcBuffAddr pc = 0x80121234 puwExcBuffAddr lr = 0x80121234 puwExcBuffAddr sp = 0x80e63400 puwExcBuffAddr fp = 0x80e6340c *******backtrace begin******* traceback 0 -- lr = 0x80138d04 traceback 0 -- fp = 0x80e635d4 traceback 1 -- lr = 0x80138d88 traceback 1 -- fp = 0x80e635e4 traceback 2 -- lr = 0x801247d4 traceback 2 -- fp = 0x80e635f4 traceback 3 -- lr = 0x801217c4 traceback 3 -- fp = 0x11111111 R0 = 0x1c R1 = 0x800dba3a R2 = 0x1b R3 = 0xfe R4 = 0x80e634a0 R5 = 0x0 R6 = 0x800cc7f8 R7 = 0x7070707 R8 = 0x8080808 R9 = 0x9090909 R10 = 0x10101010 R11 = 0x80e6340c R12 = 0x1b SP = 0x80e63400 LR = 0x80121234 PC = 0x80121234 CPSR = 0x60000013 g_pRunningTask->pcTaskName = shellTask g_pRunningTask->uwTaskPID = 6 g_pRunningTask->uwStackSize = 12288