很多.net 程序员不知道又非常重要的 .net高级调试技巧.调试别人的dll方法内的变量

事情是这样的, 最近需要开发Orcale的数据库.
于是使用了EF 加上 Oracle.ManagedDataAccess.Client

这个Oracle.ManagedDataAccess 很好用, 不需要orcale 客户端就能用.
但是这个类库有个地方不是非常好用. 数据读取出了问题,它的提示非常非常让人气愤. 啥调试信息都没有..只有一个提示 “类型转换异常”.
大家经常遇到的. InvalidCastException
异常就异常呗, 问题是查找问题的信息太少了.
我不知道是哪条数据导致的这个问题.
如果有一万条数据. 其中某一条出错了. 我不是要崩溃了??
而且还不知道是哪个字段列出了问题…

具体是如何解决这个问题的? 咱们再细细谈来. 里面可多道道了…
准备好板凳哈..学会了, 你就不怕一些莫名其妙的异常了. 自己动手找问题点…百度什么的都是新手用的了…

首先出错了报异常, 肯定要捕获异常.
异常信息里面的StackTrace 非常详细的记录了出错的具体函数.

从图上可以看出.
在 Oracle.ManagedDataAccess.Client.OracleDataReader.GetString(Int32 i)
这个方法中因为读取第i个数据出错了.并且是转换为string.

Oracle.ManagedDataAccess 并没有公布源代码, 我们也不知道里面做了什么事情.
好吧,搬出.Net Reflector 先看看这个函数里面的代码是怎么写.

后来我反编译了.Oracle.ManagedDataAccess的源代码. 一看. 果然有2个InvalidCastException 第一个是有具体信息的.. 但是第二个就是光溜溜的InvalidCastException 了. 我猜应该是第二个InvalidCastException了.

好吧,到现在为止. 我们也大概的知道了GetString(i)这个函数里面做了什么事情. 有几种情况会出这个异常..
好吧, 到这里有些大神估计就不会再调试了. 根据代码也能猜出来是那里的问题..

但是这个地方.我想知道是哪个列出了问题? internalType 在出错的时候是什么类型?
传入的参数 i 又是多少?

下面本文的主题关键来了… 如何知道这个方法的内部变量的值?
我曾经相关n多个方法, 其中包括继承重载,dll反编译重写, Trace取信息等等.方法.
结果都无法取到这个内部变量的值.再多种方法无果的情况下. 我把眼光转向了vs调试工具. 按道理说. vs调试时能取到我的变量的值,也自然能取到别人变量的值. 嗯….

如果你的代码是像我下面这样写的. 那么你的代码出错是肯定不能停止在下面的第2个箭头处.

正常应该是直接跳进第1个箭头的地方了.
好吧,本文的第一个重点. 要修改你的vs配置. vs的默认配置是不会像我的那样停止的.
具体配置是.

第一点. 源代码不可用时显示反汇编.. 这个是为什么要启用呢? 如果不启用你就无法调试内部变量了.
第二点. 如果启用了 仅我的代码 那么别人的代码也不会调试的.
另外插一句. 里面的两个三角形地方如果勾上了. 你就可以调试.net源代码了. 只是第一次调试要下载pdb符号文件比较慢. 所以我这里就去掉了.

好吧,上面两点设置好以后还有非常重要的第三点.

第三点.

这个地方,查找到你要处理的异常….
勾上它, 勾上以后, 只要出现这种异常,程序立马停止. 进入中断状态. 而不会跑到你的catch 中…
为啥不能跑到你的catch中? 如果进入到你的catch以后. 那么很不幸. 你就无法调试具体出错函数的内部变量了. 已经被回收了..

所以这里也很重要.

OK到这里, 我们已经把设置都弄好了.
下面我们来试一下.如何取得变量信息. 里面还有点技巧哦..
程序跑起来, 直到出错…

上图已经比较明确了. 调试时的2个比较重要的窗口, 一个是调用堆栈,另外一个是局部变量. 这个局部变量会自动显示当前调用层的局部变量… 注意是当前调用层哦.
而且这个当前调用层可以改变的. 如何改变? 双击”调用堆栈” 的函数就可以改变当前的调用层了.
那么,我们来看一下. 在Oracle.ManagedDataAccess.Client.OracleDataReader.GetString(Int32 i)这个函数里面出错时的i 的数值是多少?

到这里, 基本上已经能解决绝大多数问题了…
但是有的时候我们还想知道其它的变量怎么办?
例如源代码里面的. internalType . 我想知道它是什么类型…
补个源代码的图,方便大家参考.

这个要借助 vs提供的另外一个工具. 监视器.

好啦,到此结束..
有了这个工具, 还有什么问题调试不出来?

要是.net能提供 捕捉监视的变量的dll 功能就好了.
方便程序员自动捕捉内容和变量值. 直接远程就能诊断程序了.
————————————————
版权声明:本文为CSDN博主「走错路的程序员」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/phker/article/details/78570073

原文地址:https://www.cnblogs.com/xtjatswc/p/11792816.html

时间: 2024-10-11 21:49:13

很多.net 程序员不知道又非常重要的 .net高级调试技巧.调试别人的dll方法内的变量的相关文章

为什么很多Java程序员都转行做大数据了?

如今大数据发展的越来越成熟.各大企业纷纷成立大数据部门.尤其BAT等一线互联网公司每天处理的数据量都是TB级别.大数据部门已成为这些企业的核心部门,数据已成为企业最核心的资产. 但是大数据人才缺口巨大,据统计目前全国的大数据人才仅46万,未来3-5年内大数据人才的缺口将高达150万. 因此大数据工程师薪资也比其他职位高出不少.以北京为例.1-3年的大数据工程师平均年薪30-50万,3-5年经验的大数据工程师年薪在50-80万.想学习的同学欢迎加入大数据学习扣群:458345782,有大量干货(零

程序员在“金字塔”的背景下,如何做到比别人更具有竞争力?

工作了挺久,发现有个挺有意思的现象,从程序员.高级程序员,到现在挂着架构师.专家之类的头衔,伴随着技术和能力的提高,想不明白的事情反而越来越多了.这些疑问有些来自于跟小伙伴交流,有些是我的自问自答,有些到现在也想不清楚,这篇文章就来写一写这些问题. 如何更高效的学习? 很多新人程序员一开始在学习上找不到方向,但我想在渡过了一段时间的新手期之后这类问题大多都会变得不再那么明显,工作的方向也会逐渐变得清晰起来. 但是没过多久,能了解到的资料就开始超过每天学习的能力,像是买了没看的书.收藏没读的贴.m

好程序员web前端学习路线分享jQuery学习技巧

好程序员web前端学习路线分享jQuery学习技巧,jQuery在web前端学习中是一个必不可少的内容,很多小伙伴都在学习这阶段的时候遇到问题,今天我们就来聊一下jQuery,让我们一起来看一看吧! 1.关于页面元素的引用 通过jquery的$引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用dom定义的方法. 2.jQuery对象与dom对象的转换 只有jquery对象才能使用jquery定义的方

30K程序员的简述:如何成为高级开发人员

这篇文章适用于所有在这个行业已经有了几年时间后想要在职业生涯中取得突破的开发人员,编程人员和程序员(或者你可能刚刚开始,但希望你能看到你的路径).本文适合那些有着简单愿望的人:你想成为一名高级开发人员,并希望在你的领域中脱颖而出.在阅读完这篇文章后,您将获得一组具有最佳资源列表的路径,供您升级并成为高级开发人员. 免责声明:与生活中的所有事物一样,您可以随时设定自己的路径.尽管这不是唯一的方法,但是这是我在自己的职业生涯中发现的一种方法,并且通过我在过去一年中与我认为是社区中资深和受人尊敬的程序

30KiOS程序员的简述:如何成为高级开发人员

前言: 本篇文章适用于所有在这个行业已经有了几年时间后想要在职业生涯中取得突破的开发人员,编程人员和程序员(或者你可能刚刚开始,但希望你能看到你的路径).本文适合那些有着简单愿望的人:你想成为一名高级开发人员,并希望在你的领域中脱颖而出.在阅读完这篇文章后,您将获得一组具有最佳资源列表的路径,供您升级并成为高级开发人员. 免责声明:与生活中的所有事物一样,您可以随时设定自己的路径.尽管这不是唯一的方法,但是这是我在自己的职业生涯中发现的一种方法,并且通过我在过去一年中与我认为是社区中资深和受人尊

8个对程序员来说有用的jQuery小贴士和技巧

1) 禁用鼠标右键单击 jQuery程序员可以使用此代码在网页上禁用鼠标右键点击. 1 2 3 4 5 6 7 8 9 10 $(document).ready(function() {     //catch the right-click context menu     $(document).bind("contextmenu",function(e) {                         //warning prompt - optional         a

黑马程序员_IOS开发_Objective-C学习笔记_分析和调试自己的一个黑马基础测试题程序

1.程序 1.1程序介绍 从键盘输入6个字符串(仅仅包含英文字母和数字),对着6个字符串从小到大排列并输出结果.(C语言) 1.2程序设计分析 这个是我在基础测试题目环节从黑马报名系统里面下得题目. 初看题目,觉得此题不难,无非是: *建立一个字符串的数组 *然后在一个循环6次的循环体里面循环输入6次,然后再把输入的字符串放到字符串数组里面 *然后建立一个长度数组来统计相对应的字符串的长度 *最后对长度数组中的元素按大小来排序(注意:对长度数组中的元素排序的时候,同时要对字符串数组进行一样的操作

70%的Java程序员不知道为啥 ConcurrentHashMap 读操作不需要加锁?

作者:上帝爱吃苹果 目录 1.ConcurrentHashMap的简介2.get操作源码3.volatile登场4.是加在数组上的volatile吗?5.用volatile修饰的Node6.总结 我们知道,ConcurrentHashmap(1.8)这个并发集合框架是线程安全的,当你看到源码的get操作时,会发现get操作全程是没有加任何锁的,这也是这篇博文讨论的问题--为什么它不需要加锁呢? ConcurrentHashMap的简介我想有基础的同学知道在jdk1.7中是采用Segment +

黑马程序员-OC类的本质,深入探讨,load方法和initialize方法

1:类的本质:类也是一种类,可以叫做类类,类对象,类类型: 2:类和对象在内存中分配问题(注意区分类的对象和类对象的概念) 类对象在内存中只有一份,且只加载一次,类对象中存放了类中定义的方法: 而成员变量和isa指针,存放在了类的对象中;isa指针指向了类对象:如图: 3:类本身也是对象,是class类型的对象: // 以person为例 Person *p1 = [[Person alloc] init]; Person *p1 = [[Person alloc] init]; // 获取类对