这不是在 C 中的东西,它是在类 Unix 操作系统中的东西。任何不是内存安全的语言(可以尝试访问未映射的页面)都可以编译为段错误的可执行文件。包括手写汇编或 Fortran。但是,是的,C 和 C++ 是使用最广泛的两种非内存安全语言。
是的,这个名字很古老; Unix 旧并且没有需要将SIGSEGV重命名为内核传递的信号,当用户空间通过访问它没有访问的内存导致CPU故障时不是地图。这样做会破坏大量使用该常量的代码,并且仅将 strerror / perror 的英文文本字符串更改为“无效页面错误”也不会特别有帮助,尽管可能因为那些我认为消息已融入 libc。但是,不同的 libc 版本在转换前后几年会有不同的信息,不值得这么麻烦。
在使用分页的系统中,对硬件页表中“不存在”的页面的任何访问,或仅在您尝试写入时才可读或其他任何情况都会导致 CPU 发生异常。内核的页面错误异常处理程序检查页面是否应该可访问,如果是,则从磁盘将其分页,执行写时复制或其他操作。 (分别是主要或次要页面错误)。如果不是,则页面错误是“无效的”,内核会向进程传递一个 SIGSEGV 信号。
对于一般的算术异常,同样古老的是SIGFPE(浮点异常),在大多数机器上默认情况下唯一可以实际出错的是整数除法。 (默认的 FP 环境屏蔽了所有 FP 异常,因此它们只是设置粘性标志而不是在机器代码中引发异常。)POSIX standard requires 如果由于算术异常而要传递信号,则它必须是 SIGFPE。
同样,SIGSEGV 已经被 POSIX 和其他 Unix 标准标准化,所以在早期的 Unix 时代,任何人都可以合理地改变了早就过去了。
(某些系统还可以为其他类型的错误地址错误提供SIGBUS,例如,SPARC 上的 Solaris 为未对齐的访问提供SIGBUS。)
另请注意,某些其他类型的权限错误会重载到 SIGSEGV 上。例如,尝试在 Linux 下执行 x86 lgdt 之类的特权指令会导致 SIGSEGV。 (在这种情况下,用户空间实际上会尝试接管仍然用于定义 CPU 运行模式的分段机制,例如长模式下的 16 位、32 位和 64 位代码段。)未对齐也是如此SSE SIMD 指令。所以它不是严格来说是无效页面错误。
命名历史?
可执行文件也有像文本和数据这样的“段”,其中 .text 和 .data 部分分别链接。 “堆”过去大多是连续的,在 .data / .bss 之后增长(通过brk 系统调用,在mmap(MAP_ANONYMOUS) 或从 /dev/zero 映射页面之前),所以这可能是“分段错误”即使在操作系统开始使用分页而不是 CPU 分段来保护内存之后,这个术语对设计人员来说似乎也不是什么废话,因为可执行文件的“段”仍然映射到进程内存映像中的连续页面范围。
我不知道有关 Unix 信号命名的历史细节与它在 PDP-8 和 PDP-11 硬件上的开发(有或没有内存保护功能),尽管显然some models of PDP-11 有某种形式的内存保护,并且even virtual memory
TL:DR
There are two hard problems in computer science: Cache invalidation, and naming things 和一个错误。