VS中调试时不能关联源代码问题
?
一、問題提出:
我們有時候調試程序的時候,會碰到一種問題,例如通過myclass.cs編譯后的程序,我們在調試的時候,卻發現即使我們有myclass.cs源文件,Visual Studio卻不能自動關聯,當你在堆棧窗口雙擊打開時候,會出現類似以下的界面:
(圖1)
?
提示沒有源代碼,有時候還會彈出對話框,讓你選擇源文件。尤其是在調試第三方代碼,或者是調試在其他機子上編譯的程序時候,會出現這種情況,那么問題在哪里呢?
?
二、VS中是怎樣查找源文件的?
要弄清楚這個問題,首先要理解pdb文件的作用,關于這個文件的知識,請見文后的《pdb文件知識》。
源文件和可執行模塊(exe or dll)是通過pdb文件進行關聯的。如下圖所示:
?
可執行模塊中保存有pdb文件的信息,pdb文件中保存有源文件的信息。
VS查找源文件的流程是這樣的:
?
1、根據可執行模塊中保存的pdb文件信息(guid,pdb文件名,age)查找加載pdb文件。
2、根據pdb中的源文件路徑查找源文件。如果源文件在路徑中不存在,則在“圖1”中的“Browse to find source”可以使用,點擊后會彈出文件打開對話框。如果pdb是public pdb文件,則沒有包含源文件信息,這時“圖1”中的“Browse to find source”變成灰色,不可使用。
?
?
三、解決問題的思路方法
有了這個流程概念后,我們就可以知道,如果無法關聯源文件或者無法關聯正確的文件的話,出的問題一定在pdb上。
?
那么我們怎么來查找問題呢?
?
1、首先確定vs是能找到pdb文件,這個可以在vs的模塊列表窗口和堆棧窗口中看到。選中相應的模塊,然后點擊右鍵,在彈出的菜單中選擇“Symbol Load Information”,可以看到pdb文件的加載信息。例如:
E:\temp\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\WindowsFormsApplication2.pdb:Symbols loaded.
?
在“模塊列表窗口”中可以看到最終加載的符號文件信息。
其中Symbol Status是符號文件加載狀態。Symbol File是加載的符號文件的全路徑信息。
?
2、如果vs不能加載正確的pdb文件,則“堆棧窗口”中的對應模塊會變成灰色。如果是不能正確加載pdb文件,則有兩種情況。
1)pdb文件不在vs搜索的路徑之內。
這種情況發生在pdb文件丟失,或者pdb文件拷貝到其它目錄了。這個可以通過“Symbol Load Information”窗口看到。
?
2)pdb文件不匹配。
這種情況就比較難發現一點,因為很多人以為pdb文件的關聯是通過文件名的。例如明明在可執行模塊的同目錄下,有同文件名的pdb文件,卻沒有加載,這是怎么回事呢?
這個就要看看這個pdb文件的簽名是否和exe或者dll中保存的pdb文件一直。
我們可以通過dumpbin /headers命令查看可執行模塊中保存的pdb文件信息。例如:
Microsoft (R) COFF/PE DumperVersion 10.00.40219.01
Copyright (C) MicrosoftCorporation. All rights reserved.
?
?
Dump of fileSystem.Windows.Forms.dll
?
PE signature found
?
File Type: DLL
?
FILE HEADER VALUES
14C machine (x86)
3 number of sections
4D8C1991 time date stamp Fri Mar 2512:26:57 2011
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
210E characteristics
Executable
Line numbers stripped
Symbols stripped
32 bit word machine
DLL
?
OPTIONAL HEADER VALUES
10B magic # (PE32)
8.00 linker version
47B000 size of code
4F000 size of initialized data
0 size of uninitialized data
47C17E entry point (7B44C17E)
2000 base of code
47E000 base of data
7AFD0000 image base (7AFD0000 to7B49DFFF)
2000 section alignment
1000 file alignment
4.00 operating system version
0.00 image version
4.00 subsystem version
0 Win32 version
4CE000 size of image
1000 size of headers
4CBAAA checksum
3 subsystem (Windows CUI)
400 DLL characteristics
No structured exceptionhandler
100000 size of stack reserve
1000 size of stack commit
100000 size of heap reserve
1000 size of heap commit
0 loader flags
10 number of directories
0 [ 0] RVA [size] of Export Directory
47C124 [ 57] RVA [size] of Import Directory
47E000 [ 4D6E0] RVA [size] of Resource Directory
0 [ 0] RVA [size] of Exception Directory
0 [ 0] RVA [size] of Certificates Directory
4CC000 [ C]RVA [size] of Base Relocation Directory
47C0A8 [ 1C] RVA [size] of Debug Directory
0 [ 0] RVA [size] of Architecture Directory
0 [ 0] RVA [size] of Global PointerDirectory
0 [ 0]RVA [size] of Thread Storage Directory
0 [ 0] RVA [size] of Load ConfigurationDirectory
0 [ 0] RVA [size] of Bound Import Directory
2000 [ 8] RVA [size] of Import Address TableDirectory
0 [ 0] RVA [size] of Delay Import Directory
2008 [ 48] RVA [size] of COM DescriptorDirectory
0 [ 0] RVA [size] of Reserved Directory
?
?
SECTION HEADER #1
.text name
47A184 virtual size
2000 virtual address (7AFD2000 to 7B44C183)
47B000 size of raw data
1000 file pointer to raw data (00001000 to 0047BFFF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
60000020 flags
Code
Execute Read
?
Debug Directories
Time Type Size RVA Pointer
-------- ------ -------- -------- --------
4D8C1991 cv 310047C0C4 47B0C4 Format: RSDS,{99F11F8D-84DA-4309-8DA9-2B4BE6DE8672}, 1, System.Windows.Forms.pdb
?
SECTION HEADER #2
.rsrc name
4D6E0 virtual size
47E000 virtual address (7B44E000 to 7B49B6DF)
4E000 size of raw data
47C000 file pointer to raw data (0047C000 to 004C9FFF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
Read Only
?
SECTION HEADER #3
.reloc name
C virtual size
4CC000 virtual address (7B49C000 to 7B49C00B)
1000 size of raw data
4CA000 file pointer to raw data (004CA000 to 004CAFFF)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
42000040 flags
Initialized Data
Discardable
Read Only
?
Summary
?
2000 .reloc
4E000 .rsrc
47C000 .text
?
注意上面的加粗信息。
Format: RSDS,{99F11F8D-84DA-4309-8DA9-2B4BE6DE8672}, 1, System.Windows.Forms.pdb
Format:RSDS:pdb文件的格式。
{99F11F8D-84DA-4309-8DA9-2B4BE6DE8672}:關聯的pdb文件tag。
1:關聯的pdb文件的age。
System.Windows.Forms.pdb :關聯的pdb文件的文件名。
?
Vs加載pdb文件的時候會嚴格驗證guid和age必須一直,即使文件名相同也不行。
所以如果我們碰到同名的pdb文件不能加載,我們可以再看看pdb文件的信息,看看是否一致。
?
?
3、如果能加載正確的pdb文件了,卻不能自動關聯對正確的源文件。這時候就可以看看pdb文件中對應的源文件信息是否正確。
?
查看pdb文件的工具,我們可以使用vs安裝目錄下的Microsoft Visual Studio 10.0\DIASDK\Samples\DIA2Dump中的DIA2Dump工具。這個有源代碼,需要我們重新編譯就可以使用了。
?
Dia2dump pdb文件名 >> 結果文件
?
打開結果文件,我們就可以看到里面包含的各種信息,例如源文件信息。
?
Compiland就是編譯的單元,我們可以看到全路徑信息。然后到對應的路徑下查看是否源代碼文件是否存在。
?
四、注意
另外值得提一下的是,在.net中,在編譯的時候必須要采用/debug:full指令,而不是/debug:pdbonly,如果是后者,也是可以生成pdb文件,但是還是不能進行源代碼級別的調試的,原因是/debug:pdbonly雖然和/debug:full一樣生成同樣的pdb文件,它們的唯一區別是后者會在assembly中加上:DebuggableAttribute。原因是.net是虛擬機執行的,這個標記的作用是告訴.net jit要保留調試信息,否則經過jit編譯后的機器碼就和pdb中的調試信息無法關聯了。C/c++不存在這個問題。 詳細請參見:http://msdn.microsoft.com/en-us/library/8cw0bt21.aspx <pdb文件知識>: Pdb文件是program database的縮寫,意思為程序數據庫。它從編譯器的角度描述了一個程序的組成,例如源代碼,函數,變量,行號等信息。 具體可以參考以下資料:1、《軟件調試》(張銀奎編著)2、《How to Inspect the Content of a Program Database (PDB) File》http://www.codeproject.com/Articles/37456/How-To-Inspect-the-Content-of-a-Program-Database-P3、《PDB Files: What Every Developer Must Know》http://www.wintellect.com/CS/blogs/jrobbins/archive/2009/05/11/pdb-files-what-every-developer-must-know.aspx4、MSDN上的信息。?/*****************************************************************/
/**? 本人原創文章,轉摘請保留本段內容,萬分感謝!
/**? microdreamsoft(Lin Shaohua):
/**? 由于本人水平有限,歡迎各位高手指正。
/**? 本人所有原創文章將發布在以下blog:
/**? http://hi.baidu.com/microdreamsoft
/**?? http://blog.csdn.net/hydream
/**?? http://www.cnblogs.com/MicroDreamSoft/
/**?? http://websoso.bokee.com/
/**?? http://89727175.qzone.qq.com/
/**?? http://751728871.qzone.qq.com/
/*****************************************************************/
?
?
?
?
轉載于:https://www.cnblogs.com/MicroDreamSoft/archive/2012/02/08/2342359.html
總結
以上是生活随笔為你收集整理的VS中调试时不能关联源代码问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在摄影摄像中什么是M4格式?
- 下一篇: libxml中用到的Xpath语法说明