1. 程式人生 > 實用技巧 >Visual Studio除錯之符號檔案

Visual Studio除錯之符號檔案

除錯符號檔案為偵錯程式提供了從二進位制機器程式碼地址到原始碼文字檔案程式碼行的對映.因此有了符號檔案,我們才能:

1.設定斷點,因為偵錯程式需要符號檔案提供的對映關係,將原始碼行的行號轉換成對應的機器程式碼的地址。

2.檢視程式堆疊,簡單地說,就是偵錯程式使用對映關係將堆疊裡面的地址轉換成包含這個地址的函式名。

3.檢視變數的值,對於機器來說,所有的變數都只是一個記憶體地址,程式在讀取變數值的時候,只不過按照變數所屬的型別來讀取指定大小的記憶體而已。

4.甚至呼叫程式的一些函式,比如原生(Native)程式,經過編譯以後,在程式裡面實際上只變成了一段機器程式碼。我們在立即窗口裡面呼叫一個C++函式的時候,偵錯程式需要將函式名翻譯成對應的機器程式碼的起始地址,當然還要遵循一定的函式呼叫規則才能呼叫這個函式。

我們一個一個地看符號檔案的功能:

檢視程式堆疊

Visual Studio以原生程式(Native)除錯模式附加到一個已開啟的記事本程式上(附:因為我的系統都是英文版,所以中文選單都是對著英語直接翻譯的,有的會翻譯的不準確,所以我會把英文的命令附在後面),然後中斷記事本程序的執行通過點選VS選單裡面的“除錯(Debug)”-“全部中斷(Break All)”。

下面是具體的將VS附加到記事本程序的操作(不好意思,錄製的視訊太大,不知道怎麼傳)。

1.點選Visual Studio裡面的“工具(Tools)”-“附加到程序……(Attach to Process …)”。

2.選擇notepad.exe

,當然你要保證“附加到… (Attach To…)文字框裡面列出的除錯型別是“原生程式(Native)”。

3.點選確定以後,將Visual Studio附加到剛剛開啟的記事本程序。

這個時候開啟堆疊(Stack)視窗,你應該會看到類似下面的結果:

上面的堆疊,我也看不懂(我的機器是64位的Windows 7,所以地址都是8個位元組的)。因此我們需要一些東西來幫我們把難理解的地址(鳥語)翻譯成有意義的文字,這個工作就是由符號檔案來完成的。

因為記事本是作業系統自帶的程式,我們當然沒有辦法自己生成它對應的符號檔案啦,但是幸運的是,微軟早就已經考慮到可能有一些人需要除錯Windows核心例如寫驅動程式的程式設計師,因此微軟公司已經將

Windows的一些符號檔案公開了,公開的地址在:

http://msdl.microsoft.com/download/symbols

Visual Studio裡使用的方法是:

1.點選選單欄裡面的“工具(Tools)”“選項(Options)”。

2.在“選項(Options)”對話方塊左邊的列表框裡面選擇“除錯(Debugging)”-“符號檔案(Symbols)”。

3.如果你的Visual StudioVisual Studio 2008 SP 1,那麼點選“從微軟的符號檔案伺服器上載入符號檔案(Load symbols from Microsoft symbols server)”就可以了。

4.如果是其他版本-當然是低一些的版本,在右側的“符號檔案路徑(Symbol file (.pdb) locations)”列表框裡面新增新的一行,將上面的連結輸入進去。

然後在“將符號檔案快取到這個資料夾(Cache symbols from symbol servers to this directory:)”文字框裡輸入你要快取從伺服器下載的符號檔案的資料夾路徑畢竟那個伺服器是在美國。如下圖所示:

5.點選“確定( OK)”

6.對於聽說英文沒有困難的朋友,可以直接參考下面的連結學習如何設定:

http://support.microsoft.com/kb/311503/zh-cn

等待一段很長的時間以後因為偵錯程式要一個個下載記事本程式所引用到的所有動態連結庫檔案的符號檔案,你應該可以看到類似下面的堆疊資訊:

這篇文章的描述裡面,我希望你能夠明白除錯符號檔案的重要性:

1.如果沒有除錯符號檔案,那麼就不能檢視堆疊這話好像有點多餘。但是很多時候,我們在分析驗屍除錯所儲存的記憶體檔案的時候,第一步要看檢查的就是,程式崩潰的時候,堆疊是什麼樣子的,如果沒有除錯符號檔案,那我們就什麼也做不了了。

2.那麼除錯符號檔案是如何生成的呢?除錯符號檔案是由編譯器生成的,因為編譯器負責將文字格式的原始碼檔案翻譯成二進位制的程式,所以二者之間的對映關係編譯再清楚不過了。每次重新編譯的時候,編譯器都會生成對應的除錯符號檔案。

生成除錯符號檔案的命令:

程式語言

編譯器

命令列引數

C#

csc.exe

/debug[:full]

C++/C

cl.exe

/Zi

或者

Link.exe/debug選項

3.例如一個客戶跟你抱怨程式不能工作,出現了嚴重的錯誤(Bug),但是他正在執行的是1.0版本的程式,而你們公司卻已經再開發2.0版本的程式了。由於原始碼一般都不會給客戶,這個時候如果能夠找到原始的1.0版本的原始碼重新編譯,然後安裝到客戶機重現一下固然是好,但是為什麼不直接儲存1.0版本的除錯符號檔案,在除錯的時候,直接讓偵錯程式自己去找原始碼呢?這裡涉及到符號檔案伺服器和原始碼檔案伺服器的合作問題,後面的文章裡可能會介紹到。

轉載於:https://blog.51cto.com/whatday/1382396