CLR如何将SEH异常映射到托管异常类型
托管异常处理构建在Windows操作系统的结构化异常处理之上,通常称为SEH。这意味着CLR了解如何在SEH和托管异常系统之间进行互操作,这是一个非常关键的点,因为SEH基于异常代码的概念,而托管异常处理则表示使用托管类型的异常。CLR相应地将SEH异常映射到托管异常,具体取决于引发SEH异常的方式和引发者。
注意:下面的讨论重点是运行在Windows操作系统上的桌面CLR。虽然讨论的目的是帮助理解这个概念,但是它使用了一些将来可能会改变的实现细节来说明。
托管代码中的同步异常(Synchronous exceptions)
当托管代码使用throw关键字引发异常时,它已经实例化了一个托管异常对象,该对象将表示引发的异常。这将传递给CLR,CLR在线程上设置一些与异常相关的状态,并调用Kernel32的RaiseException API来引发托管异常。此API的第一个参数是引发异常的SEH异常代码,CLR传递0xE0434F4D(托管异常SEH代码)。
这时,操作系统进入处理场景,开始在引发异常的线程堆栈上寻找SEH异常处理程序。CLR将其函数之一注册为OS的异常处理程序,以处理托管代码引起的异常。当它看到CLR SEH异常代码时,它知道正在引发托管异常,并继续查找线程状态以检索与异常相关的详细信息(例如,标识表示引发异常的托管异常对象)。
因此,在同步托管抛出的情况下,很容易将SEH异常映射到托管异常类型。
托管代码中的异步异常(Asynchronous exceptions)
简单地说,异步异常是在没有显式抛出的情况下引发的异常。如果执行算术操作(例如除以零异常)或使用可能导致访问冲突(AV)等异常的不安全托管代码,则在托管代码中可能会发生这种情况。异步异常的有趣之处在于,它们是使用它们唯一的SEH异常代码来表示的。例如AV用0xc000005表示,除以0(整数)用0xC0000094表示,除以0(浮点数)用0xC000008E表示,这里列出了常见的异常,异常代码值可以在WinNT.h中找到。
当在托管代码中引发此类异常时,操作系统再次开始在引发异常的线程堆栈上查找异常处理程序。当调用CLR的异常处理程序时,它知道所讨论的异常不是托管代码同步抛出的,因为异常代码不是CLR SEH异常代码。因此,它不再查找与异常相关的详细信息的线程状态,而是将SEH异常映射到一个托管异常类型。例如,除以零异常(整数和浮点)使用System.DivideByZeroException表示。
同样,当在托管代码中生成真正的AV时,它的异常代码为0xc000005。由于托管代码具有空引用的概念,因此运行时很少再进行检查来确定AV是否表示尝试使用空引用。如果是,则映射到System.NullReferenceException。否则,它将映射到System.AccessViolationException类型(在v2.0和更高版本的运行时中)。
在Native代码中引发异常

假设Zoo抛出了一个未在其中处理的Native异常,则该异常将向上传播,因为OS沿着堆栈向上移动,寻找异常的潜在处理程序。在这种情况下,由于堆栈上的下一个帧是Bar,而Bar是受管理的,因此操作系统最终会调用CLR的异常处理程序。由于SEH异常来自Native代码,因此它可能有任何异常代码。例如,它可以是一个C++异常(它具有SEH 0X06D7363的异常代码),或者它可以是一个特定于应用程序的SEH异常代码。关键在于CLR不知道存在的所有SEH异常代码(并且将来会被创建)。从映射到特定托管异常类型的角度来看,只有现有的子集是有意义的。
因此,当CLR的异常处理程序看到Native异常时,它将尝试将最常见的SEH异常代码映射到它们相应的托管异常类型(如前面用一些示例解释的那样)。对于运行时未标识的任何其他SEH异常代码,它将映射到System.runtime.InteropServices.SEH exception类型。
接下来会发生什么?
- 当操作系统从特定SEH异常的抛出点为堆栈上的第一个托管帧调用CLR的异常处理程序(假设堆栈上没有上下文转换)时,此映射仅完成一次。
- 由于此映射是基于SEH异常代码完成的,因此CLR知道给定的托管异常实例是否表示真正的Native SEH异常。例如,CLR知道System.AccessViolationException实例是否表示真正的AV或是托管代码引发的常规托管异常。为什么这很重要?好吧,当CLR确定了异常的损坏严重性时,它就会这样做!
映射完成后,CLR将开始查找异常处理程序的常规异常处理过程。
CLR如何将SEH异常映射到托管异常类型的更多相关文章
- c# 捕获非托管异常
在.NET 4.0之后,CLR将会区别出一些异常(都是SEH异常),将这些异常标识为破坏性异常(Corrupted State Exception).针对这些异常,CLR的catch块不会捕捉这些异常 ...
- Struts2拦截器之ExceptionMappingInterceptor(异常映射拦截器)
一.异常拦截器是什么? 异常拦截器的作用是提供一个机会,可以设置在action执行过程中发生异常的时候映射到一个结果字符串而不是直接中断. 将异常整合到业务逻辑中,比如在分层系统的调用中可以从底层抛出 ...
- Struts2学习第四天——全局结果,动态结果及异常映射
1.异常映射的配置 当Action方法出错时Struts会返回异常错误信息页面,这种页面方式是不友好的,可以使用try-catch捕捉异常,然后在catch块中返回对应的错误页面.这种为单个<a ...
- SpringBoot2.0 基础案例(03):配置系统全局异常映射处理
一.异常分类 这里的异常分类从系统处理异常的角度看,主要分类两类:业务异常和系统异常. 1.业务异常 业务异常主要是一些可预见性异常,处理业务异常,用来提示用户的操作,提高系统的可操作性. 常见的业务 ...
- SimpleMappingExceptionResolver异常映射
转自:https://blog.csdn.net/qqqqqq654/article/details/65767701 SimpleMappingException异常映射 当异常发生时,我们可以将它 ...
- Java框架之SpringMVC 05-拦截器-异常映射-Spring工作流程
SpringMVC 拦截器 Spring MVC也可以使用拦截器对请求进行拦截处理,可以自定义拦截器来实现特定的功能,自定义的拦截器可以实现HandlerInterceptor接口中的三个方法,也可以 ...
- 三:SpringBoot-配置系统全局异常映射处理
三:SpringBoot-配置系统全局异常映射处理 1.异常分类 1.1 业务异常 1.2 系统异常 2.自定义异常处理 2.1 自定义业务异常类 2.2 自定义异常描述对象 2.3 统一异常处理格式 ...
- springmvc——基于xml的异常映射和基于注解的异常映射
SpringMVC提供了基于XML和基于注解两种异常映射机制.这两种异常映射不能够只使用一个,他们需要一起使用.因为有些异常是基于注解异常映射捕获不到的. 在springmvc中,一个请求如果是由&l ...
- CLR via C#深解笔记三 - 基元类型、引用类型和值类型 | 类型和成员基础 | 常量和字段
编程语言的基元类型 某些数据类型如此常用,以至于许多编译器允许代码以简化的语法来操纵它们. System.Int32 a = new System.Int32(); // a = 0 a = 1 ...
随机推荐
- PHP基于TP5使用Websocket框架之GatewayWorker开发电商平台买家与卖家实时通讯
前段时间公司提了一个新的需求,在商品的详情页要实现站内买家和商品卖家实时通讯的功能以方便沟通促成交易,要开发此功能当时首先考虑到的就是swoole和workerman了,从网上大概了解了一下关于这两款 ...
- 2017-07-25 PDO预处理以及防止sql注入
首先来看下不做任何处理的php登录,首先是HTML页面代码 <html> <head><title>用户登录</title></head> ...
- pandas-08 pd.cut()的功能和作用
pandas-08 pd.cut()的功能和作用 pd.cut()的作用,有点类似给成绩设定优良中差,比如:0-59分为差,60-70分为中,71-80分为优秀等等,在pandas中,也提供了这样一个 ...
- Falsk框架 Session 与 Flask-Session
目录 Cookie 与 Session 简单了解 Falsk 中 Session 的保管机制 相关的配置 使用 Flask-Session 三方组件 基础练习题 Cookie 与 Session 简单 ...
- insmod/rmmod
insmod -f 不检查目前kernel版本与模块编译时的kernel版本是否一致,强制将模块载入 -k 将模块设置为自动卸除 -m 输出模块的载入信息 -o <模块名称> 指定模块的名 ...
- Android EventBus使用大全
添加依赖 implementation 'org.greenrobot:eventbus:3.1.1' public class HuaDongActivity extends Activity { ...
- Linux--基本目录
特点 系统版本:CentOS 6.5 Linux目录:一切从根开始 Linux下面的设备(磁盘)不挂载的话没有办法使用,使用设备必须有一个入口,挂载点实质就是一个目录. 目录结构及含义 目录 说明 b ...
- java继承 、方法重写、重写toString方法
1.Java的继承,关键词Extends package cn.mwf.oo; public class TextExtends { public static void main(String[] ...
- SVN无法检出项目
情况说明: SVN的管理员给我一个项目的检出权限,我用浏览器可以访问,TortoiseSVN无法检出,提示没有访问URL的权限,不能检出. SVN管理员交流别人可以使用,我用同事的电脑,使用我的账号检 ...
- yum仓库的部署
https://segmentfault.com/a/1190000013968371 私有yum仓库在企业中的应用还是比较广泛,有方便.快捷.灵活等优势.如某公司安全部门不允许大批量的主机连接互联网 ...