异常机制简介

当CPU运行到一些非法的指令,例如除零错误,访问内存页失败等指令,CPU会生成一个硬件异常,不同的异常有固定的异常代码作为标识符,异常产生以后CPU暂时不能继续执行后续的指令—因为后续的指令有可能也是无效的。当然不能让整个计算机系统就这么当掉,因此CPU内置了一个异常处理表—这个异常处理表只有运行在内核模式的代码才能访问,操作系统在启动的时候初始化这个异常处理表,为每一个异常注册一个异常处理程序,因此这个表看起来就像:

0xC0000005

AccessViolationExceptionHandler()

……

0x80000003

LaunchOrNotifyDebugger()

CPU产生异常以后,根据异常代码在异常处理表里面查找对应的异常处理程序,通过调用异常处理程序执行了合适的处理之后再继续执行其他的代码。

处理CPU自定义的硬件异常以外,异常处理表里面还有一些空的表项,这样操作系统可以通过添加自定义的异常代码和相应的异常处理程序实现软件异常。在Windows操作系统中,程序可以通过调用Win32的RaiseException函数来触发软件异常。因此实际上C++和.NET里面的异常都是通过调用RaiseException来实现的,然而异常处理表不是很大,只能保存不超过256个异常处理程序信息,因此Windows只定义了几个通用的异常码来表示C++ 和.NET异常。

0xE06D7363

表示C++ 异常

0xE0434f4D

表示CLR(或者说.NET)异常

对于CPU来说,硬件异常、软件异常、C++ 异常和.NET异常的触发和处理的方式都是一样的,这种方式在Windows中叫做结构化异常处理(SEH)。

异常处理

1. 当程序里面有一个异常发生以后;

2. SEH首先通过回溯堆栈内容,查找程序内部是否有一个异常处理块(就是我们通常知道的catch 块);如果找到一个异常处理块可以处理这个异常,那么Windows将异常处理块所在的函数下面的堆栈释放,并且执行这个异常处理块里面的代码。

3. 如果Windows没有发现任何一个异常处理块处理掉这个异常的话,也就是到程序入口(main)函数也没有找到一个合适的异常处理块的话,Windows会使用它自带的异常处理块处理这个异常;

4. Windows自带的异常块会检查你的程序是否附加了一个调试器,如果是的话,Windows中断程序并将控制权交给调试器。

5. 如果没有调试器附加到你的程序上,Windows启动注册在注册表里面的默认验尸调试器,一般情况下,Windows的默认调试器是Dr Watson,这个调试器的工作就是弹出著名的“调试还是终止,这个问题”对话框(或者是“是否将错误报告发送给微软?”对话框):

在上面的处理步骤中,第一步通过RaiseException触发异常的时候,Windows会先检查你的程序是否正在被调试,如果有一个调试正附加在你的程序上,Windows向调试发送一个调试消息,通知调试器程序里面有一个异常发生,询问调试器是否要中断程序执,默认情况下调试器会忽略这条消息—因为我们纯洁的调试器总是相信程序员都能写出优良的代码出来。这个步骤在调试术语中叫做第一次机会(First Chance)--第一次在异常发生的现场观察触发异常的环境。

而第3步以后,操作系统自己来处理这个异常的时候,在调试术语中叫做第二次机会(Second Chance),由于这个时候程序实际上已经挂了(不会有任何生命活动了)—不是病危,所以这个时候即使你将调试器附加上去来检查触发异常的环境时,就像法医在检查人非正常死亡的原因一样—验尸调试。

设置调试器不要忽略first chance异常

在程序开发的时候,我们当然是希望在程序病危(first chance异常)的时候检查代码错误(Bug)的原因啦,因此如果程序发生一些莫名其妙的Bug时,在调试程序的时候,最好通知调试器不要忽略first chance异常。因为如果异常被程序内部的代码catch掉的话,很有可能会导致我们忽略重要的线索。

在Windbg里面,使用下面的命令来通知调试器不要忽略first chance异常:

sxe 异常代码

注意sxe后面有一个空格,例如在调试.NET程序的时候,可以使用命令sxe 0xE0434f4D来使调试器在catch块执行之前中断程序的执行。

可以使用命令

sxd 异常代码

来启用忽略first chance异常的功能。

.net异常机制的更多相关文章

  1. Atitit 异常机制与异常处理的原理与概论

    Atitit 异常机制与异常处理的原理与概论 1. 异常vs 返回码1 1.1. 返回码模式的处理 (瀑布if 跳到失败1 1.2. 终止模式  vs 恢复模式(asp2 1.3. 异常机制的设计原理 ...

  2. C++ 异常机制分析

    C++异常机制概述 异常处理是C++的一项语言机制,用于在程序中处理异常事件.异常事件在C++中表示为异常对象.异常事件发生时,程序使用throw关键字抛出异常表达式,抛出点称为异常出现点,由操作系统 ...

  3. 【转载】C++异常机制的学习

    参考了这篇文章:http://blog.chinaunix.net/uid-24517549-id-4079174.html 关于线程 进程和线程的概念相信各位看官早已耳熟能详.在这里,我只想带大家回 ...

  4. Java异常机制

    Java异常分类 异常表明程序运行发生了意外,导致正常流程发生错误,例如数学上的除0,打开一个文件但此文件实际不存在,用户输入非法的参数等.在C语言中我们处理这类事件一般是将其与代码正常的流程放在一起 ...

  5. 黑马程序员——【Java基础】——面向对象(二)异常机制、包(Package)

    ---------- android培训.java培训.期待与您交流! ---------- 一.异常机制 (一)异常概述 1.异常:就是程序在运行时出现不正常情况. 2.异常类:程序在运行时,出现的 ...

  6. C 几种异常机制简单讲述

    引言 这是关于C中如何使用异常机制的讨论.顺带讲一讲C中魔法函数的setjmp内部机制.通过它实现高级的异常try...catch. 允许我先扯一段面试题. 对于计算机面试题. 算法题等.觉得还是有意 ...

  7. C++异常机制知识点

     在这里总结一下,C++中的异常机制,以及如何使用异常的知识点 C++中处理异常的过程是这样的:在执行程序发生异常,可以不在本函数中处理,而是抛出一个错误信息,把它传递给上一级的函数来解决,上一级解决 ...

  8. [转载]C++异常机制的实现方式和开销分析

    原文章网址:http://baiy.cn/doc/cpp/inside_exception.htm C++异常机制的实现方式和开销分析 白杨 http://baiy.cn 在我几年前开始写<C+ ...

  9. c++异常机制实现原理

    今天突然看到一篇文章,讲异常机制的实现,所以分享一下:http://baiy.cn/doc/cpp/inside_exception.htm 内容讲的很深,但是编译器的实现是不是真是这样就不知道了,我 ...

  10. java中的异常机制(编译时异常)

    / * 1 异常机制的原理 * 异常是什么:就是错误的另外一种说法; * 在java中,有一个专门模拟所有异常的类,所有的异常都必须继承这个类:Throwable; * 本质是:当程序出错以后,jvm ...

随机推荐

  1. C# 属性(Property)和字段(Field)的区别

    导读: 近期学习过程中发现了一些问题,我的学习只是学习,敲代码就是敲代码,没有加入思考,也不问为什么就直接去敲人家写好的例子去敲,把知识都学死了,逐渐散失了思考能力,所以学习的兴趣大打折扣,正如那句话 ...

  2. 作为完美主义者(强迫症)如何将linux的eth1网卡修改为eth0网卡

    1:由于你是克隆的虚拟机或者直接就是使用别人的Centos操作系统直接打开到自己本地的虚拟机,网卡可能就是eth1而不是eth0,下面简单写一下如何将eth1修改为eth0,步骤如下所示: 2:如果你 ...

  3. 从oracle到mysql

    过去四年一直是使用oracle,现在要开始使用mysql了,对于使用中发现的不同之处,我在此记录 mysql在linux下表名区分大小写,windows下表名不区分大小写 mysql没有number类 ...

  4. Spring MVC 注解

    概述   Spring MVC是一个采用依赖注入的思想编写.对象的依赖注入Bean的方式可以通过Spring XML里面配置,配置之后的Bean使用时候,无需使用New关键字建立对象.但是如果所有的B ...

  5. Codeforces 758F Geometrical Progression

    Geometrical Progression n == 1的时候答案为区间长度, n == 2的时候每两个数字都可能成为答案, 我们只需要考虑 n == 3的情况, 我们可以枚举公差, 其分子分母都 ...

  6. python--类中的对象方法、类方法、静态方法的区别

    1.对象方法:顾名思义,是对类实例化后的对象有效的,由对象调用 2.类方法:第一个参数是cls(当前类),是对当前类做的额外的处理,类方法需要用类去调用,而不是实例对象调用 3.静态方法:没有参数!没 ...

  7. NOIP2017提高组Day2T2 宝藏 洛谷P3959 状压dp

    原文链接https://www.cnblogs.com/zhouzhendong/p/9261079.html 题目传送门 - 洛谷P3959 题目传送门 - Vijos P2032 题意 给定一个 ...

  8. Django之ORM操作总结

    Django之ORM总结 表结构 from django.db import models # 一对多:班级与学生 # 多对多:班级与老师 # Create your models here. #创建 ...

  9. [ 高危 ] my网任意账户登陆

    该网站的任意登录其实都已经提交得差不多了,本来以为这个漏洞会是一个重复的,然而试了一下发现思路奇葩. 任意登录,一般都为验证码爆破,4位手机验证码,而用于拦截的图片验证码没有或者可以重复使用,所以就能 ...

  10. 转载:ThreadPoolExecutor 源码阅读

    前言 之前研究了一下如何使用ScheduledThreadPoolExecutor动态创建定时任务(Springboot定时任务原理及如何动态创建定时任务),简单了解了ScheduledThreadP ...