如何调试没有源码的.Net程序

摘要:
在中。网络开发过程中,我们经常使用一些没有源代码的第三方库。当代码出现问题时,如果我们怀疑它与库的内部实现有关,我们应该怎么做?首先,让我们介绍一下示例代码。以下代码相对简单。它的主要功能是从文本中读取每行数据。csv文件并在控制台上显示。下载dnSpy并根据目标程序是64位还是32位打开相应的dnSpy。此外,dnSpy可以附加到正在运行的进程,但由于JIT优化,此方法可能无法获得所需的信息。

在.Net开发过程中,经常会使用一些没有源码的第三方库,在代码出了问题时,如果怀疑跟该库的内部实现有关,我们该怎么办呢?首先,自然会想到反编译去看看代码或者联系作者,然而,有没有办法让我们在debug时进入这个第三方库,并看看里面在运行时到底发生了什么呢?本文就来介绍三种debug第三方库的办法,希望能够对你有所帮助。

先介绍一下我们的样例代码,下面这段代码比较简单,主要功能:从text.csv文件中读取每行数据并在控制台显示。其中用到的类CsvConfiguration,CsvReader,CsvDataReader来自第三方库CsvHelper,可以通过Nuget下载,这里假设我们想要调试CsvDataReader类的Read方法。完整的代码工程请参考:https://github.com/DerekLoveCC/Writings/tree/master/Article/DebugWithoutSourceCodeInDotNet/code

    internal class Program
    {
        private static void Main(string[] args)
        {
            using (var textReader = new StreamReader(@".	est.csv"))
            {
                var config = new CsvConfiguration(CultureInfo.InvariantCulture)
                {
                    HasHeaderRecord = false
                };
                var csvReader = new CsvReader(textReader, config);
                var csvDataReader = new CsvDataReader(csvReader);
                while (csvDataReader.Read())
                {
                    for (int i = 0; i < csvDataReader.FieldCount; i++)
                    {
                        Console.Write(csvDataReader.GetString(i) + " ");
                    }
                    Console.WriteLine(" ");
                }
            }

            Console.Read();
        }
    }

方法一 使用dnSpy

dnSpy构建在ILSpy的基础上,开源免费,不但可以反编译代码而且能够调试,关于dnSpy的更多信息请访问:https://github.com/0xd4d/dnSpy ,下面我们一起来看看具体操作。

  1. 下载dnSpy,并根据目标程序是64还是32位,打开对应的dnSpy。本例中由于目标程序是32位的,所以打开了32位的dnSpy
  2. 用dnSpy打开CsvHelper的dll,并找到CsvDataReader类的Read方法,点击左侧来设置调试断点,如下图所示:
    dnspsy set debug point
  3. 在菜单栏,选择调试->开始调试,或者F5打开要调试的exe,如下图所示,然后点击确定开始调试
    dnspy open exe
  4. 程序会自动在第二步中的断点处停下,接下来的调试工作跟在VS里基本一样了,包括快捷键也是一样的,如下图:
    dnspy debug

总结,dnSpy功能很强大,对于.net的系统库也是可以的,从此调试无忧。此外,dnSpy可以附加到已运行的进程上,但是由于JIT的优化,使得这种方式可能无法获得想要的信息。关于编译优化和运行时优化,咱们以后再聊。

方法二 使用dotPeek + Visual Studio

Visual Studio就无需介绍了,dotPeek是大名鼎鼎的JetBrains出品的免费工具,可以到:https://www.jetbrains.com/decompiler/ 下载。这种方法的基本思想就是把dotPeek作为VS的Symbol Server,下面是使用方法:

  1. 根据目标程序是64还是32位,打开对应的dotPeek,本例是32bit所以打开的是32位dotPeek
  2. 用dotPeek打开CsvHelper的dll,然后在工具栏里点击“Start Symbol Server”按钮开启Symbol Server,如下图:
    start symbol Server
    如果是第一次打开symbol server会弹出下面的配置框,请根据你的情况选择,笔者选择了“All Assemblies”,以后如果想修改,可以在Tools->Options->Symbol Server里修改
    dotpeek symbol server config
  3. 现在就可以配置VS了,在VS里通过Tools->Options打开Options配置窗口,在Debugging/General下,取消“Enable Just My Code”, 并选中“Suppress JIT optimization on module load”,如下图:
    dotpeek vs config
  4. 设置VS的Symbol Server,首先回到dotPeek,打开Tools->OptionsSymbol Server,拷贝一下地址,然后在Visual Studio的Tools->OptionsDebuggingSymbols, 添加一个新的地址,请查看下图:
    dotpeek get symbol server addr
    dotpeek vs config symbol server addr
  5. 现在,在VS里就可以正常地debug了,第一次由于需要生成和加载pdb文件,所以有可能慢点。笔者测试效果图如下:
    dotpeek test result

总结,这种方式的优点是能够使用熟悉的VS

方法三 Resharper

Resharper也是JetBrains的付费产品,使用也很方便,请查看下面步骤:

  1. 安装Resharper之后,Resharper会作为VS的Extension,首先确保Enable了Resharper:
    resharper license
  2. 首先用VS启动debug,打开Debug->Windows->Modules, 然后继续debug直到CsvHelper程序集加载
  3. 右键点击CsvHelper程序集,选择“Load Symbols with ReSharper Decompiler”,等symbol加载完之后,就可以正常debug了,可以通过F11进入Read方法的内部,下面是一些相关截图
    resharper load sysmbol

总结,这种方式可以使用VS,但是Resharper插件可能拖慢VS

Fintech技术汇

免责声明:文章转载自《如何调试没有源码的.Net程序》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇设计模式(9)---外观模式判断一个点是否在一个复杂多边形的内部下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

chromium浏览器开发系列第四篇:如何调试最新chromium源码

附上上几篇文章地址,方便大家查看: 下载源码 编译源码 目录结构 接二连三的事情,时间比较紧张,但是还是没有把这个系列的文章丢掉,因为这也是对自己知识的总结吧。提倡大家多写写,以后再看的时候会有种莫名的小激动。 上周写的是chromium的目录结构,好像大家不太感兴趣,在我看来这部分很重要。开头有链接地址,大家想看可以再看看。 从源码下载到编译,到目录结构...

mtd-util

1.1.4.1.mtd-util简介 mtd-util,即mtd的utilities,是mtd相关的很多工具的总称,包括常用的mtdinfo,flash_erase, flash_eraseall, nanddump, nandwrite等,每一个工具,基本上都对应着一个同文件名的C文件。 mtd-util,由mtd官方维护更新,开发这一套工具,目的是为了...

ubuntu13.04下载android4.0.1源码过程

最初我参考的是老罗的博客http://blog.csdn.net/luoshengyang/article/details/6559955 进行下载安装的,但弄着弄着就发现不太对劲了。这里记录下详细过程: 1,我的前提是已经搭建好了Android开发环境,也即jdk已经安装好了,输入java -version来检查是否成功。搭建android开发环境可以...

chromium浏览器开发系列第三篇:chromium源码目录结构

上两篇介绍了下载源码和编译源码,这次主要介绍chromium的源码目录结构,我也是通过源码和官网结合来跟大家说,如果有说的不准确的,欢迎交流。 另外,官网的不一定准确,他们其实也很懒,所以最主要还是靠自己。官网只能作为一个参考。 Chromium结构相对两年前变化很大。目录结构依然很清晰,主要有三个部分(不包括其他的库):浏览器,渲染器,webkit。浏览...

ClickHouse源码笔记3:函数调用的向量化实现

分享一下笔者研读ClickHouse源码时分析函数调用的实现,重点在于分析Clickhouse查询层实现的接口,以及Clickhouse是如何利用这些接口更好的实现向量化的。本文的源码分析基于ClickHouse v19.16.2.2的版本。 1.举个栗子 下面是一个简单的SQL语句SELECT a, abs(b) FROM test 这里调用一个abs的...

理解Android编译命令(转)

一、引言 关于Android Build系统,这个话题很早就打算整理下,迟迟没有下笔,决定跟大家分享下。先看下面几条指令,相信编译过Android源码的人都再熟悉不过的。 source setenv.sh lunch make -j12 记得最初刚接触Android时,同事告诉我用上面的指令就可以编译Android源码,指令虽短但过几天就记不全或者忘记...