一、为什么需要异常表?

处于内核态的程序有下面四种情况会产生缺页异常:

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异常表的更多相关文章

  1. Linux异常关机后,Mysql启动出错ERROR 2002 (HY000)

    Linux异常关机后,Mysql启动或訪问时,出错: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/ ...

  2. Linux curl 表单登录或提交与cookie使用

    本文主要讲解通过curl 实现表单提交登录.单独的表单提交与表单登录都差不多,因此就不单独说了. 说明:针对curl表单提交实现登录,不是所有网站都适用,原因是有些网站后台做了限制或有其他校验.我们不 ...

  3. 通过字节码分析this关键字以及异常表的作用

    1.创建MyTest3类 public class MyTest3 { public void test(){ try { InputStream is = new FileInputStream(& ...

  4. 通过字节码分析this关键字以及异常表的重要作用

    在之前的字节码分析中缺少对异常的介绍,这次主要来对字节码异常表相关的东东进行一个学习,下面先来编写一个相关异常的小程序: 接着编译来看用javap -verbose来查看一下它的字节码信息: xion ...

  5. 【JVM学习笔记】异常表的重要作用以及locals属性的含义

    有如下代码 public class Test { public void work() { try { InputStream is = new FileInputStream("test ...

  6. Linux系统调用表

    Linux系统调用表 记录下来,免得到处找 32位 int 0x80 %eax Name Source %ebx %ecx %edx %esx %edi 1 sys_exit kernel/exit. ...

  7. Linux异常体系之stubs_offset

    转自 http://www.xuebuyuan.com/2208550.html 在ARM V4及V4T以后的大部分处理器中,中断向量表的位置可以有两个位置:一个是0x00000000,另一个是0xf ...

  8. 让 MySQL 在 Linux 下表名不区分大小写(实为表名全小写)

    把 Windows 下的应用部署到 Linux 下,使用到了 Quartz 集群的特性,所以建了 MySql 的中间表,一启动看到报错: Invocation of init method faile ...

  9. linux TLB表

    TLB - translation lookaside buffer 快表,直译为旁路快表缓冲,也可以理解为页表缓冲,地址变换高速缓存. 由于页表存放在主存中,因此程序每次访存至少需要两次:一次访存获 ...

随机推荐

  1. Devexpress

    1.隐藏最上面的GroupPanel gridView1.OptionsView.ShowGroupPanel=false; 2.得到当前选定记录某字段的值 sValue=Table.Rows[gri ...

  2. 2015-12-23-( dispaly:table的用法)

    dispaly属性的table和table-cell属性值不怎么常用,主要是浏览器的兼容性不好,大多数都是为了兼容IE6.IE7,此属性IE8以上,谷歌,火狐,oprea等浏览器都支持.  此disp ...

  3. DIV+CSS自适应布局

    自适应布局分两类:高度和宽度,方法有很多,我用三列布局举例,我就列几个通俗易懂的例子呗,懂了三列的,两列的原理一样,呵呵哒. 效果图如下:高度自适应——宽度自适应            1,高度自适应 ...

  4. Cocos2d 利用继承Draw方法制作可显示三维数据(宠物三维等)的三角形显示面板

    很久没有写博客了,这段时间比较忙,又是搬家又是做自己的项目,还有太多琐碎的事情缠身,好不容易抽出时间把最近自己做的一些简单例子记录一下. 在我的项目中,我需要一个显示面板来显示游戏中的一个三维数据,例 ...

  5. can't connect to mysql server on 'localhost'(10061)

    在linux下安装Navicat,想说在windows下试一试phpmyadmin之外的mysql图形工具. 显示下载安装了mysql workbench,链接成功.然后又弄了一下输入法重启,想说试一 ...

  6. 使用Python中PIL图形库进行截屏

    目的:通过使用Python的一个图形库PIL(Python Image Library)对屏幕进行截图 步骤: 1.下载PIL(路径)并安装 2.新建文件“截屏.py”,右键Edit with IDL ...

  7. 吐槽scala

    scala可能是唯一一个编译器和IDE对代码有不同理解的语言.当你开始用scala的高级特性的时候,他们的分歧特别的大,以至于现在,intellij上的scala插件已经不敢对可能编译不通过的代码标记 ...

  8. express-session 保存遇到的问题

    今天在用express4 试着做网站的时候,发现request.session 中一直不能保存新的值,还一直报一个错 express-session deprecated undefined resa ...

  9. java身份证验证

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; impor ...

  10. ex1-第一个程序 ”helloworld”

    代码: print("Hello world.")print("Hello again.")print("I like typing this.&qu ...