作为一个程序员,解BUG是我们工作中常做的工作,甚至可以说解决问题能力是一个人工作能力的重要体现。因为这体现了一个程序员的技术水平、技术深度、经验等等。

那么在我们解决BUG的过程中,定位问题是非常重要的。有句话叫"发现问题是解决问题的一半。

本文讲述就快速定位异常(专指.NET程序异常)的方法。包括在本机定位异常,在客户环境定位.net程序异常,在客户环境定位SilverLight异常。

一:定位本机异常

在我们本机定位异常很容易。假设我们都是使用的的VisualStudio,那么只需要在调试->异常菜单中将Common Langeuage Runtime Exception(CLR异常)勾选。如下图:

在上面的图片中可以发现有5种类型的异常,例如c++异常、win32异常等等。对于.NET程序来说我们只关注CLR异常。

接下来进行调试,当自己的程序代码中有异常的时候,VS就会自动定位到异常的位置。

我们可以看到异常的详细信息,并且可在调用堆栈窗口中看到 程序的堆栈信息。在堆栈信息中我们可以看到在哪个类、哪个函数中出的错,如下图:

调试程序有两种方式,一种是用VS直接启动程序,另一种是附加到进程。

附加到进程的时候,程序类型不要选错了,我使用的是.net4.0 所以程序类型选择的是 托管(4.0版)代码。

另外附加到进程有个快捷键是 Ctrl+Alt+P。

但是如果异常不是你的代码中抛出的,那么如何定位呢?

可以打开 调试 菜单下面的 选项和设置,将 启用"仅我的代码" 这一项取消勾选。那么别人代码中的异常就可以抛出了。

二:在客户环境定位.net程序异常:

我们的程序最后都会运行在客户的环境中,客户环境上不会有VS这样的开发工具,那么怎么办呢?

我们可以使用一个很小巧的命令行调试工具Mdbg.exe,这个工具是安装VS的时候附带安装的,仅能调试.net托管代码。

Mdbg.exe其实有很多功能,不过本文只讲它定位异常的功能,后续文章会讲使用Mdbg.exe单步调试的方法。

Mdbg.exe命令详细介绍可以 输入 h(help) 或者? 名来查看,也可以看下面的链接,

http://msdn.microsoft.com/zh-cn/ms229861(vs.80).aspx#

根据CLR版本的不用,Mdbg.exe也是有多个版本的。

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\Mdbg.exe用于调试

CLR2.0(对应net2.0,3.0,3.5)程序。

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\Mdbg.exe用于调试CLR4.0程序(对用.net4.0)。

另外Mdbg.exe有一个依赖DLL 叫做MdbgCore.dll。我们可以直接将相应版本的Mdbg.exe和MdbgCore.dll拷贝到客户机器上使用。

有安装VS的朋友可以拷贝我自己封装的一个安装包 http://xiazai.jb51.net/201506/other/U8DebugSetup.rar,这里面除了Mdbg.exe还有一些其他组件我们后面的文章会用到。

默认会安装在 C:\Program Files\U8Debug。

Mdbg.exe的使用方法很加简,双击打开它,然后输入 a(attach显示附加的进程),回车,这时会列表所有可以附加的进程。

PID 表示进程标识,

输入a 11940 附件到 ConsoleApplication2.ex示例程序。

这时程序会中断执行,我们在这个时机可以做一些设置。让程序在遇到异常时自动中断。

输入命令 ca (catch)查看当前调试器遇到哪些事件会中断。

可以看到 Exception对应的是Igonre all exception ,也就是忽略所有异常,发生异常时不会中断。

输入命令 ca ex 这样调试器遇到异常时就会中断了。

再次输入ca 命令会看到 Exception对应的值已经变为Stop on all exception了。这时遇到任何异常都会中断了。

输入命令 g 让程序继续执行。

当遇到异常时会自动中断到调试器,如下图:

入命令 w(where,程序运行到哪里了) 可以查看异常堆栈信息

三:在客户环境定位SilverLight异常

如果客户的silverlight应用服务器部署在外网,那么我们可以直接用浏览器访问该silverlight站点,然后用VS附加到浏览器进程来调试。

调试方法比调试普通.net程序一样。

但是如果,客户的Silverlight服务器是部署在内网,那么你只能在客户机器上调试了。

并且Mdbg.exe也帮不了你了,它不能调试Silverlight程序。

我们还有另一个著名的调试工具Windbg。体积大概有不到20M,很容易安装到客户机,安装包大家可以到网上自己下载。windbg分为32位和64位两个版本,

调试32位的程序请使用32位windbg,反之则要使用64位的windbg,具体为什么我们不用深究,记住了就可以了。

相比Mdbg.exe的小巧实用,Windbg显然强大的多,但是使用起来也复杂一些。

Windbg其实可以调试很多种类型的程序,例如普通.NET程序,c++等。但是本文只讲解使用windbg定位异常的方法。

首先我们使用IE浏览器打开silverlight应用程序,然后打开windbg附件到IE进程来调试。附加进程的方式可以通过File菜单下的Attach to a process或者使用F6快捷键。

附件进程后 程序会中断到调试器,这个时候我们需要做两个设置。

一个是 设置程序发生异常时让其中断到调试器,设置方法是打开debug菜单下的Event Filter,将CLR异常设置其为enable。

另外需要加载调试器扩展,使用过windbg的朋友都知道调试.net程序需要加载一个调试器扩展sos.dll。这个sos.dll也有一个Silverlight版本的。

位置在silverlight的安装目录 C:\Program Files (x86)\Microsoft Silverlight\5.1.10411.0\sos.dll。

我们再command窗口中输入 .load C:\Program Files (x86)\Microsoft Silverlight\5.1.10411.0\sos.dll 来加载它。

之后输入命令 g 来回复程序的执行。当发生异常时就会中断到调试器中。

发生异常是我们可以使用!pe(print exception) 来查看异常信息。如下图:

如果想查看堆栈信息的话可以输入命令 !clrstack

.NET程序调试技巧(一):快速定位异常的一些方法的更多相关文章

  1. .net程序调试一:快速定位异常

    作为一个程序员,解BUG是我们工作中常做的工作,甚至可以说解决问题能力是一个人工作能力的重要体现.因为这体现了一个程序员的技术水平.技术深度.经验等等. 那么在我们解决BUG的过程中,定位问题是非常重 ...

  2. MapReducer程序调试技巧

    写过程序分布式代码的人都知道,分布式的程序是比较难以调试的,但是也不是不可以调试,对于Hadoop分布式集群来说,在其上面运行的是mapreduce程序,因此,有时候写好了mapreduce程序之后, ...

  3. WinDBG快速定位异常位置

    在WinDBG中通过搜索内存中保存的CONTEXT结构来定位发生的异常信息,再通过WinDBG命令.cxr显示对应的调用堆栈信息.   .foreach ( place { s-[1]d 0 L?FF ...

  4. js程序调试技巧

    1.No "Access-Control-Allow-origin" 解决方案:这是API参数没有穿对的跨域错误,修改API(ajax请求路径)以保证其参数传递正确即可: 2.lo ...

  5. Android 程序调试技巧汇总

    1.Android Studio 引入一个项目作为library https://www.cnblogs.com/lixiangyang521/p/7453322.html 2.Android Stu ...

  6. ollydbg快速定位方便调试

    在ollydbg调试的时候,会看到大量的汇编代码(远多于源代码),代码中有大量的函数嵌套调用,调试起来周期很长,难度比较大. 所以我们希望能快速定位到代码,以下是快速定位的四种方法: 1.Goto命令 ...

  7. 痞子衡嵌入式:快速定位i.MXRT600板级设计ISP[2:0]启动模式引脚上电时序问题的方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是一种快速定位i.MXRT600板级设计ISP[2-0]启动模式引脚上电时序问题的方法. 我们知道恩智浦i.MXRT600是主打音频市场的 ...

  8. Java 集合快速失败异常

    快速失败 在JDK中,查看集合有很多关于快速失败的描述: 注意,此实现不是同步的.如果多个线程同时访问一个哈希映射,而其中至少一个线程从结构上修改了该映射,则它必须 保持外部同步.(结构上的修改是指添 ...

  9. 调试技巧 —— 如何利用windbg + dump + map分析程序异常

    调试技巧 —— 如何利用windbg + dump + map分析程序异常 逗比汪星人2011-09-04上传   调试技巧 —— 如何利用windbg + dump + map分析程序异常 http ...

随机推荐

  1. Java基础——线程总结

    Java基础--线程总结 一.线程是什么? 线程:一个程序里不同的运行路径. 二.怎样创建线程? 两种方法创建线程: 第一种 (1)定义详细功能类实现Runnable接口,能够多次调用而实现数据共享 ...

  2. Drupal的system_list()函数解析

    system_list()函数的目的是根据传入的资源类型,返回一个数组列表: function system_list($type) { ... ... } 参数$type支持下面三种类型: boot ...

  3. Docker构建nginx的nginx-rtmp-module视频服务器镜像

    文章地址:https://www.cnblogs.com/linyilong3/p/5862595.html GitHub nginx-rtmp-module 及配置 Dockerfile构建配置: ...

  4. SSL and SSL Certificates Explained

    Secure Sockets Layer (SSL) and Transport Layer security (TLS ) are protocols that provide secure com ...

  5. oracle 复杂的查找用法

    [第一题]: 找到员工表中工资最高的前三名,要求按如下格式输出(第一步部分):以及oracle查询结果指定分页显示的方法(第二部分). ——涉及Top-N分析问题. 一般不在子查询中使用order b ...

  6. Java 继承、多态与类的复用

    摘要: 本文结合Java的类的复用对面向对象两大特征继承和多态进行了全面的介绍. 首先,我们介绍了继承的实质和意义,并探讨了继承,组合和代理在类的复用方面的异同.紧接着,我们依据继承引入了多态.介绍了 ...

  7. DataURL与File,Blob,canvas对象之间的互相转换的Javascript (未完)

    canvas转换为dataURL (从canvas获取dataURL) var dataurl = canvas.toDataURL('image/png'); var dataurl2 = canv ...

  8. mysql主从复制之mysql-proxy实现读写分离

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://lansgg.blog.51cto.com/5675165/1242674 本文系 ...

  9. Cocos2d-x 3.1.1 Lua演示样例 ActionsProgressTest(进度条)

    Cocos2d-x 3.1.1 Lua演示样例 ActionsProgressTest(进度条) 本篇博客介绍Cocos2d-x中的进度条动画,进度条涉及以下几个重要的类和方法,笔者来给大家具体解说一 ...

  10. Javascript实现真实字符串剩余字数提示

    //文本框剩余字数提示(字符大小) function textLimitCheckSj(thisArea, maxLength, SpanId) { var str = thisArea.value; ...