《c专家编程》笔记--bus error(总线错误)
2014-03-20 13:52
260 查看
在《C专家编程》中提到了总线错误bus error(core dumped)。
总线错误几乎都是由于未对齐的读或写引起的。
它之所以称为总线错误,是因为出现未对齐的内存访问请求时,被堵塞的组件就是地址总线。对齐的意思就是数据项只能存储在地址是数据项大小的整倍数的内存位置上。
现代的计算机架构中,尤其是RISC架构,都需要字对齐,因为与任意的对齐有关的额外逻辑都会使内存系统更大且更慢。
通过迫使每个内存访问局限在一个cache行或者一个单独的页面内,可以极大地简化(并加速)如cache控制器和内存管理单元这样的硬件。
页和cache的大小都是经过精心设计的,这样只要遵守对齐规则就可以保证一个原子数据项不会跨过一个页或cache块的边界。
书中还给出了总线错误的例子:
[cpp] view
plaincopy
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程序,将程序修改为如下:
[cpp] view
plaincopy
#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
原文链接/article/1522269.html
总线错误几乎都是由于未对齐的读或写引起的。
它之所以称为总线错误,是因为出现未对齐的内存访问请求时,被堵塞的组件就是地址总线。对齐的意思就是数据项只能存储在地址是数据项大小的整倍数的内存位置上。
现代的计算机架构中,尤其是RISC架构,都需要字对齐,因为与任意的对齐有关的额外逻辑都会使内存系统更大且更慢。
通过迫使每个内存访问局限在一个cache行或者一个单独的页面内,可以极大地简化(并加速)如cache控制器和内存管理单元这样的硬件。
页和cache的大小都是经过精心设计的,这样只要遵守对齐规则就可以保证一个原子数据项不会跨过一个页或cache块的边界。
书中还给出了总线错误的例子:
[cpp] view
plaincopy
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程序,将程序修改为如下:
[cpp] view
plaincopy
#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
原文链接/article/1522269.html
相关文章推荐
- ASP.NET中常用方法
- 修改默认Netbeans JDK路径及JDK简介
- Spring + JDBC联合开发
- 要点Java13 继承Inheritance
- 字符串逆转(递归和非递归java)
- 第一个Struts2程序
- Java的23种设计模式
- .net c#获取自定义Attribute
- 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
- c++ 编译时报错 "Array initializer must be an initializer list or string literal"
- C++的基础,平时随便写的一些代码
- eclipse快捷键
- C#中的定制特性(Attributes)
- 「我们就差一个写代码的了」为什么会招黑?
- python 从2.x-3.x一些变化
- 关于MultiByteToWideChar与WideCharToMultiByte代码测试(宽字符与多字节字符的转换)以及字符串的转换代码测试
- Python 之time模块
- 免费代码托管服务体验小结
- C++中的IO库(四)
- Spring框架的IoC和AOP