VS中调试时不能关联源代码问题
2016-01-04 09:52
519 查看
转自:'target='_blank'>http://blog.csdn.net/hydream/article/details/7241439
/*****************************************************************/
/**本人原创文章,转摘请保留本段内容,万分感谢!
/**microdreamsoft(LinShaohua):
/**由于本人水平有限,欢迎各位高手指正。
/**本人所有原创文章将发布在以下blog:
/**http://blog.csdn.net/hydream/**http://websoso.bokee.com/**http://89727175.qzone.qq.com/**http://hi.baidu.com/microdreamsoft/**http://751728871.qzone.qq.com/*****************************************************************/
一、问题提出:
我们有时候调试程序的时候,会碰到一种问题,例如通过myclass.cs编译后的程序,我们在调试的时候,却发现即使我们有myclass.cs源文件,VisualStudio却不能自动关联,当你在堆栈窗口双击打开时候,会出现类似以下的界面:
(图1)
提示没有源代码,有时候还会弹出对话框,让你选择源文件。尤其是在调试第三方代码,或者是调试在其他机子上编译的程序时候,会出现这种情况,那么问题在哪里呢?
二、VS中是怎样查找源文件的?
要弄清楚这个问题,首先要理解pdb文件的作用,关于这个文件的知识,请见文后的《pdb文件知识》。
源文件和可执行模块(exeordll)是通过pdb文件进行关联的。如下图所示:
可执行模块中保存有pdb文件的信息,pdb文件中保存有源文件的信息。
VS查找源文件的流程是这样的:
1、根据可执行模块中保存的pdb文件信息(guid,pdb文件名,age)查找加载pdb文件。
2、根据pdb中的源文件路径查找源文件。如果源文件在路径中不存在,则在“图1”中的“Browsetofindsource”可以使用,点击后会弹出文件打开对话框。如果pdb是publicpdb文件,则没有包含源文件信息,这时“图1”中的“Browse
tofindsource”变成灰色,不可使用。
三、解决问题的思路方法
有了这个流程概念后,我们就可以知道,如果无法关联源文件或者无法关联正确的文件的话,出的问题一定在pdb上。
那么我们怎么来查找问题呢?
1、首先确定vs是能找到pdb文件,这个可以在vs的模块列表窗口和堆栈窗口中看到。选中相应的模块,然后点击右键,在弹出的菜单中选择“SymbolLoadInformation”,可以看到pdb文件的加载信息。例如:
E:\temp\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\WindowsFormsApplication2.pdb:Symbolsloaded.
在“模块列表窗口”中可以看到最终加载的符号文件信息。
其中SymbolStatus是符号文件加载状态。SymbolFile是加载的符号文件的全路径信息。
2、如果vs不能加载正确的pdb文件,则“堆栈窗口”中的对应模块会变成灰色。如果是不能正确加载pdb文件,则有两种情况。
1)pdb文件不在vs搜索的路径之内。
这种情况发生在pdb文件丢失,或者pdb文件拷贝到其它目录了。这个可以通过“SymbolLoadInformation”窗口看到。
2)pdb文件不匹配。
这种情况就比较难发现一点,因为很多人以为pdb文件的关联是通过文件名的。例如明明在可执行模块的同目录下,有同文件名的pdb文件,却没有加载,这是怎么回事呢?
这个就要看看这个pdb文件的签名是否和exe或者dll中保存的pdb文件一直。
我们可以通过dumpbin/headers命令查看可执行模块中保存的pdb文件信息。例如:
Microsoft(R)COFF/PEDumperVersion10.00.40219.01
Copyright(C)MicrosoftCorporation.Allrightsreserved.
DumpoffileSystem.Windows.Forms.dll
PEsignaturefound
FileType:DLL
FILEHEADERVALUES
14Cmachine(x86)
3numberofsections
4D8C1991timedatestampFriMar2512:26:572011
0filepointertosymboltable
0numberofsymbols
E0sizeofoptionalheader
210Echaracteristics
Executable
Linenumbersstripped
Symbolsstripped
32bitwordmachine
DLL
OPTIONALHEADERVALUES
10Bmagic#(PE32)
8.00linkerversion
47B000sizeofcode
4F000sizeofinitializeddata
0sizeofuninitializeddata
47C17Eentrypoint(7B44C17E)
2000baseofcode
47E000baseofdata
7AFD0000imagebase(7AFD0000to7B49DFFF)
2000sectionalignment
1000filealignment
4.00operatingsystemversion
0.00imageversion
4.00subsystemversion
0Win32version
4CE000sizeofimage
1000sizeofheaders
4CBAAAchecksum
3subsystem(WindowsCUI)
400DLLcharacteristics
Nostructuredexceptionhandler
100000sizeofstackreserve
1000sizeofstackcommit
100000sizeofheapreserve
1000sizeofheapcommit
0loaderflags
10numberofdirectories
0[0]RVA[size]ofExportDirectory
47C124[57]RVA[size]ofImportDirectory
47E000[4D6E0]RVA[size]ofResourceDirectory
0[0]RVA[size]ofExceptionDirectory
0[0]RVA[size]ofCertificatesDirectory
4CC000[C]RVA[size]ofBaseRelocationDirectory
47C0A8[1C]RVA[size]ofDebugDirectory
0[0]RVA[size]ofArchitectureDirectory
0[0]RVA[size]ofGlobalPointerDirectory
0[0]RVA[size]ofThreadStorageDirectory
0[0]RVA[size]ofLoadConfigurationDirectory
0[0]RVA[size]ofBoundImportDirectory
2000[8]RVA[size]ofImportAddressTableDirectory
0[0]RVA[size]ofDelayImportDirectory
2008[48]RVA[size]ofCOMDescriptorDirectory
0[0]RVA[size]ofReservedDirectory
SECTIONHEADER#1
.textname
47A184virtualsize
2000virtualaddress(7AFD2000to7B44C183)
47B000sizeofrawdata
1000filepointertorawdata(00001000to0047BFFF)
0filepointertorelocationtable
0filepointertolinenumbers
0numberofrelocations
0numberoflinenumbers
60000020flags
Code
ExecuteRead
DebugDirectories
TimeTypeSizeRVAPointer
--------------------------------------
4D8C1991cv310047C0C447B0C4Format:RSDS,{99F11F8D-84DA-4309-8DA9-2B4BE6DE8672},1,System.Windows.Forms.pdb
SECTIONHEADER#2
.rsrcname
4D6E0virtualsize
47E000virtualaddress(7B44E000to7B49B6DF)
4E000sizeofrawdata
47C000filepointertorawdata(0047C000to004C9FFF)
0filepointertorelocationtable
0filepointertolinenumbers
0numberofrelocations
0numberoflinenumbers
40000040flags
InitializedData
ReadOnly
SECTIONHEADER#3
.relocname
Cvirtualsize
4CC000virtualaddress(7B49C000to7B49C00B)
1000sizeofrawdata
4CA000filepointertorawdata(004CA000to004CAFFF)
0filepointertorelocationtable
0filepointertolinenumbers
0numberofrelocations
0numberoflinenumbers
42000040flags
InitializedData
Discardable
ReadOnly
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安装目录下的MicrosoftVisualStudio10.0\DIASDK\Samples\DIA2Dump中的DIA2Dump工具。这个有源代码,需要我们重新编译就可以使用了。
Dia2dumppdb文件名>>结果文件
打开结果文件,我们就可以看到里面包含的各种信息,例如源文件信息。
Compiland就是编译的单元,我们可以看到全路径信息。然后到对应的路径下查看是否源代码文件是否存在。
四、注意
/*****************************************************************/
/**本人原创文章,转摘请保留本段内容,万分感谢!
/**microdreamsoft(LinShaohua):
/**由于本人水平有限,欢迎各位高手指正。
/**本人所有原创文章将发布在以下blog:
/**
一、问题提出:
我们有时候调试程序的时候,会碰到一种问题,例如通过myclass.cs编译后的程序,我们在调试的时候,却发现即使我们有myclass.cs源文件,VisualStudio却不能自动关联,当你在堆栈窗口双击打开时候,会出现类似以下的界面:
(图1)
提示没有源代码,有时候还会弹出对话框,让你选择源文件。尤其是在调试第三方代码,或者是调试在其他机子上编译的程序时候,会出现这种情况,那么问题在哪里呢?
二、VS中是怎样查找源文件的?
要弄清楚这个问题,首先要理解pdb文件的作用,关于这个文件的知识,请见文后的《pdb文件知识》。
源文件和可执行模块(exeordll)是通过pdb文件进行关联的。如下图所示:
可执行模块中保存有pdb文件的信息,pdb文件中保存有源文件的信息。
VS查找源文件的流程是这样的:
1、根据可执行模块中保存的pdb文件信息(guid,pdb文件名,age)查找加载pdb文件。
2、根据pdb中的源文件路径查找源文件。如果源文件在路径中不存在,则在“图1”中的“Browsetofindsource”可以使用,点击后会弹出文件打开对话框。如果pdb是publicpdb文件,则没有包含源文件信息,这时“图1”中的“Browse
tofindsource”变成灰色,不可使用。
三、解决问题的思路方法
有了这个流程概念后,我们就可以知道,如果无法关联源文件或者无法关联正确的文件的话,出的问题一定在pdb上。
那么我们怎么来查找问题呢?
1、首先确定vs是能找到pdb文件,这个可以在vs的模块列表窗口和堆栈窗口中看到。选中相应的模块,然后点击右键,在弹出的菜单中选择“SymbolLoadInformation”,可以看到pdb文件的加载信息。例如:
E:\temp\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\WindowsFormsApplication2.pdb:Symbolsloaded.
在“模块列表窗口”中可以看到最终加载的符号文件信息。
其中SymbolStatus是符号文件加载状态。SymbolFile是加载的符号文件的全路径信息。
2、如果vs不能加载正确的pdb文件,则“堆栈窗口”中的对应模块会变成灰色。如果是不能正确加载pdb文件,则有两种情况。
1)pdb文件不在vs搜索的路径之内。
这种情况发生在pdb文件丢失,或者pdb文件拷贝到其它目录了。这个可以通过“SymbolLoadInformation”窗口看到。
2)pdb文件不匹配。
这种情况就比较难发现一点,因为很多人以为pdb文件的关联是通过文件名的。例如明明在可执行模块的同目录下,有同文件名的pdb文件,却没有加载,这是怎么回事呢?
这个就要看看这个pdb文件的签名是否和exe或者dll中保存的pdb文件一直。
我们可以通过dumpbin/headers命令查看可执行模块中保存的pdb文件信息。例如:
Microsoft(R)COFF/PEDumperVersion10.00.40219.01
Copyright(C)MicrosoftCorporation.Allrightsreserved.
DumpoffileSystem.Windows.Forms.dll
PEsignaturefound
FileType:DLL
FILEHEADERVALUES
14Cmachine(x86)
3numberofsections
4D8C1991timedatestampFriMar2512:26:572011
0filepointertosymboltable
0numberofsymbols
E0sizeofoptionalheader
210Echaracteristics
Executable
Linenumbersstripped
Symbolsstripped
32bitwordmachine
DLL
OPTIONALHEADERVALUES
10Bmagic#(PE32)
8.00linkerversion
47B000sizeofcode
4F000sizeofinitializeddata
0sizeofuninitializeddata
47C17Eentrypoint(7B44C17E)
2000baseofcode
47E000baseofdata
7AFD0000imagebase(7AFD0000to7B49DFFF)
2000sectionalignment
1000filealignment
4.00operatingsystemversion
0.00imageversion
4.00subsystemversion
0Win32version
4CE000sizeofimage
1000sizeofheaders
4CBAAAchecksum
3subsystem(WindowsCUI)
400DLLcharacteristics
Nostructuredexceptionhandler
100000sizeofstackreserve
1000sizeofstackcommit
100000sizeofheapreserve
1000sizeofheapcommit
0loaderflags
10numberofdirectories
0[0]RVA[size]ofExportDirectory
47C124[57]RVA[size]ofImportDirectory
47E000[4D6E0]RVA[size]ofResourceDirectory
0[0]RVA[size]ofExceptionDirectory
0[0]RVA[size]ofCertificatesDirectory
4CC000[C]RVA[size]ofBaseRelocationDirectory
47C0A8[1C]RVA[size]ofDebugDirectory
0[0]RVA[size]ofArchitectureDirectory
0[0]RVA[size]ofGlobalPointerDirectory
0[0]RVA[size]ofThreadStorageDirectory
0[0]RVA[size]ofLoadConfigurationDirectory
0[0]RVA[size]ofBoundImportDirectory
2000[8]RVA[size]ofImportAddressTableDirectory
0[0]RVA[size]ofDelayImportDirectory
2008[48]RVA[size]ofCOMDescriptorDirectory
0[0]RVA[size]ofReservedDirectory
SECTIONHEADER#1
.textname
47A184virtualsize
2000virtualaddress(7AFD2000to7B44C183)
47B000sizeofrawdata
1000filepointertorawdata(00001000to0047BFFF)
0filepointertorelocationtable
0filepointertolinenumbers
0numberofrelocations
0numberoflinenumbers
60000020flags
Code
ExecuteRead
DebugDirectories
TimeTypeSizeRVAPointer
--------------------------------------
4D8C1991cv310047C0C447B0C4Format:RSDS,{99F11F8D-84DA-4309-8DA9-2B4BE6DE8672},1,System.Windows.Forms.pdb
SECTIONHEADER#2
.rsrcname
4D6E0virtualsize
47E000virtualaddress(7B44E000to7B49B6DF)
4E000sizeofrawdata
47C000filepointertorawdata(0047C000to004C9FFF)
0filepointertorelocationtable
0filepointertolinenumbers
0numberofrelocations
0numberoflinenumbers
40000040flags
InitializedData
ReadOnly
SECTIONHEADER#3
.relocname
Cvirtualsize
4CC000virtualaddress(7B49C000to7B49C00B)
1000sizeofrawdata
4CA000filepointertorawdata(004CA000to004CAFFF)
0filepointertorelocationtable
0filepointertolinenumbers
0numberofrelocations
0numberoflinenumbers
42000040flags
InitializedData
Discardable
ReadOnly
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安装目录下的MicrosoftVisualStudio10.0\DIASDK\Samples\DIA2Dump中的DIA2Dump工具。这个有源代码,需要我们重新编译就可以使用了。
Dia2dumppdb文件名>>结果文件
打开结果文件,我们就可以看到里面包含的各种信息,例如源文件信息。
Compiland就是编译的单元,我们可以看到全路径信息。然后到对应的路径下查看是否源代码文件是否存在。
四、注意
另外值得提一下的是,在.net中,在编译的时候必须要采用/debug:full指令,而不是/debug:pdbonly,如果是后者,也是可以生成pdb文件,但是还是不能进行源代码级别的调试的,原因是/debug:pdbonly虽然和/debug:full一样生成同样的pdb文件,它们的唯一区别是后者会在assembly中加上:DebuggableAttribute。原因是.net是虚拟机执行的,这个标记的作用是告诉.netjit要保留调试信息,否则经过jit编译后的机器码就和pdb中的调试信息无法关联了。C/c++不存在这个问题。
详细请参见:http://msdn.microsoft.com/en-us/library/8cw0bt21.aspx
<pdb文件知识>:
Pdb文件是programdatabase的缩写,意思为程序数据库。它从编译器的角度描述了一个程序的组成,例如源代码,函数,变量,行号等信息。
具体可以参考以下资料:
1、《软件调试》(张银奎编著)
2、《HowtoInspecttheContentofaProgramDatabase(PDB)File》http://www.codeproject.com/Articles/37456/How-To-Inspect-the-Content-of-a-Program-Database-P
3、《PDBFiles:WhatEveryDeveloperMustKnow》http://www.wintellect.com/CS/blogs/jrobbins/archive/2009/05/11/pdb-files-what-every-developer-must-know.aspx
4、MSDN上的信息。
相关文章推荐
- java的Arrays类的应用
- 《Java编程思想》学习笔记13——Java new I/O(二)
- C++跨平台类型定义
- 《Java编程思想》学习笔记12——Java new I/O(一)
- C++常用预定义
- python性能优化
- 《Java编程思想》学习笔记11——Java I/O
- 异步Servlet编程 | Servlet3.0新特性
- 《Java编程思想》学习笔记10——文件和目录常用操作
- 基于yii1.1开发个人博客系统
- PHP 下载文件时如何自动添加bom头及解释BOM头和去掉bom头的方法
- Java笔记----java反射
- 基于java的PDF格式文件的生成
- 《Java编程思想》学习笔记9——集合容器高级
- JavaBean为什么要实现Serializable接口的原因
- Java设置模式_创建型_单例模式_只存在一个实例
- Eclipse 如何安装单独的一个jar插件
- 声明式编程和命令式编程
- 《Java编程思想》学习笔记8——泛型编程高级
- 代码审查学习资料