送专利啦~~ .Net高阶异常处理之TopLevelEH
我们知道,.Net的应用程序运行在.net framework虚拟机上,对于在运行时发生的错误,我们有try...catch可以捕捉,实在不济,对于winform和asp.net 我们都有全局的事件可以订阅处理。具体请参见:http://www.cnblogs.com/eaglet/archive/2009/02/17/1392191.html ,但是如果不通过.net Framework,而是直接通过P/Invoke调用操作系统的C/C++写的库,而不是通过.Net Framework的BCL调用操作系统功能,那么上面链接所说的方法便失去作用。譬如我有一个方法:
[DllImport("kernel32")]
private static extern void RtlMoveMemory(IntPtr dst, ref byte src, Int32 len);
然后我们拖个按钮,写个事件:
private void button1_Click(object sender, EventArgs e)
{
byte a = ;
RtlMoveMemory(IntPtr.Zero, ref a, );
}
程序会直接崩溃,用上述的方法无论如何都捕捉不到的。不信您可以试试。
那怎么办?解铃还须系铃人。你直接调用操作系统API,难道操作系统没有提供异常捕获机制么?有的。现在我们引入几个术语。
术语:
SEH: 结构化异常处理
VEH: 向量化异常处理
TopLevelEH:顶层异常处理
相信写过C或者C++程序的同学可能不会陌生。现在我们介绍当用P/Invoke调用出现异常时,操作系统的异常处理顺序流程:
1. 交给调试器(前提是进程必须被调试)
2. 执行VEH
3. 执行SEH
4. TopLevelEH(进程被调试时不会被执行)
5. 交给调试器(上面的异常处理都说处理不了,就再次交给调试器)
6. 调用异常端口通知csrss.exe
下面咱就详细讨论一下各个步骤都干了哪些细活:
1. 第一次交给调试器
如果该出现异常的程序正在被调试,则该异常首先交给调试器处理(通过DebugPort)。调试器拿到这个异常后,需要判断是否要处理该异常.
2. 执行VEH
这里就不讲Veh的概念了,有兴趣的去Google一下。
如果没有被调试,或者调试器返回DBG_EXCEPTION_NOT_HANDLED,则就会检查是否存在VEH。如果存在VEH,则把异常交给他们处理。
VEH是个链表,可以存在多个Veh。每个VEH按顺序被调用。
一个VEH可以返回连个值:EXCEPTION_CONTINUE_SEARCH、EXCEPTION_CONTINUE_EXECUTION。返回 EXCEPTION_EXECUTE_HANDLER是无效的,等同于EXCEPTION_CONTINUE_SEARCH。
当一个Veh返回EXCEPTION_CONTINUE_SEARCH,则把异常交给下一个VEH处理。
如果返回EXCEPTION_CONTINUE_EXECUTION,认为已经被处理,退出异常处理器在异常指令处继续执行。
从执行顺序来看,VEH是在SEH之前执行的,并且不依赖某一线程,本进程中任何线程出现异常都可以被VEH处理,所以在有些时候是很有用处的。
那么怎么添加一个VEH呢?这里不是我们介绍的重点,请参考:http://msdn.microsoft.com/en-us/library/ms681420%28VS.85%29.aspx
3. 执行SEH
SEH是基于线程栈的异常处理机制。当所有的VEH都不处理该异常,该异常就会让SEH处理,所以它只能处理自己线程的异常。
4. TopLevelEH
顶层异常处理,这个就是我们今天介绍的重点了,这个其实是利用SEH实现的。在最顶层的SEH中,可以注册一个顶层异常处理器。虽然他是基于SEH实现的,但是它可以处理所有线程抛出的异常。
当SEH都处理不了该异常,在最顶层的SEH中就会检查是否注册了顶层异常处理,如果注册了,则执行顶层异常处理。
注意:如果该进程正在调试状态,顶层异常处理会被忽略,不会被执行。
顶层异常处理函数也可以返回三个值:EXCEPTION_CONTINUE_SEARCH、EXCEPTION_EXECUTE_HANDLER、EXCEPTION_CONTINUE_EXECUTION,先记着,等会有用。
这个到底有什么用呢?应用程序难免会出现崩溃的,一旦崩溃了怎么办?想想QQ,每次崩溃都会弹出友好提示,它是怎么做到的呢?对了,就是这个TopLevelEH。
关于这个,某java开发的同学其实已经申请了专利:
公开号 CN101794243 A
发布类型 申请
专利申请号 CN
公开日 2010年8月4日
申请日期 2010年3月18日
优先权日 2010年3月18日 摘要:
一种利用操作系统结构化异常处理加固java应用程序的方法
CN A 本发明提供一种利用操作系统结构化异常处理加固java应用程序的方法,Java提供了在java程序中调用本地程序的方法,这些本地程序通常以动态库的形式存在,一旦动态库中出现没有捕获的错误,就会导致整个java虚拟机崩溃,并且没有任何补救方法。通过利用操作系统的结构化异常处理机制,能保证java虚拟机在崩溃以后按照需要执行相应的补救措施,比如发出友好化的通知,重新启动java虚拟机等。
看看,人家java的Jni(就是java中调用本地链接库的方法,对应于.net的P/Invoke)也同样遇到了这个问题,然后。。然后就专利了还,好吧这个专利太简单,我送给.net的同学们好了。
该专利被华为引用:
公开号 WO2013071766 A1
发布类型 申请
专利申请号 PCT/CN2012/
公开日 2013年5月23日
申请日期 2012年7月12日
优先权日 2011年11月14日
公告号 CN103107905A, EP2712119A1, US20140115587
申请人 Huawei Technologies Co., Ltd., 华为技术有限公司 摘要:
本发明公开了一种异常处理方法、装置和客户端,属于在线应用领域。该方法包括:虚拟管理服务器接收与第一客户端交互的虚拟机发送的异常通知,所述异常通知至少携带用户标识和应用标识;所述虚拟管理服务器根据保存的与所述用户标识及应用标识对应的异常处理方式,保存所述虚拟机数据或与所述应用标识对应的应用的应用数据,并释放所述虚拟机资源。该装置包括:接收模块和异常处理模块。本发明使得不同应用、不同用户可以根据其需求定制不同的异常处理方法,也使得客户端不但可保存异常发生时的时刻或最接近异常发生时的时刻用户的使用状态,而且提高了在线应用系统的容量和效率。
说白了就是捕捉到异常之后发消息而已啦,其实所谓的专利就是这么简单的东西。
关于5和6我们就略过好了,讲讲大家都关心的怎么来实现吧。
首先定义一个委托:
public delegate Int32 CallBack(ref long a); CallBack mycall;
注册一个顶层异常处理器的方法如下:
[DllImport("kernel32")]
private static extern Int32 SetUnhandledExceptionFilter(CallBack cb);
在系统初始化时,调用:
mycall = new CallBack(MyExceptionfilter);
SetUnhandledExceptionFilter(mycall);
MyExceptionfilter签名如下:
Int32 MyExceptionfilter(ref long a)
它返回一个Int值,对应上面的TopLevelEH:
EXCEPTION_EXECUTE_HANDLER == 1 表示我已经处理了异常,可以优雅地结束了
EXCEPTION_CONTINUE_SEARCH == 0 表示我不处理,其他人来吧,于是windows调用默认的处理程序显示一个错误框,并结束
EXCEPTION_CONTINUE_EXECUTION e== -1 表示错误已经被修复,请从异常发生处继续执行。
在实际方法中,你可以记录下程序的dump文件(Dump文件有什么用?回头我再写一篇好了),发送消息,然后优雅的结束或者重启,做出极好的客户体验,是不是很棒?!接下来我们处理开头的异常,那其实很简单了,必定会被捕获到,不信您可以试试。
代码实在很简单,我就不上传了,有心的同学一试就出来了。
觉得写得好,您就点个赞~
参考链接:http://bbs.pediy.com/showthread.php?t=173853
送专利啦~~ .Net高阶异常处理之TopLevelEH的更多相关文章
- .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
dump文件相信有些朋友已经很熟悉了,dump文件的作用在于保存进程运行时的堆栈信息,方便日后排查软件故障,提升软件质量.关于dump分析工具windbg.adplus的文章更多了,如果您还不知道怎么 ...
- python高阶函数&异常处理
高阶函数 1.什么是高阶函数 在Python中,变量可以指向函数 函数名也是变量 既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数. ma ...
- ASP.NET Core 6框架揭秘实例演示[33]:异常处理高阶用法
NuGet包"Microsoft.AspNetCore.Diagnostics"中提供了几个与异常处理相关的中间件,我们可以利用它们将原生的或者定制的错误信息作为响应内容发送给客户 ...
- javascript设计模式学习之三—闭包和高阶函数
一.闭包 闭包某种程度上就是函数的内部函数,可以引用外部函数的局部变量.当外部函数退出后,如果内部函数依旧能被访问到,那么内部函数所引用的外部函数的局部变量就也没有消失,该局部变量的生存周期就被延续. ...
- JavaScript高阶函数的应用
定义 高阶函数是指至少满足下列条件之一的函数: 函数可以作为参数被传递: 函数可以作为返回值输出. JavaScript语言中的函数显然满足高阶函数的条件,在实际开发中,无论是将函数当作参数传递,还是 ...
- Javascript 闭包与高阶函数 ( 一 )
上个月,淡丶无欲 让我写一期关于 闭包 的随笔,其实惭愧,我对闭包也是略知一二 ,不能给出一个很好的解释,担心自己讲不出个所以然来. 所以带着学习的目的来写一写,如有错误,忘不吝赐教 . 为什么要有闭 ...
- 深入理解javascript函数进阶系列第一篇——高阶函数
前面的话 前面的函数系列中介绍了函数的基础用法.从本文开始,将介绍javascript函数进阶系列,本文将详细介绍高阶函数 定义 高阶函数(higher-order function)指操作函数的函数 ...
- js 高阶函数 闭包
摘自 https://www.cnblogs.com/bobodeboke/p/5594647.html 建议结合另外一篇关于闭包的文章一起阅读:http://www.cnblogs.com/bob ...
- 迈向高阶:优秀Android程序员必知必会的网络基础
1.前言 网络通信一直是Android项目里比较重要的一个模块,Android开源项目上出现过很多优秀的网络框架,从一开始只是一些对HttpClient和HttpUrlConnection简易封装使用 ...
随机推荐
- ajax 跨域访问的解决方案
ajax 跨域访问的解决方案 一.什么是跨域: 1.什么样的请求属于跨域: 域名,端口有任何一个不相同都属于跨域: 二.跨域的常用几种解决方案: 1.jsonp: 2.iframe: 3.webcon ...
- 【selenium专题】元素定位之多层框架和窗口
本节知识点 多层框架或窗口切换样式:WebDrvier.switchto().TargetLocator Interface WebDriver.TargetLocator下所有可切换对象 参考API ...
- 多进程《三》join方法
一 Process对象的join方法 在主进程运行过程中如果想并发地执行其他的任务,我们可以开启子进程,此时主进程的任务与子进程的任务分两种情况 情况一:在主进程的任务与子进程的任务彼此独立的情况下, ...
- kvm.install
#!/bin/bash ## TODO ## windows edition function with video driver NAME=win2008r2_fei_test CPU= MEM= ...
- dict字典;dict的操作
一.字典: 1. 字典 dict 用{}来表示 键值对数据 {key:value} 唯一性 键 都必须是可哈希的 不可变的数据类型就可以当做字典中的键 值 没有任何限制 1.1 字典的创建: ...
- Elasticsearch C# NEST IndexMany Children
foreach (IEnumerable<object> batch in objects.Batch(1000)) { var indexResponse = client.Bulk(s ...
- 为什么我会选择走 Java 这条路?
阅读本文大概需要 2.8 分钟. 作者:黄小斜 文章来源:微信公众号[程序员江湖] 最近有一些小伙伴问我,为什么当初选择走Java这条路,为什么不做C++.前端之类的方向呢,另外还有一些声音:研究 ...
- oracle navicat 可视化操作进行数据的修改
在进行oracle数据库中的数据操作编辑时,需要小心.oracle内置的安全机制是无处不在,并且很有必要存在的. 使用navicat对oracle中数据进行select操作时,查询出的结果是只读的,这 ...
- React第二篇:组件的生命周期
前言:因为生命周期是必须要掌握的,所以React的第二篇咱就写这. (版本:16.3.2) React的生命周期大致分为四个状态:分别是Mouting.Updating.Unmounting.Erro ...
- 包子凑数(dp思想)
问题描述: 小明几乎每天早晨都会在一家包子铺吃早餐.他发现这家包子铺有N种蒸笼,其中第i种蒸笼恰好能放Ai个包子.每种蒸笼都有非常多笼,可以认为是无限笼.每当有顾客想买X个包子,卖包子的大叔就会迅速选 ...