2011-03-28 50 views
217

爲什麼Visual Studio 2005在發佈時進行編譯時會生成.pdb文件?我不會調試發佈版本,爲什麼它們會生成?版本生成.pdb文件,爲什麼?

+14

爲什麼要在釋放中生成pdb?所以當一個崩潰報告來自野外時,你有信息來調試它。另一個價值是客戶可以在原作者不會的時候進行調試。 – 2012-02-12 18:14:15

+0

@IanBoyd:該評論的第二句暗示你部署了PDB。絕大多數情況下這是不可取的。 – IInspectable 2017-06-09 11:52:09

+2

@IInspectable或[可取的](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/microsoft-public-symbols) – 2017-06-09 21:03:34

回答

361

因爲沒有PDB文件,不可能通過除地址級調試之外的其他任何東西來調試「發佈」版本。優化確實會在您的代碼中執行一些操作,如果發生錯誤(例如引發異常),很難找到罪魁禍首。即使設置斷點也是非常困難的,因爲源代碼行不能與生成的彙編代碼一一對應(或者甚至以相同的順序)。 PDB文件可以幫助您和調試器解決問題,從而使驗屍調試更加容易。

您指出,如果您的軟件已準備好發佈,那麼您應該已經完成​​了您的所有調試。雖然這是事實,但也有幾個重要的點要牢記:

  1. 你應該測試和調試應用程序(你釋放它之前)使用「釋放」的構建。這是因爲打開優化(它們在「調試」配置下被默認禁用)有時會導致出現細微的錯誤,否則您將無法捕獲。當你正在做這個調試時,你會需要PDB符號。

  2. 客戶經常報告邊緣情況和只在「理想」條件下出現的錯誤。這些都是在實驗室中幾乎不可能複製的東西,因爲它們依賴於該用戶機器的某些令人毛骨悚然的配置。如果他們是特別有用的客戶,他們會報告拋出的異常併爲您提供堆棧跟蹤。或者他們甚至會讓你借用他們的機器來遠程調試你的軟件。無論哪種情況,您都需要PDB文件來幫助您。

  3. 性能分析應該總是在啓用優化的「發佈」版本上完成。而且,PDB文件再次派上用場,因爲它們允許將被彙編的彙編指令映射回您實際編寫的源代碼。

你不能回去生成PDB文件編譯後*如果您在構建過程中沒有創建它們,那麼您就失去了機會。它不會傷害任何東西來創建它們。如果你不想分發它們,你可以簡單地從你的二進制文件中省略它們。但是如果你以後決定你想要他們,那你的運氣不好。更好的是始終生成並存檔副本,以防萬一您需要它們。

如果你真的想關閉它們,那永遠是一種選擇。在您的項目的「屬性」窗口中,將「調試信息」選項設置爲「無」,以進行要更改的任何配置。

但是,請注意,默認情況下,「調試」和「釋放」配置使用不同的設置來發出調試信息。你會想保持這個設置。調試版本的「調試信息」選項設置爲「完整」,這意味着除了PDB文件之外,調試符號信息也會嵌入到程序集中。您還可以獲得支持諸如編輯和繼續等很酷功能的符號。在發佈模式中,選擇「僅限pdb」選項,就像它聽起來一樣,它只包含PDB文件,而不會影響程序集的內容。所以它不像/bin目錄中存在或不存在PDB文件那麼簡單。但假設您使用「僅限pdb」選項,則PDB文件的存在不會影響代碼的運行時性能。

*作爲Marc Sherman points out in a comment,只要你的源代碼並沒有改變(或者你可以從一個版本控制系統原碼),可以重建,並生成匹配的PDB文件。至少,通常。這在大多數情況下運作良好,但the compiler is not guaranteed to generate identical binaries each time you compile the same code,所以可能會有細微的差異。更糟糕的是,如果您在此期間對工具鏈進行了升級(比如爲Visual Studio應用Service Pack),則PDB更不可能匹配。爲了保證可靠地生成PDB文件,您不僅需要存檔版本控制系統中的源代碼,還需要存檔整個構建工具鏈的二進制文件,以確保您可以精確地重新創建您的配置建立環境。不用說,簡單地創建和存檔PDB文件就容易多了。

+18

「編譯後無法生成PDB文件。」 - 如果你的源代碼沒有改變,那麼你可以在事實之後重新生成一個可用的PDB。默認情況下,windbg不會加載這個PDB,但你可以通過指定/ i選項像''reload/i foo.dll'來加載它。即使在釋放foo.dll後創建了foo.pdb,也會加載foo.pdb。 – 2012-11-29 14:20:06

+0

我注意到每個新的編譯都有不同的哈希摘要,因此即使在相同的環境中,每個編譯也會有輕微的差異。 PDB的地址能否不隨方差而改變,因此需要保持PDB的構建?只是把它看作一個想法,因爲我不太瞭解PDB是如何工作的或者爲什麼在構建之間哈希會發生變化。 – thebunnyrules 2017-01-31 23:27:24

+1

@在腳註中,我鏈接到[一篇文章](https://ericlippert.com/2012/05/31/past-performance-is-no-guarantee-of-future-results/),解釋*「設計的C#編譯器從不會生成相同的二進制文件,C#編譯器每次運行它時,都會在每個程序集中嵌入一個新生成的GUID,從而確保沒有兩個程序集的位對位相同。「*這就解釋了爲什麼它具有不同的散列,因此具有不同的PDB文件。這可以用十六進制編輯器修復,但不方便用戶使用。並且也在這個答案的範圍之外。 – 2017-02-01 05:19:15

71

PDB可以爲Release以及Debug生成。這是設置爲(在VS2010但在VS2005必須是相似的):

ProjectPropertiesBuildAdvancedDebug Info

它只是更改爲None

+1

但是,你爲什麼要這樣做?如果您的軟件已準備好發佈,那麼您應該已經完成​​了您的所有調試 – 2011-03-28 09:40:36

+4

因爲您可以調試生產問題。一旦我們必須這樣做。 – Aliostad 2011-03-28 09:44:35

+1

你如何做到這一點?是否有某種工具可以讓您遠程調試? – 2011-03-28 09:45:54

7

爲什麼你確定你不會調試發佈版本?有時(希望很少發生,但發生)您可能會收到客戶提供的缺陷報告,由於某種原因(不同的時序,小的不同行爲或其他),在調試版本中無法重現。如果這個問題在發佈版本中似乎是可重現的,那麼您會很高興擁有匹配的pdb。

+5

@ m.edmondson使用RDP,Webex等訪問遠程機器,並在那裏安裝windbg。設置你的符號路徑和巴姆,你是金! – 2012-11-29 14:14:06

+0

指向更詳細指南的鏈接會更有幫助。這種單線的方法可能會導致人們(比如我)走錯路。例如,大多數.NET開發人員對Windbg一無所知。 – Nuzzolilo 2014-09-12 18:54:52

+1

@ m.edmondson - 某些版本的Visual Studio有能力執行遠程調試。從遠程機器上的「附加處理」調試菜單。 – Matt 2014-11-08 16:01:07

8

沒有.pdb文件,幾乎不可能逐步完成生產代碼;你必須依賴其他昂貴且耗時的工具。 我知道你可以使用tracing或windbg作爲例子,但這取決於你想要達到的目標。 在某些情況下,您只是想通過使用生產數據來觀察特定行爲的遠程代碼(無錯誤或異常),這就是.pdb文件派上用場的地方。沒有他們在該代碼上運行調試器是不可能的。

2

.PDB文件是「程序數據庫」的簡稱。它包含調試器的調試點信息以及使用或引用的資源。它在我們構建爲調試模式時生成。它允許應用程序在運行時進行調試。

調試模式下,.PDB文件大小增加。它在我們測試我們的應用程序時使用。

發佈或部署時不需要此文件。 pdb文件的好文章。

http://www.codeproject.com/Articles/37456/How-To-Inspect-the-Content-of-a-Program-Database-P

+1

「沒有需要此文件時發佈或部署「,除非有人在發佈的版本中遇到崩潰,並且從它們獲得的崩潰報告不包含可用的堆棧跟蹤......那麼您希望您將它包含在內。 – Nyerguds 2017-01-02 10:44:01

4

此外,您還可以使用崩潰轉儲來調試軟件。客戶將其發送給您,然後您可以使用它來確定源代碼的確切版本 - 並且Visual Studio甚至會使用故障轉儲來提供正確的調試符號集(以及源代碼,如果您設置正確的話)。請參閱微軟的documentation on Symbol Stores

1

在多項目解決方案中,您通常希望擁有一個根本不生成PDB或XML文件的配置。我不認爲將每個項目的Debug Info屬性更改爲none,而是認爲添加僅適用於特定配置的構建後事件會更方便。

不幸的是,Visual Studio不允許您爲不同的配置指定不同的構建後事件。所以,我決定手動做到這一點,通過編輯csproj文件的啓動項目並添加以下(而不是任何現有PostBuildEvent標籤):

<PropertyGroup Condition="'$(Configuration)' == 'Publish'"> 
    <PostBuildEvent> 
     del *.pdb 
     del *.xml 
    </PostBuildEvent> 
    </PropertyGroup> 

不幸的是,這會讓後生成事件文本框爲空,並把其中的任何內容都可能產生不可預知的結果。

+2

這將刪除所有'* .xml'文件,請注意。 – 2017-04-03 07:17:10

0

調試符號(.pdb)和XML文檔( .xml)文件佔總大小的很大比例,不應該是常規部署軟件包的一部分。 但應該可以在需要時訪問它們。

一種可能的方法:在TFS構建過程結束時,將它們移動到單獨的工件上。

相關問題