段错误的形成原因

段错误的形成原因

形成原因:

segfault实际上是“segmentation fault”的缩写形式,我们可以翻译为“段错误”。segfault是这样形成的:进程空间中的每个段通过硬件MMU映射到真正的物理空间;在这个映射过程中,我们还可以给不同的段设置不同的访问权限,比如代码段就是只能读不能写;进程在执行过程中,如果违反了这些权限,CPU会直接产生一个硬件异常;硬件异常会被操作系统内核处理,一般内核会向对应的进程发送一条信号;如果没有实现自己特殊的信号处理函数,默认情况下,这个进程会直接非正常退出;如果操作系统打开了core dump功能,在进程退出的时候操作系统会把它当时的内存状态、寄存器状态以及各种相关信息保存到一个文件中,供用户以后调试使用 [1]

段错误segmentation fault,信号SIGSEGV,是由于访问内存管理单元MMU异常所致,通常由于无效内存引用,如指针引用了一个不属于当前进程地址空间中的地址,操作系统便会进行干涉引发SIGSEGV信号产生段错误。[2]

产生段错误的几种方式:

❏ 空指针

解引用空指针是不安全的。这块地址空间一般是受保护的,对空指针解引用在大部分平台上会产生segfault。

❏ 野指针

野指针指的是未初始化的指针。它的值取决于它这个位置以前遗留下来的是什么值。所以它可能指向任意一个地方。对它解引用,可能会造成segfault,也可能不会,纯粹凭运气。但无论如何,这个行为都不会是你预期内的行为,是一定会产生bug的。

❏悬空指针

悬空指针指的是内存空间在被释放了之后,继续使用。它跟野指针类似,同样会读写已经不属于这个指针的内容。

❏ 使用未初始化内存

不只是指针类型,任何一种类型不初始化就直接使用都是危险的,造成的后果我们完全无法预测。

❏ 非法释放

内存分配和释放要配对。如果对同一个指针释放两次,会制造出内存错误。如果指针并不是内存分配器返回的值,对其执行释放操作,也是危险的。

❏ 缓冲区溢出

指针访问越界了,结果也是类似于野指针,会读取或者修改临近内存空间的值,造成危险。

❏ 执行非法函数指针

如果一个函数指针不是准确地指向一个函数地址,那么调用这个函数指针会导致一段随机数据被当成指令来执行,是非常危险的。

❏ 数据竞争

在有并发的场景下,针对同一块内存同时读写,且没有同步措施。

参考文献:
[1] 范长春.《深入浅出Rust》[M].机械工业出版社.2018

posted @ 2024-04-12 15:35  HL棣  阅读(47)  评论(0编辑  收藏  举报