热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Windows核心编程学习笔记24章

第24章异常处理程序与软件异常本章讲解SHE结构的另一个方面的功能。分三个部分:一、异常分类。二、异常处理程序结构。三、与终止处理程序的区别。一、异常分类

第24章 异常处理程序与软件异常

本章讲解SHE结构的另一个方面的功能。分三个部分:一、异常分类。二、异常处理程序结构。三、与终止处理程序的区别。

一、异常分类:硬件异常和软件异常。

二、当一个硬件或软件异常被抛出时,OS会给我们的应用程序一个查看异常类型的机会,并允许应用程序自己处理这个异常。异常处理程序的语法结构:

__try

{//guarded body}

__except(exception filter(异常过滤程序))

{//exception handler(异常处理程序)}

try块后必须且仅能跟一个except块或finally块,不能同时跟俩,多个finally块或except块也不行。但却可以将try-finally块嵌套与try-except块中,反过来也可以。

当抛出异常时,系统定位到except块的开始处,并对异常过滤程序的表达式求值,这个表达式的值必定为以下三个标识符之一:EXCEPTION_EXECUTE_HANDLER、EXCEPTION_EXECUTE_SEARCH、EXCEPTION_EXECUTE_EXECUTION。

讲讲这三个标识符将怎样影响线程的执行。参照下面两个图。

OK,这两个图是从书上截取的。我想说的是,这两个图是错误的。有兴趣的试试这段代码:

void Func1()
{
__try
{
int j = 0;
int i = 5 / j;
Func2();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
AfxMessageBox("Func1!\n");
}
}
void Func2()
{
int dwTemp = 0;
__try
{
int i = 5;
}
__finally
{
AfxMessageBox("Func2!\n");
}
AfxMessageBox("Func3!\n");
}


现在我自己画正确的图:




发生EXCEPTION_CONTINUE_EXECUTION异常时,代码继续执行,所以最好避免使用此类型的异常。

全局展开,我口述下吧:


情形1:try-except块外面包含着try-except块:若异常发生在外层try-except块,则内层try-except块不执行;若异常发生在内层的try-except块,则执行完内层后接着下一行执行代码。

情形2:try-finally块外面包含着try-except块,且异常发生在try-except块:当异常发生时,若try-finally块还未执行,则仅执行except块。其实类似情况1

情形3(也是最复杂的情况):try-finally块外面包含着try-except块,且异常发生在try-finally块。执行顺序:先执行try-finally块的finally,然后再执行try-exceptexcept块。若异常发生在try-except块,则finally块就不执行。

         注意:Windows Vista开始,若一个异常发生在try/finally块,而其外层有没有try/except(同时过滤程序返回EXCEPTION_CONTINUE_HANDLER),进程就立刻终止,不再全局展开也不执行finally块。

试试下面的,看能算出正确的执行顺序吗?答案见代码后。

void Func1()
{
//1.do any processing here.
__try
{
//2.call another function.
Func2();
}
__except(/*6.Evaluate filter*/EXCEPTION_EXECUTE_HANDLE)
{
//8.After the unwind, the exception handler executes.
}
//9.exception handled---continue execution.
}
void Func2()
{
DWORD dwTemp = 0;
//3.do any processing here.
__try
{
//4.request permission to access protected data.
WaitForSingleObject(g_hSem, INFINITE);
//5.modify the data
//an exception is generated here.
g_dwProtectedData = 5 / dwTemp;
}
__finally
{
//7.global unwind occurs because filter evaluated to EXCETPTION_EXECUTE_HANDLER.
//allow others to use protected data.
ReleaseSemaphore(g_hSem, 1, NULL);
}
//continue processing--never executes.
}


 

答案:上面的数字表明了执行顺序。

GetExceptionCode是内在函数,它的返回值表明刚刚发生的异常的类型。此函数只能在异常过滤程序里(__except之后的括号里)或异常处理程序的代码里调用。

逗号操作符:从左到右执行逗号分隔的表达式,当所有表达式都求值完毕时,返回最后一个表达式的值。

软件异常:我们可在程序里强制抛出一个异常,而非由CPU捕获某个事件抛出的异常。传统的做法是:函数通过返回一些错误代码来指明运行失败。函数的调用者应检查这些错误代码并采取相应的措施。这会导致调用者需要频繁的做清理工作并返回给它自己的调用者一个失败代码。错误代码的逐层传播导致代码很难编写和维护。

另一种方法是我们可让函数在失败时抛出异常,而不是返回错误代码。这种方式,代码可易编写和维护。且因省略了很多的错误检查代码,程序执行效率更高。RaiseException可抛出一个异常。

软件异常的捕获方式与硬件异常完全一样。参考P660

三、与终止处理程序区别:①异常过滤程序(exception filter)和异常处理程序(exception handler)主要由OS来负责执行-----在异常过滤程序表达式计算和异常处理程序执行方面,编译器所做的工作十分有限。②还记得在终止处理程序try块中建议不用return,continue,break等语句,但在异常处理程序的try块中,这些语句不会导致程序性能损失或增加代码量。

 


推荐阅读
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
author-avatar
是唐雨冰吗
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有