我在前些陣子開了好幾個梯次的 Visual Studio 2015 開發與偵錯技巧 課程,課程中有提到我們在對 .NET 應用程式進行偵錯時,有個最重要的 pdb 符號檔必須隨著專案一起發行,才能夠在執行的過程中得知完整的偵錯資訊,否則不但無法在程式執行過程中載入偵錯工具 (Debugger),連例外狀況發生時也將無法得知錯誤發生的呼叫堆疊與程式碼行數。但我們在 Visual Studio 常用的 Web 單鍵發行功能,預設設定是採用 Release 方案組態進行發布,而且預設還會將所有 pdb 符號檔排除,也就是透過 Web 單鍵發行的網站,將完全不會有相對應的 pdb 檔案,本篇文章告訴該如何設定。
我們先來看看 Web 單鍵發行的流程:
1. 先啟用 Web 單鍵發行 工具列

2. 接著新增自訂設定檔

3. 隨便設定一組發行設定檔名稱

4. 我們選擇最簡單的「檔案系統」發行方法,將網站發布到本機特定目錄即可


5. 在這個步驟你可以選擇用 Debug 或 Release 組態進行發布,預設為 Release 組態。
這裡請注意:
- 選用 Release 組態發行,預設不會輸出任何 pdb 偵錯符號檔!
- 選用 Debug 組態發行,專案就會預設輸出 pdb 偵錯符號檔。

6. 最後我們直接發行網站到指定資料夾

這裡值得一提的部分是,剛剛所做的設定,最終會建立一個 *.pubxml 檔案在 Web 應用程式專案的 Properties\PublishProfiles 目錄下,你在 Web 單鍵發行的設定中的每個設定檔,都會在這個資料夾看見相對應的 *.pubxml 檔案。

我們在發行完畢之後,從發行後的 bin\ 目錄下去查看,你會發現這裡並沒有任何 *.pdb 檔案。
這也意味著這樣的網站在執行過程中,如果遇到例外狀況,你將無法收錄完整的偵錯資訊,這樣的網站即便你安裝了 Elmah 也無法得知完整的程式碼行數與堆疊追蹤資訊!

你可以看的出來,在我們剛剛的設定過程中,並沒有任何可以讓我們設定是否發佈 pdb 檔的地方,事實上這個設定是有的,只是被藏在「專案屬性」的【封裝/發行 Web】頁籤中而已。
以下是調整設定的步驟說明:
1. 開啟專案屬性視窗

2. 當你切換到【封裝/發行 Web】頁籤之後,因為不同的方案組態可以保存不同的專案屬性設定,所以請記得先切換「組態」到 Release 才能針對 Release 發行時進行微調!
如下圖標號 3 的地方,就是每個 Web 應用程式專案範本預設設定之一,也就是在 Release 模式下預設會排除產生的偵錯符號,也就是 pdb 檔在發行的時候預設會被移除掉。
你只要取消勾選【排除產生的偵錯符號】這個核取項目就可以解決找不到 pdb 檔的問題了!

※ 注意事項
我們在執行 Web 單鍵發行時,在【設定】頁籤中有個「發行前先刪除現有的所有檔案」選項,預設並沒有勾選。
如果你有勾選的話,可能要注意一下,如果你的發行方式會直接將檔案發佈到 IIS 的網站目錄,他會將你站台上所有檔案刪除,然後重新佈署網站,一不小心可能連 App_Data 或其他由使用者上傳的檔案都給一併刪除了!

如果你沒有勾選的話,其實也需要注意可能會有無效檔案殘留在資料夾中的問題!
舉個例子來說,如果你先用 Debug 組態發行網站到 IIS 站台下,此時網站是有 pdb 偵錯符號檔的。當你改天用 Release 組態發行檔案時,由於你設定他不會刪除現有的檔案,而本次發行又不會發行 pdb 檔,因此在 bin 目錄下就會同時出現 *.dll 與 *.pdb 檔,很有可能會讓你誤以為你是有 pdb 檔案的。
我曾經在課堂上提過,.NET 應用程式在建置的時候,如果會同時產生 dll 與 pdb 檔案,這兩個檔案同時會被寫入一個 GUID 序號,而且每次編譯都會不一樣,因此每次建置所產生的 pdb 檔案都會與該次建置時的 dll 檔做好匹配,只要兩個檔案內的 GUID 不符合,就會完全沒有作用。
所以,即便你現在改用 Release 組態發行網站,而 bin\ 目錄下也有 pdb 檔案,不代表這個 pdb 可以使用,因為這個 pdb 檔案無法跟 dll 檔案進行匹配,所以你的 .NET 應用程式在執行的時候,將如同沒有 pdb 檔案一樣,也就是發生例外的時候不會有完整的偵錯資訊可參考!
相關連結