【你问我答】Segmentation Fault如何被检测?

问题描述:

Segmentation Fault 是如何被检测到的?

回答有奖:

选取一位认真回答问题的牛友,赠送200牛币!
▶回答尽量有自己的思考,不要单纯的只是复制粘贴定理定义,或者他人blog哦~

你问我答问题汇总:点击进入
关注你问我答栏目:点击关注

------------
#我也有问题想询问牛友,怎么办?

欢迎私信@筱茜 说明你的问题,将根据问题具体情况排期进入【你问我答】专场~
私信请注明参与【你问我答】专场哦~

你问我答 - 答问题,成大佬,拿牛币!
你问我答是牛客新栏目,每周1期几个问题,
牛友在问题贴下留下自己的知识,经验与见解,
帮助更多牛友了解更多技术相关知识!
#C/C++#
全部评论
segment fault 是段错误,通常在非法内存访问,读写的时候会报这个错误。 一、比较常见的错误情况如下 1:赋值操作(非法地址写) 2:数组越界 (非法地址读 或 写) 相当于执行了putchar(a[3]),a[3]是"\0",在内存中是00,也是个常见的非法内存访问 3:内存(字符串)拷贝 (非法地址读 或 写)   4:非法地址执行(栈溢出,任意地址执行时可能出现这种情况) 这条指令 == call 0xdeadbeef,0xdeadbeef 是个非法地址,所以会报段错误。 还有一些暂时想不起来的,不过原理也是非法内存访问和读写。 二、知道了错误的成因就可以知道怎么检测了。 1:printf 大法 最简单的往往是最常用的,printf一下地址,变量。 2:调试的方法 利用gdb, asan这些工具可以很快定位到segment fault的地址 是一个0地址写的seg fault 3:catchsegv 指令 是一个输出segfault 时寄存器的内容。 暂时想到这么多,写的东西也不是很深,其实段错误是很好检测的,因为一旦发生段错误,os就会请求中断或者发出信号来结束程序。要在编译时候检测,借助gcc+asan这种内存检查工具才可行,即便是asan也可能存在疏漏。windows下也有成熟独立的体系,原理相同就不多说了。
点赞
送花
回复
分享
发布于 2019-10-08 16:09
Segmentation Fault 是如何被检测到的? 首先说一下Segmentation Fault 是什么? A segmentation fault (often shortened to SIGSEGV) is a particular error condition that can occur during the operation of computer software. “当程序试图访问不被允许访问的内存区域(比如,尝试写一块属于操作系统的内存),或以错误的类型访问内存区域(比如,尝试写一块只读内存)。这个描述是准确的。为了加深理解,我们再更加详细的概括一下SIGSEGV。 SIGSEGV是在访问内存时发生的错误,它属于内存管理的范畴 SIGSEGV是一个用户态的概念,是操作系统在用户态程序错误访问内存时所做出的处理。 当用户态程序访问(访问表示读、写或执行)不允许访问的内存时,产生SIGSEGV。 当用户态程序以错误的方式访问允许访问的内存时,产生SIGSEGV。 SIGSEGV在很多时候是由于指针越界引起的,但并不是所有的指针越界都会引发SIGSEGV。一个越界的指针,如果不解引用它,是不会引起SIGSEGV的。而即使解引用了一个越界的指针,也不一定会引起SIGSEGV。这听上去让人发疯,而实际情况确实如此。SIGSEGV涉及到操作系统、C库、编译器、链接器各方面的内容, SIGSEGV是由谁产生,发送给谁? 由操作系统内核产生,发送给用户进程 操作系统检查Segmentation Fault流程 在 shell 中启动一个进程,进程访问一个虚拟地址,MMU 将这个虚拟地址转化成物理地址的过程中,发现转化不了,于是产生一个中断。中断的过程即由 IDTR 找到 IDT,执行中断处理函数,最后调到 do_page_fault 函数。do_page_fault 在当前进程的 vma 中找这个地址(task_struct 维护一颗 vm_area 的红黑树),如果访问的虚拟地址没有落到任何一个 vma 中,那么 do_page_fault 会给进程发送一个 SIGSEGV 信号。SIGSEGV 信号的默认 handler 是 Core,终止这个进程,产生一个 core dump。终止的时候,这个进程把它的 status 给父进程 shell(segfault 的 status 是 139),shell 收到了之后,知道子进程是因 segfault 退出,就在屏幕上打出来一行字 Segmentation fault (core dumped)。
点赞
送花
回复
分享
发布于 2019-10-08 16:08
网易互娱
校招火热招聘中
官网直投
A segmentation fault (often shortened to SIGSEGV) is a particular error condition that can occur during the operation of computer software. A segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (for example, attempting to write to a read-only location, or to overwrite part of the operating system). Segmentation is one approach to memory management and protection in the operating system. It has been superseded by paging for most purposes, but much of the terminology of segmentation is still used, "segmentation fault" being an example. Some operating systems still have segmentation at some logical level although paging is used as the main memory management policy. On Unix-like operating systems, a process that accesses an invalid memory address receives the SIGSEGV signal. On Microsoft Windows, a process that accesses invalid memory receives the STATUS_ACCESS_VIOLATION exception. 就是:所谓的段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。一旦一个程序发生了越界访问,cpu就会产生相应的异常保护,于是segmentation fault就出现了。 即“当程序试图访问不被允许访问的内存区域(比如,尝试写一块属于操作系统的内存),或以错误的类型访问内存区域(比如,尝试写一块只读内存)。这个描述是准确的。为了加深理解,我们再更加详细的概括一下SIGSEGV。段错误应该就是访问了不可访问的内存,这个内存区要么是不存在的,要么是受到系统保护的。
点赞
送花
回复
分享
发布于 2019-10-08 18:03
一般来说是段错误 一般都是非法内存操作,例如数组越界,例如申请a[5],却访问到a[5]或者a[6],这也会有很多情况,可能是循环操作时循环变量控制有问题,可能是字符串拷贝时长度发生溢出 指针指向了非法内存,例如申明一个指针,但是没有对指针进行初始化,直接就引用,或者引用里面的元素或者函数,或者没有分配内存就进行释放等,另外,申请内存还要检查是否申请成功,如果没有申请成功也会出现这种情况 单步调试或者加打印信息,细心一点总可以找到错误的,注意编译成调试版本 如果是linux,可以产生core文件,从core文件查看出错的地方
点赞
送花
回复
分享
发布于 2019-10-11 20:46

相关推荐

点赞 评论 收藏
转发
1 2 评论
分享
牛客网
牛客企业服务