你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 计算机安全与维护
Linux下实现Windows的结构化异常处理(一)
 

摘 要   针对Linux环境下对于异常处理支持的不足,提出了一种解决方案,实现了类似于Windows平台下的结构化异常处理技术,使程序可以更加方便地处理异常,这样提高了代码的健壮性和可维护性。

关键词  Linux;异常;结构化异常处理

 

在编写程序的过程中,经常会遇到代码因为种种原因发生异常的情况。用户模式下的应用程序还比较好,通常系统不会挂掉,不论是检查现场环境以便调试或是重新运行都比较方便。可驱动程序出现异常麻烦就比较大了,要么丢失错误现场,要么就等着重启动才能再次运行。实在是件让人头痛的事情。

Windows平台下,这个问题很好解决:SEHStructure Exception Handling)技术的出现为程序员提供了一个标准解决方案,程序员只需要注册好异常处理函数(由编译器负责,通常不是一个完整的函数,而是和可能发生异常的代码在同一个函数中),当因为当前线程的代码引发异常时,系统会自动调用异常处理函数,完成善后工作。

Linux下却没有类似的机制,异常处理例程是静态包含在内核代码中,而且必须精确定位出可能产生异常的代码的地址,这无疑会给异常处理带来很大的麻烦。不过反正Linux是开放式的,既然内核自己不提供类似的机制,那就自己来实现它。

要实现SEH,首先需要能够拦截异常,其次是在拦截到异常之后转移到相关的代码,最后,要能在可能产生异常的代码之前注册异常处理例程,并且在代码结束部分取消异常处理例程。

 

1  异常拦截

要拦截异常,直接修改IDT表,用自己的GP(general-protection)异常处理服务代码替换掉内核的异常处理代码就行,这个功能很容易实现。以下代码实现了拦截异常的功能:

void *_Origin_GP_Entry_;

 

void _hook_generalfalut()

{

    dtr  idtr;

    desc *pdesc;

   

    asm("sidt %0":"=m"(idtr));

    *pdesc=phys_to_virt(idtr->base);

    pdesc+=0xd;// point to GP description

    _Origin_GP_Entry_=(void*)((pdesc->basehigh<<16)|pdesc->baselow);

   

    pdesc->basehigh=((unsigned long)_ExceptionEntry>>16);

    pdesc->baselow=((unsigned long)_ExceptionEntry&0xffff);

}

注意:在程序退出时必须恢复原来的GP异常入口

 

2  异常处理

在自己的异常服务程序中检测相应的异常处理程序是否已经注册,如果是,则恢复现场,然后跳转到注册的异常处理程序运行;如果没有注册,就把控制权转交给内核的异常处理程序。

  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089