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