操作系统下糟糕的异常处理方式计划
伤势较重 linux下发生异常,芯片会自动产生一个异常中断。在这异常中断处理程序中会判断异常来自用户程序或者内核,如果是发生在用户程序,那么会产生一个异常信号,再根据异常信号的回调函数通知用户程序发生异常。如果发生在内核里面,那么就会搜索内核模块的异常结构表,找到相应的处理调用地址,修改异常中断的返回地址为异常处理的地址,中断返回的时候程序就跳到异常处理程序处理执行了。但具体这两种处理方法都很糟糕,下面简要分析一下。 linux系统把所有进程数据结构都放于内核,这就增加了一些不必要的切换时间。 linux可以通过系统调用,安装信号的回调函数,这回调函数指针存放在内核的进程数据结构里面。这点windows处理得比较好,windows把进程数据结构分成了两部分,一部分敏感数据放于内核的进程数据结构里面,加以保护,另一部分不敏感数据就放于用户空间,这样当访问那些不加保护的数据时,就不用切换到内核,节约了时间。像windows下异常处理,也是一种回调函数,但因为结构放于用户空间,安装的时候就很方便,也节约切换时间。 上面那一点只是效率问题,但linux内核的异常处理那才是糟糕。先介绍一下linux内核的异常处理结构吧,看明白了你自然就知道糟糕到什么程度了。要了解这,显然应该是先从异常中断入手。下面主要是x86芯片的一些处理,但别的芯片下的也应该差不多。 文件:entry.S: ENTRY(general_protection)pushl $ SYMBOL_NAME(do_general_protection)jmp error_code
这是异常中断入口,显然会执行do_general_protection。文件traps.c: asmlinkage void do_general_protection(struct pt_regs * regs, long error_code){if (regs-eflags VM_MASK)goto gp_in_vm86;/*虚拟8086下发生的异常否*/if (!(regs-xcs 3))goto gp_in_kernel;/*内核发生的异常否*/ror_code = error_code;ap_no = 13;force_sig(SIGSEGV, current);/*用户程序发生的异常,产生异常信号,根据异常信号的句柄回调处理函数*/return;gp_in_vm86:lock_kernel();handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);/*虚拟8086的处理*/unlock_kernel();return;gp_in_kernel:{unsigned long fixup;fixup = search_exception_table(regs-eip);/*根据异常时的eip搜索异常结构链找到处理程序地址*/if (fixup) {regs-eip = fixup;/*找到异常处理地址,修改中断返回地址,中断返回时跳到异常处理程序处*/return;}die(\"general protection fault\", regs, error_code);/*没找到异常处理程序地址,显示内核异常信息后死机*/}}
搜索异常处理程序代码文件extable.c: extern const struct exception_table_entry __start___ex_table[];extern const struct exception_table_entry __stop___ex_table[];unsigned long search_exception_table(unsigned long addr){unsigned long ret;#ifndef CONFIG_MODULES/* There is only the kernel to search. */ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);if (ret) return ret;#else/* The kernel is the last \"module\" -- no need to treat it special. */struct module *mp;for (mp = module_list; mp != NULL; mp = mp-next) {if (mp-ex_table_start == NULL)continue;ret = search_one_table(mp-ex_table_start,mp-ex_table_end - 1, addr);if (ret) return ret;}#endifreturn 0;}static inline unsigned longsearch_one_table(const struct exception_table_entry *first,const struct exception_table_entry *last,unsigned long value){while (first = last) {const struct exception_table_entry *mid;long diff;mid = (last - first) / 2 + first;diff = mid-insn - value;if (diff == 0)return mid-fixup;else if (diff 0)first = mid+1;elselast = mid-1;}return 0;}
成都治白癜风专业医院西安治疗男科医院哪家好
石家庄治疗牛皮癣最好的医院
- “酒瓶、空白、遥控器”成今年乌镇戏剧节青年竞演比赛三金属元素
- 一瓶茅台价值百亿?哈吉拍卖称系恶意竞拍,重新开拍后已有5人报名
- 共赏盛夏奇观!vivo S15系列快闪大型活动来袭,热闹非凡
- APP也能拍出电影感,vivo S15系列让你自带主角光环
- 科学安排教学工作 及时公开发表提示信息 北京市教委部署近期高校教育教学工作
- 放弃民办三本选择公办专科后,才说出的4件事,后悔没有早知道
- 东方海外国际(00316)第2月份总收益同比增加52.4%至52.85亿美元
- 莱克稳居2021年空气特别设计品牌三甲,激发国内企业品牌建设积极性
- 后悔没早看到这些"神"设计,漂亮又实用,众所周知是这3个地方
- 我在甘肃卖拉面:180㎡年营收500万,8个月回本
- 苏州大学和河海大学,谁的统治力更更胜一筹?
- 大S结婚照曝光!具俊晔一本正经哑肩太僵硬,她笑得欢快却太端着