DotNet Framework源代码调试问题(转)
DotNet Framework源代码调试问题
几年前,记得vs2008刚发布的时候,带了一个新的特性,就是可以调试.Net Framework的源代码,当时非常兴奋,马上实验了一下,按照(ConfiguringVisual Studio to Debug .NET Framework Source Code)http://blogs.msdn.com/b/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx
配置VS2008,就可以看到神奇的.net framework源代码。相当简单方便。后面因为时间原因,也没有太多时间去追踪查看学习.net framework的源代码。
几年后的今天,因为一些问题,需要查看下.NetFramework的实现机理,却发现怎么配置也无法step in .net framework的源代码了。害的我花了将近一天时间查资料,才总算把这个问题弄明白了。
在网上有大量的人碰到了这个问题,baidu或者google一下,会发现无论是国内还是国外,很多人都碰到了问题,回答的人也有各种答案,但是真正能解决问题的似乎没有。无论怎样,经过自己的努力,总算找到了原因,在这里写出来,希望给同样碰到这个问题的人有所启发,少走弯路,由于本人水品有限,如有高手不吝指正错误,万分感谢!
在解释下面的过程前,你需要对pdb文件有所熟悉了解,如果您不熟悉,请参见我的另外一篇博文《VS中调试时不能关联源代码问题》中的pdb文件知识部分。
1、 问题描述
1)在微软的开放源码参考网站上,有配置vs2008的说明。地址在:http://referencesource.microsoft.com/serversetup.aspx
按照上面的配置后,发现不行。
如图:
这样设置后(注意我f:盘中的路径设置是从网站上下载的msi文件安装路径,后面还有解释。),调试程序,下断点,在堆栈窗口中会看到.net framework的程序集变成亮色了(没有加载pdb的程序集会显示灰色)。但是双击,会出现:
No Source Available的界面提示:
而且Browse to Find Source不能使用。关于Browse to FindSource的问题,请参见本人另外一篇博文《VS中调试关联源代码问题》。
2)按照第二种方式,将源代码下载下来(官方说明:http://referencesource.microsoft.com/downloadsetup.aspx)安装,然后配置。下载地址:http://referencesource.microsoft.com/netframework.aspx。经证实还是不行。在这里我多说两句,以这种方式安装源代码和pdb文件时候,建议把上面地址中的所有包都下载下来安装,而且安装在统一的文件夹下面,这个是不会有冲突的。因为pdb和源代码是和build相关联的。安装在一个目录下,以后方便只设置一个symbols目录就可以了。如我上图中的“F:\DotNetRefSrc”。安装完了,可以看到如下的目录结构:
其中Source子目录是每个发布版本的源代码镜像,Symbols是pdb文件目录。我们需要特别关注一下Symbols目录。
2、 问题探究
1)首先怀疑是我配置有问题,难道是我2010版本的问题?于是在msdn网站上找到这个:How to: Debug .NET FrameworkSource
http://msdn.microsoft.com/en-us/library/cc667410.aspx
说明vs2010也应该可以的呀。
为了证实,于是又启动vs2008实验了一下,发现还是一样。所以确认不是版本问题。而且下面有人留言在说微软这个问题:
not working!
This never workedfor me. Not even with *fresh* Windows 7 x64 and Visual Studio 2010installations. All I'm getting is "No source available". And peopleall over the Internet are crying out loud that it's not working for themeither. It's frustrating, you know?
2)于是百度,google。发现网上很多人碰到这个问题。看来不只是我的问题。
3)在microsoft的官方网站和论坛中,也有很多人在咨询这个问题。
例如:
http://social.msdn.microsoft.com/Forums/en-US/refsourceserver/threads?page=1(ReferenceSource Server Discussion)
http://stackoverflow.com/questions/8139269/vs2010-how-to-enable-enable-net-framework-source-stepping
(How do i enable .NETframework source stepping in Visual Studio 2010?)
注意上面的这个地址,这个人总结给我很大的启发。
3、 问题确定
上面那个人的回答突然让我想到是不是因为pdb版本问题或者.netframework版本源代码问题。因为微软并非所有的都开源了,有些是没有开源的,我看的源代码位于System.Windows.Forms中,这个程序集是可以确认开源了的。因此只有可能是版本问题,我的dll和pdb版本不匹配。为了确认,我查看了下vs2010加载的到底是哪个版本的pdb。如下:
C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.pdb:Cannot find or open the PDB file.
D:\ProgramFiles\Microsoft Visual Studio 10.0\Common7\IDE\System.Windows.Forms.pdb: Cannotfind or open the PDB file.
d:\symbolscache\System.Windows.Forms.pdb\98E168F147A646C9BE3D5B9C755E65DA1\System.Windows.Forms.pdb:Symbols loaded.
具体查看方法:在堆栈窗口上选中要查看的模块,然后右键,选择“Symbol Load Information”。或者在“模块窗口”中选择相应的模块,右键“Sysmbol Load Information”查看。
通过上面的信息,我们可以得出一个小结论,就是vs2010加载pdb文件是有搜索路径的。
很明显,它加载的是我d盘下面的缓存文件夹下的pdb文件,采用diadump程序(在visualstudio的安装目录下的dia samples目录下)。可以查看pdb文件的内容,可以看到这个pdb文件是public pdb文件,而不是private build pdb文件,难怪不能关联源文件。
同样,我们通过dumpbin可以查看下这个dll的debug关联信息。
可以看到pdb文件名是System.Windows.Forms.pdb。
加载的pdb文件是:
System.Windows.Forms.pdb\98E168F147A646C9BE3D5B9C755E65DA1\System.Windows.Forms.pdb
上面提到要注意symbols这个目录,这个目录的结构是这样的:
程序集关联的pdb文件名\GUID\程序集关联的pdb文件名
说明我的程序集的关联的pdb文件是{99****}的一个pdb文件,于是我从下载的目录中F:\DotNetRefSrc\Symbols\system.windows.forms.pdb查看有没有这个目录,发现没有,难怪vs会去微软服务器上下载。
所有微软发布的源代码的pdb只有:
明显没有99开头的guid。
我的环境是.Net Framework 4sp1+VS2010 sp1。我赶紧去gac中查看System.Windows.Forms.dll的版本,可以看到这个信息:
文件版本是4.0.30319.235。而发布的带源代码的只有4.0.30319.1的。。。同样我查看了3.5sp1的版本,发现发布的最高版本只有50727.4016 ,我的是2.0.50727.4961。
4、总结
至此,我总算明白了原因所在。很明显主版本号都是一致的,而是后面的修订版本号和我的不一样,很有可能是我的电脑安装的某些补丁造成的,而微软又是不发布相关update的pdb文件和源代码的。因此造成pdb文件不匹配,于是vs根据guid去它的public sysmbol server去取public build pdb文件,造成无法关联源代码文件,也就没有办法进行跟踪.net framework源代码了。
对这个问题,在微软的论坛中,也有人建议在虚拟机中建立一个对应发布了源代码的Framework的版本,不要更新。问题是这样也太麻烦了吧?而且对于我们这种又不是专门天天去看Framework的源代码,大部分时候是因为在写应用的时候,因为碰到一个问题,需要跟入Framework源代码去,方便了解整个机理。可是。。。。。。
还有就是采用Reflector的vs plugin,不过Reflector现在可是收费的。
参考信息:
Reference Source Code Center Team Blog(参考代码开放官方博客,发布有开放的版本信息)
Reference Source ServerDiscussion (官方论坛)
http://social.msdn.microsoft.com/Forums/en-US/refsourceserver/threads?page=1
(官方网站)
http://referencesource.microsoft.com/Default.aspx
VS2010: How to enable “Enable .NET Framework source stepping”? (网上人与我相同的问题)
http://stackoverflow.com/questions/8139269/vs2010-how-to-enable-enable-net-framework-source-stepping
How to: Debug .NET Framework Source(微软msdn文档中心)
http://msdn.microsoft.com/en-us/library/cc667410.aspx