linux软件总线错误,什么内存加载导致x86-64 linux上的总线错误?

我以前认为x86-64支持未对齐的内存访问和无效的内存访问总是导致分段错误(可能除了像movdqa或movaps之类的SIMD指令).不过最近我用普通的mov指令观察到了总线错误.这是一个复制者:

void test(void *a)

{

asm("mov %0, %%rbp\n\t"

"mov 0(%%rbp), %%rdx\n\t"

: : "r"(a) : "rbp", "rdx");

}

int main()

{

test((void *)0x706a2e3630332d69);

return 0;

}

(必须用帧指针省略编译,例如gcc -O test.c&& ./a.out).

mov 0(%rbp),%rdx指令和地址0x706a2e3630332d69是从有缺陷的程序的coredump复制的.将其更改为0会导致段错误,但只是对齐到0x706a2e3630332d60仍然是总线错误(我的猜测是它与地址空间在x86-64上的48位相关).

问题是:哪些地址导致总线错误(SIGBUS)?它是由体系结构确定还是由OS内核配置(即在页表,控制寄存器或类似的东西中)?

解决方法:

SIGBUS处于悲伤状态.不同的操作系统之间没有达成共识,它的意义和生成时间在操作系统,CPU架构,配置和月相之间变化很大.除非您使用非常具体的配置,否则您应该“将其视为SIGSEGV,但不同”.

我怀疑它本来应该意味着“你尝试过无论内核做什么都无法成功的内存访问”,所以换句话说,你在地址中的确切位模式永远不会是有效的内存访问.最常见的是,这意味着严格对齐架构上的未对齐访问.然后,一些系统开始使用它来访问不存在的虚拟地址空间(例如,在您的示例中,您所拥有的地址不可存在).然后偶然的一些系统使得它也意味着userland试图触摸内核内存(因为从技术上讲,它至少是从用户区的角度来看不存在的虚拟地址空间).然后它变得随机.

除此之外,我见过SIGBUS:

>从mmap:ed硬件访问不存在的物理地址.

> exec of non-exec mapping

>访问完全有效的映射,但此时过度使用的内存不能出错(我在这里看过SIGSEGV,SIGKILL和SIGBUS,至少有一个操作系统根据你所使用的架构有不同的做法).

>内存管理死锁(和其他“一些可怕的错误,但我们不知道什么”内存管理错误).

>堆栈红区访问

>硬件错误(ECC内存,pci总线奇偶校验错误等)

>访问mmap:ed文件,其中文件内容不存在(超过文件末尾或空洞).

>访问mmap:ed文件,其中文件内容应该存在,但不存在(I / O错误).

>无法执行换出和交换的正常内存访问(I / O错误).

标签:c-3,linux,assembly,x86

来源: https://codeday.me/bug/20190713/1453501.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值