![]() |
1
15
如果打开未对齐的访问陷阱,可以从未对齐的访问获取SIGBUS,但在x86上通常是关闭的。如果出现某种错误,您也可以通过访问内存映射设备来获取。 最好的方法是使用调试器来识别出错指令(SIGBUS是同步的),并尝试查看它试图执行的操作。 |
![]() |
2
23
|
![]() |
3
10
x86(包括x86_64)Linux上的SIGBUS是一种罕见的野兽。它可能出现在试图访问超过
但由于硬件故障,要获得SIGBUS并不容易。也就是说,来自任何指令的未对齐访问(无论是否为SIMD)通常会导致SIGSEGV。堆栈溢出导致SIGSEGV。即使对非规范格式地址的访问也会导致SIGSEGV。所有这些都是由于#GP被提升,它几乎总是映射到SIGSEGV。 现在,以下是一些由于CPU异常而获取SIGBUS的方法:
int main() { __asm__("mov rbp,0x400000000000000\n" "mov rax,[rbp]\n" "ud2\n"); } |
![]() |
4
6
哦,是的,还有一种更奇怪的方法可以找到SIGBUS。 如果内核由于内存压力(必须禁用OOM killer)或IO请求失败而无法在代码页中分页,则SIGBUS。 |
![]() |
5
4
一种常见的情况是,您使用ftruncate惰性地增长文件,将其映射到内存中,开始写入数据,然后文件系统中的空间用完。映射文件的物理空间是在页面错误上分配的,若并没有剩余空间,则进程将接收SIGBUS。 如果您需要应用程序正确地从该错误中恢复,那么在使用fallocate进行mmap之前显式地保留空间是有意义的。在errno after fallocate调用中处理ENOSPC比处理信号简单得多,特别是在多线程应用程序中。 |
![]() |
7
0
在这种情况下,您需要通过
|
![]() |
8
-1
x86 Linux上发生总线错误的一个常见原因是,试图取消引用并非真正的指针或野生指针的内容。例如,未能初始化指针,或为指针指定任意整数,然后尝试取消引用它,通常会产生分段错误或总线错误。 对齐确实适用于x86。即使x86上的内存是字节可寻址的(因此您可以有一个指向任何地址的char指针),但如果您有一个指向4字节整数的指针,则该指针必须对齐。 您应该在gdb中运行程序,并确定哪个指针访问正在生成总线错误以诊断问题。 |
![]() |
9
-1
这有点离经叛道,但您可以从未对齐的SSE2(m128)负载获得SIGBUS。 |
![]() |
MaPo · Linux,设置锁定ICMP_过滤器选项 3 月前 |
![]() |
user2138149 · 双栈网络服务器无法按预期处理ipv4请求 4 月前 |
![]() |
Marco · PyCharm Linux系统文件上os.stat异常 5 月前 |