2014-01-22 20 views
3

背景:我們看到一個非常間歇的崩潰的函數foo(int *p)。崩潰發生在取消引用p時,其值在這些情況下結果爲0xffffffff。核心轉儲的分析表明,foo()從下面的彙編代碼段稱爲:MIPS:合法將兩個連續的「加載字」指令放入同一個寄存器?

bne ... somewhere else 
lw $a0,44(sp) 
lw $a0,40(sp) 
jal foo() 
lui s1, 0x1000 

在覈心轉儲檢查內存表明44(sp)0xffffffff,而40(sp)是我們打算取消引用正確的值。但是,在foo()的崩潰時間a0的值是0xffffffff。 (需要注意的是,在這種情況下,foo()只是訪問一個成員;所以它實際上是foo()中的第一條指令,該指令已經試圖通過a0訪問,並且崩潰。而且,ra指向上述代碼片段之後的指令, s1目前包含0x10000000,所以我們完全相信,foo(),的確,從上面的代碼中調用)

我們目前唯一的理論是,兩個連續的lw s轉換a0是一個危險 - 無論是記錄一個,在這種情況下,這看起來像一個編譯器錯誤;或無證件。

那麼:是上述程序集合法嗎?如果是的話,還有什麼其他想法可以在這裏發生?

謝謝!

UPDATE:嗯,原來這一切都是白費力氣:由同事信息轉儲的重複分析翻起來,我已經錯過了,那裏有一個直接跳轉到jal foo()代碼路徑指令後,立即將a0設置爲44(sp)。換句話說,代碼中有一條路徑與我們看到的不涉及危險或「跳過指令」或任何其他內容的結果一致......我想我已經檢查了這一點,但是我想我或者沒有做出任何決定, T,或者錯過了... :(

無論如何,我已經接受markgz的答案,因爲它回答了關於這些指令(顯然他們是)合法我原來的問題。

回答

1

快速搜索對於MIPS32R2 ISA MIPS文檔後LW說明書上沒有顯示LW任何限制。

可能是在一個錯誤在您的CPU中執行MIPS。需要注意的事項包括:

  • 什麼地址是44(sp),40(sp) - 它們在頁面邊界還是256MByte邊界或其他有趣的地址?
  • 任何一個負載都會觸發頁面錯誤?
  • 修補二進制文件以在負載之間插入NOPSSNOPSYNC指令會使問題消失嗎?
+0

謝謝!這些地址不在任何特殊邊界(0x17409e8和0x17409ec),也不應該觸發頁面錯誤(它們都在堆棧上)。我們還沒有嘗試修補二進制文件,我們的下一步將是/試圖重現與最小的測試案例... –

+0

有趣的。這些信息使得硬件錯誤對我來說似乎不太可能。 – markgz

+0

重新分析表明問題的整個前提是錯誤的......請參閱原始問題中的UPDATE以瞭解詳細信息。再次感謝你的幫助! –

相關問題