理解First Chance和Second Chance避免单步调试
原文链接地址:http://blog.csdn.net/Donjuan/article/details/3859160
在现在C++、Java、.Net代码大行其道的时候,很多代码错误(Bug)都是通过异常的形式表现出来的。由于工期紧或者种种原因,很多程序员在碰到程序发生未处理的异常的第一反应就是try … catch (Exception e) { … }。然而代码开发到后期的时候,这种简单粗暴的解决代码错误(Bug)的方式就会在其他不相干的地方表现出来,有的时候甚至导致程序随机的不稳定,而且很难调试。比如执行下面的代码你会发现输出的值是12345.6789:
using System;public class Class1{public static void Main(){Console.WriteLine(Calculate("12345.6789 + 987654321l"));}private static double Calculate(string expression){string[] numbers = expression.Split('+');return RedundantParseForDemoOnly(numbers[0].Trim()) +RedundantParseForDemoOnly(numbers[1].Trim());}private static double RedundantParseForDemoOnly(string number){try{return double.Parse(number);}catch{return 0;}}}
当然啦,你可以说只要强迫项目组所有程序员不要catch通用异常就可以了,但是老虎总是有打盹的时候,而且大部分项目组因为人才梯队建设的问题都会有那么几个新人……
我在工作中发现很多程序员都不理解,或者说根本就没有去注意过表2里面的输出,浪费了很多好的调试机会。因此我看到很多优秀的程序员都是非常辛苦的单步调试,一步步地跟踪代码。这个过程不仅辛苦,而且非常容易出错,因为单步跟踪代码容易让人犯晕。实际上你可以利用Windows提供的结构化异常处理(SEH)来帮助你快速找到问题所在。
在程序运行的时候,特别是程序里面发生异常的时候,如果你使用windbg.exe、cdb.exe等命令行调试器的时候,或者如果你留心Visual Studio的输出( output)窗口里的文本输出的时候,你将会看到类似下面的输出:
First-chance exception at 0x004116a9 in 异常处理.exe: 0xC0000005: Access violation writing location 0x00000000.……First-chance exception at 0x7c812aeb in 异常处理.exe: Microsoft C++ exception: char at memory location 0x0012fd88..
异常机制简介
CPU产生异常以后,根据异常代码在异常处理表里面查找对应的异常处理程序,通过调用异常处理程序执行了合适的处理之后再继续执行其他的代码。
对于CPU来说,硬件异常、软件异常、C++ 异常和.NET异常的触发和处理的方式都是一样的,这种方式在Windows中叫做结构化异常处理(SEH)。
异常处理
3. 如果Windows没有发现任何一个异常处理块处理掉这个异常的话,也就是到程序入口(main)函数也没有找到一个合适的异常处理块的话,Windows会使用它自带的异常处理块处理这个异常;
4. Windows自带的异常块会检查你的程序是否附加了一个调试器,如果是的话,Windows中断程序并将控制权交给调试器。
设置调试器不要忽略first chance异常
在Windbg里面,使用下面的命令来通知调试器不要忽略first chance异常:
sxe 异常代码
注意sxe后面有一个空格,例如在调试.NET程序的时候,可以使用命令sxe 0xE0434f4D来使调试器在catch块执行之前中断程序的执行。
可以使用命令
sxd 异常代码
来启用忽略first chance异常的功能。
在Visual Studio里面,请参考我的另外一篇文章学习如何设置:CLR Debugger - 在程序抛出异常的时候中断程序的执行
如何知道调试器正在忽略first chance异常?
通过查看调试器里面的输出信息,你可以了解调试器是否启用了在first chance异常触发时中断程序执行的功能。
在Visual Studio里面,可以查看“输出”窗口里面的文本输出:
在Windbg里面,类似下面的输出表示调试器忽略了first chance异常:
附录
// 异常处理.cpp : Defines the entry point for the console application.// #include "stdafx.h"#include <iostream>#include <windows.h>#include <excpt.h>using namespace std;int ExceptionFilter(unsigned int code, struct _EXCEPTION_POINTERS *ep){if ( code == EXCEPTION_ACCESS_VIOLATION )return EXCEPTION_EXECUTE_HANDLER;elsereturn EXCEPTION_CONTINUE_SEARCH;}void CppTestFunction(){try{throw "Test Cpp Exception";}catch ( char * ){cout << "char * exception caught" << endl;}}int _tmain(int argc, _TCHAR* argv[]){int *p = NULL;__try{*p = 1;}__except ( ExceptionFilter(GetExceptionCode(), GetExceptionInformation())){cout << "ACCESS VIOLATION CAUGHT" << endl;}CppTestFunction();return 0;}
转载于:https://www.cnblogs.com/wuyuan2011woaini/p/5178970.html
理解First Chance和Second Chance避免单步调试相关推荐
- 单步调试理解webpack里通过require加载nodejs原生模块实现原理
在webpack和nodejs里,我们经常使用require函数加载原生模块或者开发人员自定义的模块. 原生模块的加载,比如: const path = require("path" ...
- 二、Neo4j源码研究系列 - 单步调试
二.Neo4j源码研究系列 - 单步调试 一.背景介绍 上一篇我们已经把了neo4j的源码准备以及打包流程完成了,本篇将讲解如何对neo4j进行单步调试.对于不了解如何编译打包neo4j的读者,请阅读 ...
- linux下gdb单步调试
用 GDB调试程序 GDB 概述 ---- GDB 是 GNU开源组织发布的一个强大的 UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像 VC. BCB等 IDE的调试,但如果你是在 ...
- android平台从froyo 2.2开始支持jni单步调试了
一.写在前面的话(可以理解为废话) 前段时间从网上看了google的io大会,亲眼看到了google在it技术发展和创新领域所做的工作(在此也问候一下apple公司的美术家门,你们辛苦了).虽然goo ...
- x86_64平台SingleStep单步调试原理和示例
先看一个程序: // simple.c int value = 0; int main(int argc, char **argv) {value ++;value ++;value ++;value ...
- GDB调试利器-单步调试与查看变量
前言 前面两篇已经对Linux下如何使用gdb启动调试,GDB调试利器-断点设置与查看源码我们已经了解了GDB基本的启动调试,设置断点,查看源码等,如果这些内容你还不知道,建议先回顾一下前面的内容. ...
- Windows上VS2017单步调试FFmpeg源码的方法
之前在https://blog.csdn.net/fengbingchun/article/details/90114411 介绍过如何在Windows7/10上通过MinGW方式编译FFmpeg 4 ...
- 单步调试_keil for arm 调试时无法单步运行及打断点
在keil调试的过程中,会出现部分函数断点打不上去.单步调试step over功能无法使用的情况.造成该情况的主要原因可能为编译时使用的优化等级过高,导致其调试信息失真的问题. 解决办法,打开魔术棒- ...
- Python如何实现单步调试
Python如何实现单步调试 https://www.cnblogs.com/jing1617/p/9396617.html https://www.cnblogs.com/xiaohai2003ly ...
最新文章
- java8学习:新的日期使用
- aspose.words for java操作文档doc,设置一级二级三级标题以及段落表格等详情
- how is SAP UI5 configuration.js loaded in the runtime
- Android 第五课 常用控件的使用方法(TextView、Button、EditView、 ImageView、 ProgressBar、 ProgressDialog等)
- javascript权威指南(2)
- vue 转换信息为二进制 并实现下载
- 选择器、像素和百分比、颜色单位、文档流-css基础
- 【UOJ#177】欧拉回路
- 经典神经网络 -- GoogLeNet / Inception : 设计原理与pytorch实现
- C语言编译器(C语言编程软件)完全攻略
- 【第十届“泰迪杯”数据挖掘挑战赛】C题:疫情背景下的周边游需求图谱分析 问题一方案及Python实现
- keyword can not be an expression
- 内窥镜胶囊(胶囊内镜)硬件方案(二)
- java web play_玩转Java Web应用开发:Play框架
- 百度seo引流怎么做?一个免费分享知识的平台
- 10万存银行,几年能翻一番?
- (十一:2020.08.28)CVPR 2017 追踪之论文纲要(译)
- access表达式的用法
- Appium 常用初始化启动参数 Capability详解
- html 图片自动滚动播放,JS实现图片自动滚动(图片横向滚动)