存储器区段错误(英语:Segmentation fault,经常被缩写为segfault),又译为存储器段错误,也称访问权限冲突(access violation),是一种程序错误。
简介存储器区块错误(英语:Segmentation fault,经常被缩写为segfault),又译为存储器段错误,也称访问权限冲突(access violation),是一种程序错误。
它会出现在当程序企图访问CPU无法定址的存储器区块时。当错误发生时,硬件会通知操作系统产生了存储器访问权限冲突的状况。操作系统通常会产生核心转储文件(core dump)以方便程序员进行除错。通常该错误是由于调用一个地址,而该地址为空(NULL)所造成的,例如链表中调用一个未分配地址的空链表单元的元素。数组访问越界也可能产生这个错误。
x86内存分段x86架构中,存储器分段(英语:Memory Segmentation)是在不改变16位段选择符时,使用单个索引寄存器(保存了段内地址偏移值)所能够寻址的的存储器范围部分。也指在英特尔x86指令集体系结构下存储器分段的实现方式。
从8086开始到随后的各款x86架构CPU,无论是实模式还是保护模式,内存寻址时都使用16位段寄存器(segment register)。段寄存器默认使用情况为:
代码段寄存器CS与寄存器IP相配合获得当前线程代码执行到的内存位置;
数据段寄存器DS与各通用寄存器配合访问内存中的数据;
栈段寄存器SS与寄存器(E)SP、(E)BP配合访问线程的调用栈(call stack);
扩展段寄存器ES用于特定字符串指令(如MOVS或CMPS)。
80386引入了2个额外的段寄存器FS与GS,并无特定的硬件用途。
这些段寄存器除了有16位的可见部分,还有不可见的隐藏部分,称为描述符缓存“descriptor cache”或隐藏寄存器“shadow register”。当一个段选择符(segment selector)装入段寄存器的可见部分,处理器同时也把该段描述符的其它数据装入到段寄存器的隐藏部分,这包括段开始的基地址、段长度、访问控制信息等。这些信息缓存到段寄存器中,避免了处理器在转址(translate address)时花费额外的总线周期从段选择符表中读入数据。处理器指令中可以明示使用哪些段寄存器,这将替换掉默认使用的段寄存器。1
核心转储核心文件(core file),也称核心转储(core dump),是操作系统在进程收到某些信号而终止运行时,将此时进程地址空间的内容以及有关进程状态的其他信息写出的一个磁盘文件。这种信息往往用于调试。
程序自身产生的coredump文件一般可以用来分析程序运行到哪里出错了。Linux平台常用的coredump文件分析工具是gdb;Solaris平台用pstack和pflags;Windows平台用userdump和windbg。外部程序触发的dump一般用来分析进程的运行情况,比如分析内存使用/线程状态等。Solaris的常用内存分析工具umem就是需要先通过gcore pid得到coredump的文件然后继续分析内存情况。
本词条内容贡献者为:
武伟 - 高级工程师 - 天津直升机有限责任公司