每天早晨叫醒你的不是闹钟,而是梦想

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  62 Posts :: 0 Stories :: 5 Comments :: 0 Trackbacks

常用链接

留言簿(1)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

我们经常会发现有两种内存转储(core dump)  
  一种是段故障(segment fault)通常是在一个非法的地址上进行取值赋值操作造成。  
  一种是总线错误(bus error)通常是指针强制转换,导致CPU读取数据违反了一定的总线规则。

首先,core就是内存的意思,在半导体应用之前,内存是由铁氧化物圆环制造的(core),但一直沿用至今。

而这两种错误,都是有硬件告知操作系统一个有问题的内存引用。操作系统通过信号,再将错误信息告知进程。缺省情况下,进程收到“总线错误”或“段错误”信号后,将信息转储并终止。当然也可以为这些信号设置一个信号处理程序(signal handler)。

总线错误(bus error),几乎都是有内存未对齐读引起的。内存对齐,就是内存变量的地址只能是其大小的整数倍,这样存储的目的就是为了方便并快速存取内存。一般情况下,编译器都会做好内存对齐工作,为什么又会引发段故障呢?很多情况就是由指针和强制类型转换引起的,如:

union{

    char a[10];

    int i;

}u;

int *p = (int *)&(u.a[1]);

*p = 17;

当然,还有一些其它原因会引起“总线错误”,如奇偶校验码错误,所引用的内存块不存在。但是现在,内存都有硬件电路检测和修正,一般不会再传到软件层了;除了驱动程序,一般也不会引用不存在的内存块。

段错误,一般是由于引用不位于自己的地址空间的地址引起的。最常见的就是通过一个未初始化,或者有非法值的指针引起的,如:int *p = 0; *p = 7; 而导致指针的非法值可能是由于不同的编程错误引起的,比起“总线错误”更加间接。

段错误一般是由硬件段表转换机构的错误引发,如Sun硬件中的内存管理单元(MMU)。

还有一个微妙之处是,如果未初始化的指针恰好具有未对齐的值,它将产生总线错误,而不是段错误。

posted on 2011-04-25 14:00 沛沛 阅读(5907) 评论(0)  编辑 收藏 引用 所属分类: 体系结构

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理