vxworks任務異常處理

做VxWorks的時候經常會碰到任務異常的問題,有時很難定位,下面是根據網上的一些資料整理出來的。不正確的地方請指出,謝謝!

1、任務異常的一般表現

    異常是分類型的,而且不同的CPU系統上是有區別的。常見的有PPC,DSI,還有ISI和Program等,具體看CPU的手冊

    指令異常:系統打印program異常或instruction access異常
     訪問非法地址異常,串口打印data access異常,如:
             data access
             Exception current instruction address:0x00187d4c
             Machine Status Register:0x00009030
             Data Access Register: 0x8003435c
             Condition Register:0x48000080
             Data storage interrupt Register:0x0000000b
             Task:0xc844f0 "XXX"
     中斷處理中產生的異常

2、可能的原因
     1、堆棧寫越界,主要是數組寫越界,導致前面聲明的變量(因爲堆棧是從下往上增長的)或者函數的參數或者函數返回的地址被改寫爲無效值。
     2、堆棧溢出,堆棧聲明過小,而函數又聲明瞭大數組,超出堆棧的容量
     3、內存改寫,這是最通常出現的原因。包括,指針沒有初始化,導致訪問隨機地址;訪問空指針;內存操作範圍越界,例如在使用
           memcpy/memset等函數           使用的長度超過所分配,導致改寫了其他的指針。因此在定位異常問題過程中,可以通過內存
           管理先查看一下先前是否有內存寫越界的記錄,但是內存寫越界只有在釋放該內存區時才能檢查到,如果該內存
          沒有被釋放,則即使寫越界也是不知道的


     4、系統調用不當。(在中斷中可以調用msgQSend的,而其它一些不允許的調用本身也是直接返回失敗,一般不會直接導致
            異常;之所以異常往往是調            用了semTake返回就以爲成功了,直接訪問被信號量保護的資源)

     5、增量編譯引起的問題,Tornado增量編譯有時會出現問題,導致古怪的異常,重新全量編譯後,肯呢個會解決問題
     6、多任務搶佔引起的問題,當多個任務共同訪問一個或者多個變量時,如果互斥不當,可能會產生同步或互斥的問題,
           比較典型的是:任務A和B都使用一個變量指針P;而A和B的優先級不同(即存在任務搶佔),則他們在釋放或者修改這個變量
           指針的時候,可能會出現隨機的異常訪問問題。

3、處理策略
     1、如果有理由懷疑是增量編譯引起的,則首先嚐試全量編譯一下工程
     2、分析異常出現時的調用棧信息:以data access異常爲例;
           如果在系統出現異常時接了串口,則可以直接看到類似以下列信息;如果出現異常時沒有接串口,則定位問題時可首先接
          上串口或者Tornado,然後使用“ti”命令也可以看到如下的異常信息:
          data access
          Exception current instruction address:0x00187d4c--通過這個地址通常
          可以通過符號表知道異常出現時系統正在運行哪個函數,  l 0x00187d4c和lkaddr 0x00187d4c

          Machine Status Register:0x00009030
          Data Access Register: 0x8003435c
          Condition Register:0x48000080
          Data storage interrupt Register:0x0000000b
          Task:0xc844f0 "XXX"                                         --通過這個參數,可以知道是哪個任務出現的異常

        具體定位提示:
        1、可以使用“checkStack”命令看是否產生了堆棧溢出:如果是XXX任務的隊戰溢出,則在checkStack的打印中,
              XXX的堆棧狀態會顯示成“overflow”
        2、可以使用tt命令查看任務調用棧,通過分析調用棧的每一層函數,嘗試找原因,參照上面的可能的原因部分
        3、分析函數調用序列中所訪問的全局變量(尤其是指針和數組),看是否存在任務搶佔而導致全局指針被修改或者訪問無效指針的問題。


    3、重現問題,如果通過上述步驟無法直接找到原因,那麼恭喜你,你已經遇到恐怖的隨機內存改寫問題,這類問題通常難
          以重現,而且通過分析單個任務的運行軌跡很難找到原因,這類問題很可能的情況是:雖然任務A在運行函數FuncA時產生的
          異常,但真正的內存改寫代碼很可能是在任務X或函數FuncX中,解決這類問題的關鍵是如何重現問題,一旦問題可以比較容易
         的重現,那麼可以說問題已經解決了一半。

重現問題的辦法:
     1、回憶先前的操作步驟,一步一步地重做一遍,看問題是否可以重現
     2、如果是任務A產生的異常,則人工製造一些條件,使任務A不斷的運行,以重現問題,通過腳本或者打樁,不斷地發一些消息觸發
           任務A的運行,這是最常用的方法,如果A是週期運行,則縮短週期,加快運行

     3、逆向分析,通過分析代碼,可能懷疑一些代碼有問題,這時候,可以針對性的創造各種人爲條件來重現問題,例如懷疑某個定時
           器可能存在重複進入和重複刪除,則可以人爲修改代碼流程,使之進入定時器重複進入/重複刪除流程,或者用腳本不斷地創建和
           刪除定時器,以加快問題出現的頻率

     4、手動調整任務優先級,分析任務搶佔相關的問題,在基本確定任務異常可能和任務搶佔相關的情況下,可以嘗試以各種組合,將幾個
           相關的任務優先級調整成相同的優先級(這樣,這幾個任務就不會再產生任務搶佔了)。在此基礎上嘗試重現問題;如果在優先級相
           同的情況下異常不再出現,則說明這幾個任務之間所共享的變量存在互斥問題;否則說明該問題很可能和互斥無關,或者根據需要把
           某些優先級調高,某些調低,以重現任務搶佔的問題。


4、解決問題

    1、如果找到料問題所在,則直接修改問題
    2、如果通過多日的重現和定位,都無法找到真正的原因,那麼沒有辦法的辦法就是:直接修改代碼,把懷疑有問題的地方全部改掉,
          然後再測試看問題是否解決。

發佈了30 篇原創文章 · 獲贊 12 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章