1. 程式人生 > 實用技巧 >如何除錯沒有原始碼的.Net程式

如何除錯沒有原始碼的.Net程式

在.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(@".\test.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方法,點選左側來設定除錯斷點,如下圖所示:
  3. 在選單欄,選擇除錯->開始除錯,或者F5開啟要除錯的exe,如下圖所示,然後點選確定開始除錯
  4. 程式會自動在第二步中的斷點處停下,接下來的除錯工作跟在VS裡基本一樣了,包括快捷鍵也是一樣的,如下圖:

總結,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,如下圖:

    如果是第一次開啟symbol server會彈出下面的配置框,請根據你的情況選擇,筆者選擇了“All Assemblies”,以後如果想修改,可以在Tools->Options->Symbol Server裡修改
  3. 現在就可以配置VS了,在VS裡通過Tools->Options開啟Options配置視窗,在Debugging/General下,取消“Enable Just My Code”, 並選中“Suppress JIT optimization on module load”,如下圖:
  4. 設定VS的Symbol Server,首先回到dotPeek,開啟Tools->Options\Symbol Server,拷貝一下地址,然後在Visual Studio的Tools->Options\Debugging\Symbols, 新增一個新的地址,請檢視下圖:

  5. 現在,在VS裡就可以正常地debug了,第一次由於需要生成和載入pdb檔案,所以有可能慢點。筆者測試效果圖如下:

總結,這種方式的優點是能夠使用熟悉的VS

方法三 Resharper

Resharper也是JetBrains的付費產品,使用也很方便,請檢視下面步驟:

  1. 安裝Resharper之後,Resharper會作為VS的Extension,首先確保Enable了Resharper:
  2. 首先用VS啟動debug,開啟Debug->Windows->Modules, 然後繼續debug直到CsvHelper程式集載入
  3. 右鍵點選CsvHelper程式集,選擇“Load Symbols with ReSharper Decompiler”,等symbol載入完之後,就可以正常debug了,可以通過F11進入Read方法的內部,下面是一些相關截圖

總結,這種方式可以使用VS,但是Resharper外掛可能拖慢VS