Linux异常表
一、为什么需要异常表?
处于内核态的程序有下面四种情况会产生缺页异常:
1、内核试图访问属于进程地址空间的页,但是,该页对应的页框不存在或者内核试图去访问一个只读的页,分别对应“请求调页”和“写时复制”两种情况。
2、内核寻址到属于内核地址空间的页,但是相应的页表项没有被初始化,这个对应“非连续内存区访问”。
3、内核代码包含编程错误,函数执行产生异常,这是一个内核漏洞。
4、系统调用服务例程试图读写一个内存区,而该内存区的地址是通过系统调用参数传递过来的,但确不属于进程的地址空间。
前面两种情况缺页异常处理程序很容易识别出来,但是后面两种情况却比较难区分。为了识别出后面的两种情况,linux内核专门建立了一个异常表来辨别后两种情况。
二、linux怎样实现异常表?
异常表存放了内核服务例程访问进程地址空间的每条指令的地址。这个表存放在内核代码段的__ex_table节,其起始和终止地址由C编译器产生的两个符号__start__ex_table和__stop__ex_table来标识,在linux内核链接脚本文件中将每个目标文件中的__ex_table节合并,并定义了__start__ex_table和__stop__ex_table来标识。
__start___ex_table = .; //异常表
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
此外,每个动态装载的内核模块包含自己的局部异常表,当模块被加载进内核时,这个表也被装入内存。
每个异常表的表项都是一个exception_table_entry结构:
struct exception_table_entry
{
unsigned long insn, fixup;
};
insn是访问进程地址空间的指令的线性地址。当存放insn单元中的指令所触发的缺页异常发生时,fixup就是要调用的汇编指令代码地址,通常这个汇编代码强制服务例程返回一个出错码给用户态进程。
一般通过下面的汇编伪指令向异常表中插入一个表项:
.section __ex_table, “a”
.long faulty_instruction_address, fixup_code_address
.previous
faulty_instruction_address是访问进程地址空间指令的地址,fixup_code_address是faulty_instruction_address指向的指令所引起异常的修正代码,通常是给用户程序返回错误码。
例如在访问进程地址空间的内核代码中:
__get_user_1:
GET_THREAD_INFO(%edx)
cmpl TI_addr_limit(%edx),%eax
jae bad_get_user
: movzbl (%eax),%edx
xorl %eax,%eax
ret __get_user_2:
addl $,%eax
jc bad_get_user
GET_THREAD_INFO(%edx)
cmpl TI_addr_limit(%edx),%eax
jae bad_get_user
: movzwl -(%eax),%edx
xorl %eax,%eax
ret __get_user_4:
addl $,%eax
jc bad_get_user
GET_THREAD_INFO(%edx)
cmpl TI_addr_limit(%edx),%eax
jae bad_get_user
: movl -(%eax),%edx
xorl %eax,%eax
ret bad_get_user:
xorl %edx,%edx
movl $-,%eax
ret .section __ex_table,"a"
.long 1b,bad_get_user
.long 2b,bad_get_user
.long 3b,bad_get_user
.previous
从上面的汇编代码中可以知道,真正访问进程地址空间的指令是标号1,2,3处的指令,所以只需要把这三处的指令地址放到异常表中就可以了,bad_get_user是处理这个三条指令引起异常的修改代码。
三、怎样通过异常表来判断异常类型?
当内核态发生缺页异常时,缺页异常处理程序先排除了前面两种情况,然后检查异常表:如果表中包含产生异常的指令地址,那么这个错误就是由非法的系统调用参数引起的,也就是第四种情况,否则,就是由某一更严重的内核bug引起的,即第三种情况。
Linux异常表的更多相关文章
- Linux异常关机后,Mysql启动出错ERROR 2002 (HY000)
Linux异常关机后,Mysql启动或訪问时,出错: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/ ...
- Linux curl 表单登录或提交与cookie使用
本文主要讲解通过curl 实现表单提交登录.单独的表单提交与表单登录都差不多,因此就不单独说了. 说明:针对curl表单提交实现登录,不是所有网站都适用,原因是有些网站后台做了限制或有其他校验.我们不 ...
- 通过字节码分析this关键字以及异常表的作用
1.创建MyTest3类 public class MyTest3 { public void test(){ try { InputStream is = new FileInputStream(& ...
- 通过字节码分析this关键字以及异常表的重要作用
在之前的字节码分析中缺少对异常的介绍,这次主要来对字节码异常表相关的东东进行一个学习,下面先来编写一个相关异常的小程序: 接着编译来看用javap -verbose来查看一下它的字节码信息: xion ...
- 【JVM学习笔记】异常表的重要作用以及locals属性的含义
有如下代码 public class Test { public void work() { try { InputStream is = new FileInputStream("test ...
- Linux系统调用表
Linux系统调用表 记录下来,免得到处找 32位 int 0x80 %eax Name Source %ebx %ecx %edx %esx %edi 1 sys_exit kernel/exit. ...
- Linux异常体系之stubs_offset
转自 http://www.xuebuyuan.com/2208550.html 在ARM V4及V4T以后的大部分处理器中,中断向量表的位置可以有两个位置:一个是0x00000000,另一个是0xf ...
- 让 MySQL 在 Linux 下表名不区分大小写(实为表名全小写)
把 Windows 下的应用部署到 Linux 下,使用到了 Quartz 集群的特性,所以建了 MySql 的中间表,一启动看到报错: Invocation of init method faile ...
- linux TLB表
TLB - translation lookaside buffer 快表,直译为旁路快表缓冲,也可以理解为页表缓冲,地址变换高速缓存. 由于页表存放在主存中,因此程序每次访存至少需要两次:一次访存获 ...
随机推荐
- c#中abstract与virtua、overridel的用法
1.abstract 抽象方法 ,virtual 虚方法 ,override 重载函数 父类A.m() 子类B.m() abstract的方法父类可以不实现,让子类去重写(重写=overwrite ...
- Usaco*Brownie Slicing
Description Bessie烘焙了一块巧克力蛋糕.这块蛋糕是由R*C(1 <= R,C <= 500)个小的巧克力蛋糕组成的. 第i行,第j列的蛋糕有N_ij(1 <= N_ ...
- 一鼓作气 博客--第四篇 note4
1.元祖允许重复数据.只读元组,列表,元祖没有增删改查,比如身份证列表,不允许修改,就存成 元祖. 2. 字典 key-value对 特性: 无顺序 去重 查询速度快,比列表快多了 比list占用内存 ...
- 达梦7的试用 与SQLSERVER的简单技术对比
达梦7的试用 与SQLSERVER的简单技术对比 达梦数据库公司推出了他们的数据库服务管理平台,可以在该平台使用达梦数据库而无须安装达梦7数据库 地址:http://online.dameng.com ...
- 多种坐标系之间的转换 Proj.NET和DotSpatial
Proj.NET ( http://projnet.codeplex.com/)是一个.NET下开源的空间参照和投影引擎,遵循OGC相关标准.负责人(Coordinators )是D_Guidi 和S ...
- ENode框架使用场景简述
ENode是一个.NET平台下,纯C#开发的,基于DDD,CQRS,ES,EDA,In-Memory架构风格的,可以帮助开发者开发高并发.高吞吐.可伸缩.可扩展的应用程序. 开源项目地址:https: ...
- Java NIO3:通道和文件通道
通道是什么 通道式(Channel)是java.nio的第二个主要创新.通道既不是一个扩展也不是一项增强,而是全新的.极好的Java I/O示例,提供与I/O服务的直接连接.Channel用于在字节缓 ...
- 作业三: 代码规范、代码复审、PSP
分) 对于是否需要有代码规范,请考虑下列论点并反驳/支持: 这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 我是个艺术家,手艺人,我有自己的规范和原则. 规范不能 ...
- 使用PM2将Node.js的集群变得更加容易
介绍 众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎.不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心 ...
- jQuery AJAX 网页无刷新上传示例
新年礼,提供简单.易套用的 jQuery AJAX 上传示例及代码下载.后台对文件的上传及检查,以 C#/.NET Handler 处理 (可视需要改写成 Java 或 PHP). 有时做一个网站项目 ...