bus error(總線錯誤)


轉自  http://blog.csdn.net/todd911/article/details/8813321

在《C專家編程》中提到了總線錯誤bus error(core dumped)。

總線錯誤幾乎都是由於未對齊的讀或寫引起的。它之所以稱為總線錯誤,是因為出現未對齊的內存訪問請求時,被堵塞的組件就是地址總線。對齊的意思就是數據項只能存儲在地址是數據項大小的整倍數的內存位置上。現代的計算機架構中,尤其是RISC架構,都需要字對齊,因為與任意的對齊有關的額外邏輯都會使內存系統更大且更慢。通過迫使每個內存訪問局限在一個cache行或者一個單獨的頁面內,可以極大地簡化(並加速)如cache控制器和內存管理單元這樣的硬件。頁和cache的大小都是經過精心設計的,這樣只要遵守對齊規則就可以保證一個原子數據項不會跨過一個頁或cache塊的邊界。 

書中還給出了總線錯誤的例子: 

union   
{  
    char a[10];  
    int i;  
}u;  
  
int *p =(int*)&(u.a[1]);    
*p =17;            /*p中未對齊的地址將會引起總線錯誤,因為數組和int的聯合確保了a是按照int的4字節來對齊的,所以“a+1”肯定不是int來對齊的。*/  

但是在實際的運行中並沒有出現該錯誤,我的環境是CentOS release 6.2,2.6.32-279.14.1.el6.i686,gcc 4.4.6

后來在網上參考了一個sample程序,將程序修改為如下: 

#include <stdlib.h>    
int main(int argc, char **argv) {    
#if defined(__GNUC__)  
# if defined(__i386__)  
        /* Enable Alignment Checking on x86 */  
        __asm__("pushf\norl $0x40000,(%esp)\npopf");  
# elif defined(__x86_64__)  
        /* Enable Alignment Checking on x86_64 */  
        __asm__("pushf\norl $0x40000,(%rsp)\npopf");  
# endif  
#endif    
union{  
         char a[10];  
         int i;  
}u;    
int *p =(int*)&(u.a[1]);  
*p =17;  
}   

運行結果如下:
Bus error (core dumped) 

原因是:

x86體系結構會把地址對齊之后,訪問兩次,然后把第一次的尾巴和第二次的頭拼起來。

如果不是x86,那種體系結構下的機器不肯自動干這活,就會產生core。

如果在代碼中將對齊檢查功能打開,運行后能顯示bus error


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM