Bus errors VS Segmentation faults

晁开宇
2023-12-01
/*********************************************************************
* Author          :     lile
* Modified        :     2019年12月28日星期六  10:56:13
* Email           :     roger0212@163.com
* HomePage        :     lile777.blog.csdn.net
* CopyRight       :     该文章版权由lile所有。
*                       保留原文出处链接和本声明的前提下,可在非商业目的下任意传播和复制。
*                       对于商业目的下对本文的任何行为需经作者同意。
*********************************************************************/

Bus errors are rare nowadays on x86 and occur when your processor cannot even attempt the memory access requested, typically:

using a processor instruction with an address that does not satisfy its alignment requirements.

Segmentation faults occur when accessing memory which does not belong to your process, they are very common and are typically the result of:

using a pointer to something that was deallocated.
using an uninitialized hence bogus pointer.
using a null pointer.
overflowing a buffer.

PS: To be more precise this is not manipulating the pointer itself that will cause issues, it’s accessing the memory it points to (dereferencing).

They aren’t rare; I’m just at Exercise 9 from How to Learn C the Hard Way and already encountered one…

Another cause of bus errors (on Linux anyway) is when the operating system can’t back a virtual page with physical memory (e.g. low-memory conditions or out of huge pages when using huge page memory.) Typically mmap (and malloc) just reserve the virtual address space, and the kernel assigns the physical memory on demand (so called soft page faults.) Make a large enough malloc, and then write to enough of it and you’ll get a bus error.



A segfault is accessing memory that you’re not allowed to access. It’s read-only, you don’t have permission, etc…

A bus error is trying to access memory that can’t possibly be there. You’ve used an address that’s meaningless to the system, or the wrong kind of address for that operation.



在《C专家编程》中提到了总线错误bus error(core dumped)。
总线错误几乎都是由于未对齐的读或写引起的。
它之所以称为总线错误,是因为出现未对齐的内存访问请求时,被堵塞的组件就是地址总线。对齐的意思就是数据项只能存储在地址是数据项大小的整倍数的内存位置上。
现代的计算机架构中,尤其是RISC架构,都需要字对齐,因为与任意的对齐有关的额外逻辑都会使内存系统更大且更慢。
通过迫使每个内存访问局限在一个cache行或者一个单独的页面内,可以极大地简化(并加速)如cache控制器和内存管理单元这样的硬件。
页和cache的大小都是经过精心设计的,这样只要遵守对齐规则就可以保证一个原子数据项不会跨过一个页或cache块的边界。
参考: http://blog.csdn.net/todd911/article/details/8813321

#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;
}


总结:

  1. Bus errors —— 当前程序无法获取到所需要的内存》》饿死
  2. Segmentation faults —— 访问的内存不属于当前程序所分配的内存空间》》非法访问他人空间被毙
 类似资料:

相关阅读

相关文章

相关问答