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 快表,直译为旁路快表缓冲,也可以理解为页表缓冲,地址变换高速缓存. 由于页表存放在主存中,因此程序每次访存至少需要两次:一次访存获 ...
随机推荐
- linux工具
sudo yum install yum-utils
- ajax 后台正常执行 错误类型却是404
后台执行importExcel,明明方法执行成功,但是前台却提示404 @RequestMapping("/import") public Json importExcel(@Re ...
- 关于“模仿"和”创新“
互联网刚刚进入中国的前10年,国内互联网企业基本处于模仿和学习阶段.三大门户新浪.搜狐和网易,师从雅虎:现在如日中天的BAT三巨头,百度学习谷歌.阿里巴巴学习亚马逊和EBAY.腾讯学习ICQ. 关于模 ...
- Search in Rotated Sorted Array
Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...
- Java 集合类的特性
ArrayList: 元素单个,效率高,多用于查询 Vector: 元素单个,线程安全,多用于查询 LinkedList: 元素单个,多用于插入和删除 HashMap: 元素成对,元素可为空 H ...
- linux配置ftp高级权限
建一个用于管理的ftp高级账号,ftproot,定义它的目录,也就是我们存放项目的地址,所属组www, useradd -d /home/www -g www ftproot www里存放很多项目,我 ...
- initWithCoder与initWithFrame的区别
1. initWithFrame方法是什么? initWithFrame方法用来初始化并返回一个新的视图对象,根据指定的CGRect(尺寸). 当然,其他UI对象,也有initWithFrame方 ...
- SQL Server2000清除数据库日志
sqlserver2000压缩日志 可以将jb51.ldf文件变得很小,方便备份数据库等,在sqlserver查询分析器中执行即可.复制代码 代码如下: DUMP TRANSACTION [jb51] ...
- SQL Server 2016 CTP2.2 的关键特性
SQL Server 2016 CTP2.2 的关键特性 正如微软CEO 说的,SQL Server2016 是一个Breakthrough Flagship Database(突破性的旗舰级数据库 ...
- 动态Web API层
返回总目录 本篇目录 构建动态Web API控制器 ForAll 方法 重写ForAll 方法 Http动词 动态Javascript代理 Ajax参数 单一服务脚本 Angular支持 Durand ...