有時,在各種Unix體系結構中,在程序運行時重新編譯程序會導致程序崩潰並顯示「總線錯誤」。任何人都可以解釋發生這種情況的條件嗎首先,如何更新磁盤上的二進制文件對內存中的代碼執行任何操作?我能想象的唯一情況是有些系統將代碼映射到內存中,當編譯器重寫磁盤映像時,這會導致mmap無效。這種方法的好處是什麼?通過更改可執行文件來使運行代碼崩潰看起來非常不理想。重新編譯二進制文件時發生總線錯誤
回答
在本地文件系統上,所有主流的類Unix系統都支持通過刪除文件來解決此問題。舊的vnode保持打開狀態,即使在目錄條目消失之後重新用於新映像,舊文件仍然存在,未更改,現在未命名,直到最後一次引用它(在此情況下,內核)消失爲止。
但是,如果你剛開始重寫它,那麼是的,它是mmap(3)'ed。當塊被重寫的兩種情況之一可以取決於哪個MMAP發生(3)選項的動態鏈接程序使用:
- 內核將無效相應的頁面,或
- 磁盤映像將改變,但現有的存儲器頁不會
無論哪種方式,正在運行的程序可能有麻煩。在第一種情況下,它基本上保證爆炸,而在第二種情況下,除非所有的頁面都被引用,分頁並且從不丟棄,否則它將被破壞。
有兩個mmap標誌旨在解決這個問題。一個是MAP_DENYWRITE(防止寫入),另一個是MAP_COPY,它保留了原始版本的純粹版本,並防止作者更改映射圖像。
但是出於安全原因,DENYWRITE已被禁用,並且在任何主要的類Unix系統中都沒有執行COPY。
這是一個有點複雜的情況,可能會發生在你的情況。這個錯誤的原因通常是內存對齊問題。總線錯誤在基於FreeBSD的系統中更常見。考慮一個場景,你有一個類似的結構,
struct MyStruct { char ch [29]; // 29字節 int32 i; // 4字節 }
所以這個結構的總大小應該是33個字節。現在考慮一個你有32字節緩存行的系統。此結構不能加載到單個緩存行中。現在考慮以下語句
Struct MyStruct abc; char * cptr = &abc; //結構起始處的char點指向 int32 * iptr =(cptr + 1)// iptr指向結構的第2個字節。
現在總體結構大小爲33字節,您的int指針指向第2個字節,因此您可以從int指針讀取32字節數據(因爲分配的內存總大小爲33字節)。但是當你嘗試讀取它時,如果結構被分配在緩存線的邊界,那麼操作系統不可能在一次調用中讀取32個字節。由於當前緩存行僅包含31個字節的數據,其餘1個字節位於下一個緩存行。這將導致一個無效的地址,並會給「布斯錯誤」。大多數操作系統通過在內部生成兩個內存讀取調用來處理這種情況,但一些Unix系統不處理這種情況。爲避免這種情況,建議您注意內存對齊。大多數情況下,當您嘗試將結構轉換爲另一種數據類型並嘗試讀取該結構的內存時,會發生這種情況。
該情況有點複雜,所以我不確定我是否可以用更簡單的方式解釋它。我希望你瞭解這種情況。
感謝您的回答,但我不明白這與更改磁盤上的映像有何關係。代碼運行良好,除非我在可執行文件運行時重新編譯它。 – Lutorm 2011-03-10 18:55:29
- 1. 編譯二進制文件
- 2. C++ - 讀取二進制文件錯誤或編譯器錯誤?
- 3. C++:二進制搜索編譯錯誤
- 4. makefile - 在重新編譯其他c文件時總是重新編譯version.c
- 5. pip編譯vs二進制文件
- 6. 使用VexCL「編譯二進制文件」
- 7. 反編譯非PC二進制文件
- 8. 如何編譯二進制文件?
- 9. 是否可以編輯和重新編譯iOS二進制文件?
- 10. 在線C++編譯器:爲我輸出二進制文件?
- 11. luabind編譯錯誤發生
- 12. 當我編譯AlamofireImage3.1時發生錯誤
- 13. 編譯爲CSS時發生sass錯誤
- 14. 嘗試編譯時發生錯誤Chess.app
- 15. 編譯cocos2dx時發生錯誤3.13.1
- 16. 如何編譯時發生錯誤
- 17. Prestashop:SMARTY - 當文件被修改時強制編譯/重新編譯
- 18. GCC編譯的二進制文件給予 「不能執行二進制文件」
- 19. g ++編譯的二進制文件給「不能執行二進制文件」
- 20. 編譯在線編譯時間錯誤?
- 21. 開始從kaa下載二進制文件時發現錯誤
- 22. 當從二進制文件讀取時發生java浮點錯誤
- 23. gdb:使用-g編譯的二進制文件與使用-g編譯的二進制編譯的代碼
- 24. 錯誤重新編譯
- 25. 的Xcode總線錯誤當編譯
- 26. 在SBT本地發佈預編譯X二進制文件
- 27. 在VS2005中修補一個二進制文件而不用重新編譯
- 28. 編譯器錯誤與二進制樹複製構造函數
- 29. 將函數傳遞給新線程時發生編譯器錯誤?
- 30. 在彙編內聯編程中發生總線錯誤x86
因此編譯器一般不會刪除和重寫,而是覆蓋輸出文件? – Lutorm 2011-03-10 18:56:43