dot NET 20应用程序调试.doc_第1页
dot NET 20应用程序调试.doc_第2页
dot NET 20应用程序调试.doc_第3页
dot NET 20应用程序调试.doc_第4页
dot NET 20应用程序调试.doc_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2.6 建立符号库 2.6 建立符号库对那些在Windows上开发时间超过5分钟的人来说,他们都知道,得到正确的调试符号是提高调试速度的诀窍。尽管托管代码在PDB文件中只有代码和行号信息以及局部变量,但如果你的问题与本机代码有关,那你就太不走运了。本机代码将更多的信息放入PDB,如果没有调试符号,就会因为没有PDB文件中的帧指针省略(frame pointer omission ,FPO)而使数据不可能得到可用的调用堆栈。如果你认为让开发团队以及公司的每个人使用正确的符号有困难,那就想想微软的操作系统小组的处境有多糟糕吧。他们每天都要生成不同的版本,而且全世界有数以千计的不同版本的操作系统在任何时候运行。相比之下,你的符号问题就似乎微不足道了。即使你认为自己在一个大型的项目中,但比起微软操作系统小组所承受的调试符号的数量,你的项目也就不算什么了。除了获得调试符号外,微软还必须面对维护管理二进制文件的难题。微软为更好地解决调试崩溃的问题引入了一种叫微型转储(minidump)或崩溃转储(crash dump)的技术。当发生系统崩溃时,这些文件中都包含了应用程序的状态,对使用其他操作系统的开发人员来说,可能会把这些文件称为核心转储(core dumps)。微型转储的魅力就在于,通过在转储文件中记录应用程序的状态,就能加载到调试器中,以重现崩溃时的情况。在接下来的章节中,除了讨论如何在调试器中读取微型转储文件外,还将讨论生成微型转储文件的机制。微型转储的关键问题就是加载正确的二进制。你可能会在Windows Vista之前的操作系统上进行开发,但是客户的微型转储文件可能是在只应用了Service Pack 1的Windows Server 2003上生成的。与调试符号的问题一样,如果你不能加载微型转储生成时在地址空间中的可执行文件,那么你想轻松解决微型转储文件中的错误几乎是不大可能的。微软的开发人员意识到他们不得不采取些行动让自己轻松点。由于缺少与任何机器上无数的修补程序相匹配的操作系统符号和二进制,我们这些微软之外的人也一直在抱怨调试的经历真是苦海无边。符号服务器的概念很简单:在一个大家都知道的地址保存所有公共版本符号和二进制可执行程序,并使调试器更智能,这样就能对加载到进程的每个模块加载正确的符号和二进制可执行程序无论模块是从代码中加载还是从操作系统中加载无需进行任何用户交互。它的好处就是事实上也是这么简单。本节中我还会指出一些小问题,但是如果正确安装了符号服务器,无论你进行托管开发还是本机开发,或是同时进行两种类型的开发,也无论是使用Visual Studio或WinDBG作为调试器,开发团队或公司中就不会有人缺少正确的符号或二进制。请大家放心,我还会提供一个工具能帮大家确认是否有适合操作系统和产品的合适的符号和二进制。与前几个版本相比,Visual Studio 2005对访问符号服务器进行调试的方法作了很大的改进。不巧的是,文档仍旧没有讨论最重要的观点,即如何将符号和二进制文件引入符号服务器。由于这是使用符号服务器的最大好处,接下来就会讨论如何安装一个有效的符号服务器。让公司里每个执行你的项目的人都能访问服务器的步骤非常简单。你可能需要将这个服务器命名为SYMBOLS以方便地与其他服务器区分。在接下来的讨论中,我将假设这就是服务器的名字。这个服务器不需要很快的运行速度,它只是作为文件服务器。惟一的要求就是需要服务器上有大量的磁盘空间,80GB以上可能差不多。一旦安装了服务器软件之后,需再创建两个共享目录OSSYMBOLS和PRODUCTSYMBOLS。允许开发团队的每个人都可以读写权限来访问OSSYMBOLS目录,开发人员和QA只需要只读权限访问PRODUCTSYMBOLS目录,就可给进行编译的账户以写入权限。由于能通过共享名字进行区分,一个目录用于操作系统符号和二进制文件,另一个目录就用于我们的产品的符号和二进制文件。为了方便你管理需要分离的这两个目录。当然,对我来说假设你的公司有服务器是一件很简单的事情,我把获得服务器这个任务就交给读者自己了。下一步就是从/whdc/devtools/debugging/default.mspx下载或安装最新版本的Debugging Tools for Windows,这是因为符号服务器二进制是由Windows小组而不是Visual Studio小组开发的。为了正确地调试应用程序,最好确定你安装的版本与你正在使用的操作系统是相匹配的。你可能需要核对Debugging Tools for Windows的更新版本,因为Windows小组似乎经常更新这个工具。安装了Debugging Tools for Windows之后,在系统的PATH环境变量中添加安装目录。4个主要的二进制如Symsrv.dll、Dbghelp.dll、Symchk.exe和Symstore.exe必须能对符号服务器中读取或写入操作。对于那些访问互联网的时候都需要使用代理服务器登录的人来说,我颇为同情。幸运的是,Windows小组知道我们的痛苦。Debugging Tools for Windows与Visual Studio 2005都带有Symsrv.dll的一个版本,在所有监控互联网信息包的公司中也可以使用。相关信息需要阅读Debugging Tools for Windows文档中标题为“Using Symbol Servers and Symbol Stores(使用符号服务器和符号库)”的关于代理服务器和防火墙的部分。在文档中讨论了如何设置_NT_SYMBOL_PROXY环境变量来下载符号而无须输入用户名和密码。你还需要寻找Debugging Tools for Windows的新版本。既然Windows小组总是更新符号服务器二进制文件,你就应该寻找新的发布版本。在大多数情况下,这个小组会在1月和7月发布新版本,但是其他时候就不会发布了。请在/WEBLOGS/阅读Wintellect Blog,因为当这个小组发布新的Debugging Tools for Windows的时候我总是会提醒大家。安装了Debugging Tools for Windows以后,就应该安装两个调试器进行使用。对WinDBG,最好在系统设置中使用两个环境变量来告诉调试器符号服务器驻留在哪里。为了在Windows XP和Windows Server 2003中访问这个区域,右击“我的电脑”,从快捷菜单中选择“选项”。点击“高级”标签,在“系统选项”对话框的底部,点击“环境变量”。 图2-5显示了环境变量对话框。你需要创建两个新的环境变量_NT_SYMBOL_ PATH和_NT_EXECUTABLE_IMAGE_PATH,我将马上向你显示这些值。你从名字中就能猜到,第一个环境变量就是WinDBG寻找PDB文件的地方,而WinDBG使用第二个环境变量寻找微型转储文件的二进制。_NT_SYMBOL_PATH的值如下(注意,下面的代码都需要在一行中输入,你应该把访问Visual Studio安装目录的路径放在Visual_Studio_ installation_directory):SRV*c:symbols*SymbolsOSSymbols*SymbolsProductSymbols*/download/symbols;SDKv2.0symbols;SDK v2.0 64bitsymbols;_NT_EXECUTABLE_IMAGE_PATH的值很相似:SRV*c:symbols*SymbolsOSSymbols*SymbolsProductSymbols图2-5 环境变量对话框为了详细解释符号路径,最好了解调试器如何查找符号。关键的值都在PDB文件和GUID中。当你编译源代码到Portable Executable(PE)文件并生成PDB文件时,编译器或连接器就会放入一个调试片断(debug section)。在这个片断中,它列举了访问PDB文件及GUID的完整路径,相同的GUID也写入了PDB文件。在这两个地方有了唯一的GUID,调试器就不需要依赖易出现问题的时间戳来保证它正在查看匹配二进制的PDB文件。当调试器加载PDB时,第一个就会在二进制的调试片断中寻找访问PDB文件的完整路径。如果有匹配的PDB文件,调试器就会打开那个PDB文件,你就能用符号进行调试了。如果你想知道为什么能在机器上生成二进制文件并将二进制文件移到不同的驱动和目录,但是调试器似乎就知道从那里寻找符号,这就是原因。如果调试器不能从嵌入二进制文件的路径中找到匹配的PDB文件,它就会在加载二进制的目录中寻找,如果匹配的符号存在,它们就会被加载。现在你知道为什么能把二进制和PDB文件复制到其他机器上,符号也能正确显示了吧。如果PDB文件不在二进制加载的目录中,而你又设置了_NT_SYMBOL_PATH环境变量,符号搜索就会稍微有些不同。_NT_SYMBOL_PATH变量中包含了由分号隔开的搜索路径列表。调试器能解析出这些路径并查找匹配的名字和GUID,如果找到它们,PDB文件就能加载。当符号服务器看到SRV开头的路径,这就是开始查找符号的信号,而且如果你设置了环境变量,而你仍未得到任何Symbol Server支持,我几乎能保证你交换了SRV中的R和V。SRV后的第一个星号(*)就是被称为下载缓冲区的点。调试器检查了符号服务器的各种设置,如果它找到了PDB文件,它就能把这个文件复制到下载缓冲区。当调试器找到匹配的PDB文件时,它就能打开那个PDB文件,并停止检查剩余的符号服务器路径。下载缓冲区意味着当每次调试时,访问网络上的PDB文件不会影响网络性能。如果磁盘空间不够,你可以在下次调试前删除C:SYMBOLS目录下的所有东西,调试器会自动重新下载匹配的PDB文件。如果PDB文件在下载缓冲区中找不到,调试器会查找环境变量中由接下来的星号标识的符号服务器。在_NT_SYMBOL_PATH值中,第一个搜索的地址就是操作系统符号服务器SymbolsOSSymbols。在本节接下来的内容中,我会向你们介绍如何花最小的精力填充操作系统符号服务器。如果PDB文件在操作系统符号服务器中找到,PDB文件就会被复制到下载缓冲区,这样你不需要在匹配的PDB文件上重新设置网络访问。正如你能猜到的那样,符号服务器在SymbolsProductSymbols包含了产品符号。你还会知道如何将所有版本放入产品符号服务器中,这样你永远都不会没有调试符号。最后一个指定的符号服务器(/download/symbols)是最有意思的一个。如果调试器在你公司的符号服务器中找不到符号,它会向微软公共的符号服务器要求匹配的PDB文件。这个好处就在于对Windows 2000以来的所有Windows操作系统(包括所有服务包和修补程序)来说,你能自动获得操作系统符号。如果在“周二补丁日”(每个月的第二个周二,是微软发布最新的修补程序的日子)之后开始工作,你一样能立刻获取所有更新的操作系统符号。毫无疑问,能够在本机代码中检查出错时的堆栈是非常美好的,这对提高生产力有巨大的帮助。无论你在自己的机器上进行单元测试或在客户提供的微型转储文件上调试,都能下载调试符号,得到正确的PDB文件。如果你公司的符号服务器是在SYMBOLS上安装的,除了有调试微型转储所需的二进制文件外,还有PDB文件。微软公共符号服务器则只有PDB文件。这仍会导致特定微型转储的一些问题,但调试器能让调试继续工作。公共符号服务器的最后一个要点就是符号文件不是完全的本机PDB文件,但是它们被分解了,因为它们只包含了公有函数和访问堆栈最重要的FPO数据。总而言之,早先显示的用分号分割的环境变量值中的符号服务器有两条路径:Visual_Studio_installation_directorySDKv2.0symbols和Visual_Studio_installation_directory SDKv2.0 64bitsymbols。如果你相信我所说的与微软公共符号服务器(Microsoft Public Symbol Server)组合在一起的符号服务器是很有用的,你可能会疑惑为什么我又推荐你把框架SDK(Framework SDK)符号目录添加到路径中。在大多数情况下,Visual Studio的安装会自动安装框架SDK,即使你可以选择不去安装SDK。我建议最好安装框架SDK。框架SDK符号目录包含着通用语言运行时(Common Language Runtime,CLR)的核心DLL的PDB文件。一些用于大多数内核问题的紧急情况下的WinDBG扩展命令需要访问PDB文件才能工作。在缓存区中没有文件或无法连接到互联网的情况下,在环境变量中有这些路径或许能帮助你解决问题。既然已经了解了调试器查找符号的步骤,你就可以理解用于二进制文件的_NT_EXECUTABLE_IMAGE_PATH环境变量的同样步骤。由于二进制文件不在微软公共符号服务器中,你需要告诉WinDBG只搜索你的内部符号服务器。唯一的区别是WinDBG会先查找你的机器上的二进制文件。例如,如果微型转储文件在C:Foo目录下有一个二进制的记录,那就是WinDBG在执行搜索符号服务器任务前先查找的地方。在WinDBG中,查看是否正确设置了_NT_SYMBOL_PATH则有点困难。由于这是有关WinDBG的问题,在第6章“WinDBG、SOS和ADPlus”中的“符号服务器安装”一节中,我将会详细介绍检查WinDBG是否正确加载符号的步骤。Visual Studio 2005将使用_NT_SYMBOL_PATH和_NT_EXECUTABLE_IMAGE_PATH环境变量,但是你在IDE中也能设置相同的值。在Visual Studio设置符号和二进制文件路径的方法的一个优点是:一旦你设置了,就能非常简单地将这些设置导入或导出其他安装。在团队范围内建立设置是个很好的想法,在安装了新机器后,组里的每个人都能导入并能立刻准备调试。在Visual Studio 2005的选项对话框中,单击“调试”节点,然后点击“符号”节点。那里的属性页就是你直接输入路径的地方。在我提倡的安装中,请按照下列的顺序输入路径。1. SymbolsOSSymbols2. SymbolsProductSymbols3. /download/symbols4. Visual_Studio_installation_directory SDKv2.0symbols5. Visual_Studio_installation_directory SDKv2.0 64bitsymbols另外,你需要将缓存区目录设置到C:SYMBOLS下,这样可以在两个调试器之间共享缓存文件。图2-6显示了“选项”对话框,对话框中已正确填写了所有的值。图2-6 Visual Studio调试符号设置Visual Studio方法优于WinDBG环境变量方法的原因就在于Visual Studio只需要将服务器名共享名放入符号设置中就可以自动处理符号服务器。与先前版本比起来这是一个主要的改进,能使你的调试更简单。符号库本身并没有什么让人兴奋的。它只是一个使用文件系统查找文件的数据库。图2-7显示了是用Windows资源浏览器显示的符号服务器的部分文件树列表。根目录是OSSymbols,每个不同的符号文件,如Advapi32.pdb,都位于第一层子目录。在每个符号文件名下面是与GUID对应的目录,以识别那个符号文件的特定版本。记住,如果你有一个文件的多个版本,如Advapi32.pdb用于不同的操作系统版本,在Advapi32.pdb下就会有多个目录对应你曾经访问的每个唯一的版本。在对应的子目录下,就可以找到特定版本的符号文件。图2-7显示了Advapi32.pdb目录下的两个GUID值。如果你碰巧看见一个比GUID更短的目录名,那么这可能说明你正在调试来自Windows 2000的符号,由于早期Visual Studio 2005的编译器没有内嵌GUID,因此它们使用PE(Portable Executable)文件的校验作为仅有的识别特征。图2-7 符号服务器数据库的一个例子虽然当你调试时能下载符号,但是却无法下载二进制文件引入符号服务器。不仅如此,你可能需要对所有支持的版本用所有操作系统二进制和符号预填入符号服务器,而不是依赖开发人员的调试应用程序来获得符号。只有这样,你才能处理从客户返回的任何微型转储文件及在开发过程中遭遇的任何调试挑战。Debugging Tools for Windows(包括了WinDBG)包含两个非常有用的工具。第一个是符号检查器(Symchk.exe,Symbol Checker),它主要负责将来自微软的调试符号下载到你的符号服务器。第二个是符号库(Symstore.exe,Symbol Store),它主要负责将获得的二进制文件保存到符号库。当我意识到自己不得不同时运行这两个工具并将所有我想支持的操作系统版本的符号和二进制完全地填充到我的操作系统符号服务器时,我决定自动化这个过程。我希望快速建立操作系统符号服务器,并且毫不费力地用最新的二进制文件和调试符号填充。当你安装最初的操作系统符号服务器时,需要安装操作系统的第一个版本,并且不需要任何服务包或修补程序。你还需要安装Debugging Tools for Windows,并将安装目录添加到路径。为了获得该操作系统版本的二进制文件和符号文件,你需要运行我的Ossyms.js文件,稍后将讨论这个文件。当Ossyms.js运行结束时,你需要安装第一个服务包,并重新执行Ossyms.js。当你加载了所有的服务包,并复制了它们的二进制文件和符号后,你最后需要应用由Windows XP、Windows Vista和Windows Server 2003的Windows Update功能推荐的所有热修复并最后一次运行Ossyms.js。一旦你在所有想支持的操作系统中完成这个程序后,当你想安装修补程序或新的服务包来更新符号服务器时,只需运行Ossyms.js就可以了。对于磁盘空间的规划,需要为每个操作系统预留接近1GB的空间,而每个服务包所需的容量也差不多。在运行Ossyms.js之前,你需要更改执行Windows Script Hosting文件的程序,即把它从默认的Wscript.exe更改为Cscript.exe。Wscript.exe将通过消息框进行所有的输出,有了类似Ossyms.js的脚本或任何这种类型的其他脚本,你只需点击OK即可。用管理员特权打开一个命令提示行并执行下面这个命令,可将Cscript.exe设置为Windows Script Hosting执行程序:cscript /H:CScript to set你可能会认为Ossyms.js只是执行Symchk.exe和Symstore.exe的一个简单的包装,但实际上它是一个非常巧妙的封装。如果你查看这两个程序的命令行选项,肯定需要对它们进行自动调用,因为它们的用法很容易混淆。如果不用任何命令行参数执行Ossyms.js,你就能看见下面的输出,向你显示所有的选项:OSsyms - Version 2.0 - Copyright 2002-2006 by John Robbins Debugging Microsoft .NET 2.0 ApplicationsFills your Symbol Server with the OS binaries and symbols. Run this each time you apply a service pack/hotfix to get perfect symbols while debugging and for minidumps. SYMSTORE.EXE and SYMCHK.EXE must be in the path.Usage : OSsyms -e|-b|-s|-d - Symbol server in servershare or drive:dir format. -e - Do EXEs as well as DLLs. -d - Debug the script. (Shows what would execute.) -b - Dont add the binaries to the symbol store. -s - Dont add the symbols to the symbol store. (Not recommended)唯一需要的参数是服务器共享目录格式的符号服务器。Ossyms.js运行并循环地添加操作系统目录(%SYSTEMROOT%)下的所有DLL二进制文件。在复制了二进制文件之后,Ossyms.js调用Symchk.exe来自动下载所有这些DLL的符号。如果你还想添加所有的EXE二进制文件和关联的符号,可在符号服务器参数之后向Ossyms.js添加-e命令行选项。为了查看添加或忽略了哪些二进制文件和符号文件(以及为什么添加或忽略的原因),可以查看两个文本文件:DllBinLog.txt和DllSymLog.txt,它们能分别显示二进制添加结果和符号添加结果。对EXE文件来说,这两个文件分别是ExeBinLog.txt和ExeSymLog.txt。请注意,Ossyms.js需要很长时间运行。复制二进制文件到你的符号服务器很快,但是下载符号却很花时间。如果你下载DLL和EXE操作系统符号,可能需要下载400MB左右的数据。需要避免的一件事是要用多台电脑来同时向符号服务器添加二进制文件的情况。这是因为Symstore.exe程序使用文件系统和文本文件作为它的数据库,因此它不具备事务管理能力。Symchk.exe不会访问Symstore.exe文本文件数据库,因此由多名开发人员来添加符号是没有任何问题的。微软一直将更多的产品符号放在公共符号服务器上。Ossyms.js有足够的灵活性,这样你就能轻易地添加不同的目录,在这些目录中不仅有二进制文件,还有安装到符号服务器的符号。为了添加新的二进制文件,可以在Ossyms.js搜索g_AdditionalWork,这是在文件顶部定义的一个全局变量。Ossyms.js文件将g_AdditionalWork设置为null,这样它就不会在main例程上进行。为了添加新的一组文件,可分配一个Array类型并添加SymbolsToProcess类作为元素。下面的代码片段显示了如何添加处理所有出现在Program Files目录中的DLL文件。注意,第一个元素并不必须成为环境变量,它可以是一个指定的目录,如“C: Program Files”。使用公共的系统环境变量,你就能避免写死磁盘驱动器。var g_AdditionalWork = new Array( new SymbolsToProcess ( %ProgramFiles% , / Start directory. *.dll , / Searching wildcard. PFDllBinLog.TXT , / Binary logging file. PFDllSymLog.TXT ) / Symbol logging file.) ;注意,你已经看到如何获得操作系统的调试符号和二进制,下面开始讨论使用Symstore.exe将产品符号引入符号库中。Symstore.exe有很多的命令行转换。在表2-2中我列出了一些重要的转换。表2-2 Symstore.exe重要的命令行选项开关解释Add向符号库中增加文件Del从一个特别的集合中删除文件/f File增加特定的文件或目录/r递归地增加文件或目录/s Store符号库的根目录/t Product软件产品名称/v Version软件产品版本号/c附加注释续表开关解释/o输出调试信息/i ID从history.txt被删的ID/?输出帮助信息使用Symstore.exe最好的办法就是让它在每天的编译之后(在冒烟测试验证产品功能正常之后)、每个里程碑之后及发给工程师团队之外的每个版本中,在每个日常版本的底部自动添加生成树的EXE、DLL和PDB文件。你可能不想让开发人员将他们本机的编译结果增加进去,因为这会用上大量的磁盘空间。举个例子,如下命令将在D:BUILD目录下所有的PDB和二进制文件全部保存到你的符号库中。symstore add /r /f d:build*.* /s SymbolsProductSymbols /t MyApp /v Build 632 /c 01/22/06 Daily Build尽管添加文件时总需要/t(Product)选项,但不幸的是,/v(Version)和/c(Comment)却不是的。我强烈建议你总是使用/v和/c,因为对于产品符号服务器中的文件你总是不可能知道得很多,但当你的产品符号服务器装满的时候这就变得相当重要了。即使操作系统符号服务器中的符号由于没有私有的符号和类型而更小,但是软件产品的符号文件却更大,对6个月的项目来说要浪费很大一部分磁盘空间。我们通常希望,在符号服务器中留下各个里程碑编译的版本以及发送给工程小组之外的版本。另外,我还喜欢在符号服务器中保存最近4个星期的日常版本的符号和二进制。正如你在表2-2中看到的那样,Symstore.exe确实支持删除文件。为了保证删除了正确的文件,你需要在符号服务器的共享目录下查看一个特殊的目录000admin。在这个目录下是History.txt文件,它包括了发生在符号服务器中处理的所有事务,而且,如果你向符号服务器添加了文件,History.txt文件就包含了作为处理的一部分添加的实际文件列表的编号文件。History.txt是一个逗号分割的文本文件(CSV),所有的字段显示在表2-3(添加文件)和表2-4(删除文件)中。表2-3 History.txt 增加文件时的CSV字段字段解释ID事务号,10位数字,在符号服务器中最大可以有9 999 999 999笔事务Add在添加文件时,总是会显示AddFile or Ptr表明是否添加了一个文件(file)或一个指向存放于其他位置的文件的指针(ptr)续表字段解释Date事务的日期Time事务开始的时间Product从/t开关中得到的产品的文本Version从/v开关中得到的版本的文本(可选)Comment从/c开关中得到的注释的文本(可选)Unused预留作以后使用表2-4 History.txt 删除文件时的CSV字段字段解释ID事务号Del删除文件时,该字段显示为delDeleted Transaction删除过程的事务号一旦你找到了想删除的事务ID,那么告诉Symstore.exe执行任务就是一件简单的事情了。symstore del /i 0000000009 /s SymbolsProductSymbols我注意到一种情况有点奇怪,当从你的符号服务器上删除它们的时候,没有获得任何输出告诉你删除是否成功。事实上,如果你忘了一个关键的命令行参数,如符号服务器本身,你就不会被提醒而且会错误地认为删除已经发生了。因此,进行删除之后,我总是检查History.txt文件来保证删除确实发生了。如果你正在寻找一个好项目,考虑要做的事情可能是编写一个基于表格的应用程序来管理符号库中的符号。手动来查看服务器中的东西及删除旧版本的产品符号是非常单调乏味的。通过显示文件添加的日期及添加的文件的名字,你可以让删除变成一次单击就可以实现的选项。2.7 安装源代码服务器 2.7 安装源代码服务器安装符号服务器能帮你将本机代码中的调用堆栈取回并放入托管代码中,但是,如果你不知道源代码的版本,仍会在程序集语言的水平上调试。不管你的小组对版本控制系统是多么警惕,但是,有时当你调试版本的时候仍会不知道你需要的是哪个版本。即便你可能会得到较为相近的版本,但如果你想查看的那个修改并不在你所猜想的那个特定版本中,那么你也无法使问题得以解决。如果调试器能事先知道源代码版本并自动在代码窗口中显示正确的版本,那该有多好。如果调试器不用任何提示或输入就能获得源代码那不是更好吗?我不知道你是怎么想的,但是对我来说是尽善尽美的一件事。这就是源代码服务器工具所能做的。在讨论安装和使用源代码服务器之前,我不得不提醒你让源代码服务器工作也是有风险的。源代码服务器有一些Bug,而且缺少文档。但是,我已经试验了一个星期的时间梳理出你可能碰到的所有问题,所以对你有疑虑的地方我会帮你略过。源代码服务器之禅正如你所看到的那样,符号服务器实际上使用了文件系统的数据库。当你准备加载Foo.pdb时,调试器建立一个以缓存区目录开头的目录路径,附加在打开的文件上,并用GUID结尾来识别文件的特定版本。在那个目录路径中是调试器需要的实际的PDB文件。即使在名字中有服务器这个词,但是源代码服务器实际上不会像符号服务器程序保存PDB文件那样保存你的源代码。在用任何最新的编译器生成的PDB文件中保存有用来生成二进制的每个源文件的完整路径。当你在二进制文件上运行源代码服务器程序时,它们会向PDB文件添加一个片段,在这个片段中会内嵌由版本控制系统报告的精确文件版本。而且,它还会内嵌相应的版本控制命令从版本控制系统中获得那个文件。运行源代码服务器工具和在PDB文件中内嵌上述信息的过程被称为源代码索引。一旦你将版本和命令从版本控制系统中索引至PDB文件,不管你在公司的哪个位置,只要你访问过版本控制系统,调试器就会在版本控制系统中寻找正确的文件版本。在下文中我将介绍如何在PDB文件中查看这些信息。由于源代码服务器正在使用你的版本控制系统,它必须支持你正在使用的特定的版本控制系统。当你安装最新的源代码服务器二进制时,它能支持Perforce(http:/subversion.tigris. org/Subversion),以及随处可见的Visual SourceSafe。对包括Microsoft Team Foundation System在内的其他版本控制系统的支持将是短暂的。如果你使用不被支持的版本控制系统,那倒有一个好消息,就是源代码服务器工具是可扩展的,只要你的系统支持命令行工具来获得版本信息并取回源文件,你就能编写自己的模块来使用你的系统。在源代码服务器安装目录中你需要生成那个模块并整合到工具中。你应在源代码服务器安装目录中查看Srcsrv.doc文件。从最高级别来看,源代码服务器工作流是简单的。第一步很明显就是同时编译应用程序的调试和发布版本。在运行自动化的冒烟测试之后,你就能用源代码服务器程序为有版本控制信息的PDB文件添加索引。最后一步是将这些索引的PDB文件保存到你的符号服务器,这样对每个人都有好处。对于本章来说,我使用Visual SourceSafe,因为它是开发人员在Windows上使用的最常见的版本控制系统。而且源代码服务器编写的方式在不同的产品之间区别不大,因此,基本概念几乎是相同的。不管你使用哪个版本控制系统,我强烈建议你安装一些练习系统,这样你就能通过练习精通源代码服务器。当我提及源代码服务器二进制文件时,我指的是那些进行实际源代码索引的程序,调试器已经有了Srcsrv.dll,而Srcsrv.dll知道如何执行内嵌到PDB文件中的版本控制系统。源代码服务器二进制是Debugging Tools for Windows工具包的一部分,Debugging Tools for Windows能免费从/whdc/devtools/debugging/default.mspx下载。如果你准备在64位系统上运行你的代码,就能使用相应的64位调试器工具包,但是32位的版本在x64上也能工作。唯一的问题就是默认的Debugging Tools for Windows安装文件不会默认安装必要的源代码服务器二进制文件。你需要自定义安装Debugging Tools for Windows并选择SDK部分来安装。这会在Debugging Tools for Windows目录下添加一个SDK目录,在SDK目录内部包含了所有相应程序的SRCSRV目录。你可以把这个目录留在那里,并把你的路径指向这个目录或把这个目录复制到其他地方。无论如何,包含这个工具的目录应该在你的路径中。安装了自定义的Debugging Tools for Windows后,如果你的机器上没有Perl 5.6或更高的版本,你还需要进行安装。我使用的是Perl 5.8.7,你可以从/上下载。当你查看源代码服务器目录中的文件时,就能发现源代码服务器工具中的大部分工作都在Perl代码中。核心的批文件Ssindex.cmd调用Perl.exe并通过标准输出传送Perl代码。后辍为.pm的文件是知道如何描述单个版本控制系统的Perl模块,而Ssindex.cmd加载这些版本控制系统并通过调用标准的界面来隔离系统差异。其他的后辍为.cmd的文件,如VSsindex.cmd,是方便使用特定的版本控制系统的封装程序(wrapper),因为Ssindex.cmd需要命令行上的版本控制系统。SRCSRV目录中的Pdbstr.exe和Srctool.exe文件用于读写PDB文件,Vssdump.exe程序则帮助整合Visual SourceSafe。它只能用x86版本的Debugging Tools for Windows工具包进行安装。当你确认参数后运行Ssindex.cmd时,它会要求版本控制系统给出所有源文件列表及目标版本控制项目和所有子项目中的关联版本号。下一步就是开始循环查找PDB文件。对于每个找到的PDB文件,Perl代码调用Srctool.exe从PDB中获得源文件名字列表。代码在PDB中查找源文件名并查看它们是否匹配任何从版本控制搜索中保存的源文件名,如果匹配,就将这些文件信息保存到一个临时文件中。一旦代码查看了所有的源文件,就可以调用Pdbstr.exe将索引流,正确地说应该是SRCSRV写入PDB文件(注意,这个索引流不是NTFS文件系统流,而是PDB文件的一部分)。当调试的时候,调试器会查找这个索引流,如果找到它,调试器就会知道这里有源代码服务器并调用Srcsrv.dll来执行版本控制系统以获得正确的文件。对于当你索引源代码时所发生的事情,我只想向你提供一个概括的介绍。如果你对Ssindex.cmd更感兴趣,可以查看代码或Srcsrv.doc。如我早先提到的,如果Source Server不支持你的版本控制系统,只需编写与Srcsrv.doc中指定的界面一致的Perl模块。基础索引为了帮你了解手动使用源代码服务器的步骤,我会用一个非常简单的源代码树,这个源代码树由两个控制台应用程序CppApp和NetApp组成,这两个程序分别在相应命名的D:DevCppApp和D:DevNetApp目录中。CppApp是本机C+应用程序,而NetApp则用C#编写。我还要显示本机代码,因为大多数人现在仍然支持C+应用程序。这两个工具向D:DevDebug编译它们的Debug版本。Visual SourceSafe版本控制在共享TimonSource中,而CppApp和NetApp则作为$/的项目(这是Visual SourceSafe中的根项目)。注意,为了用Visual SourceSafe索引源文件,你需要在项目中设置活动的目录。我还会在项目中应用版本控制标签“First Version”。最后,编译这两个项目,现在它们已经可以用于索引了。第一步是确认Visual SourceSafe命令行程序(Ss.exe)、Perl和源代码服务器程序都在用于命令行程序的路径中。如果它们不在,就没有东西会工作。容易混淆的地方是当你开始调试的时候,如果版本控制程序不在路径中,源文件获取会失败,而你也不知道为什么你会在反汇编窗口中。另一个需要注意的地方是源代码服务器Visual SourceSafe代码。即使Source Server Help能指定服务器在命令行中使用,对Visual SourceSafe来说,它不能工作。你需要在Visual SourceSafe数据库中设置SSDIR环境变量。在我的例子中,我会在命令行提示中发布下面的命令:set SSDIR=TimonSourceVisual SourceSafe的另一个问题是当前项目的概念,当前项目是当你终止SourceSafe 资源管理器界面时选择的项目。Visual SourceSafe的源代码索引会“考虑”当前项目,这意味着它假设当前项目是你想工作的那个项目。如果你的版本控制系统中有一个项目,那确实很好,但实际上没人会这么做。为了让Visual SourceSafe索引进行工作,你需要在你准备索引的这个项目中设置Visual SourceSafe当前项目。对于命令行中的索引,你能用Ss.exe cp选项进行设置。在我的例子中,我运行下面这个命令,因为我用根项目进行工作:ss cp $/第二步是当索引时安装Srcsrv.ini,Srcsrv.ini包括为服务器定义逻辑名字和服务器路径。在C:Program FilesDebugging Tools for WindowsSDKSRCSRV目录中的Srcsrv.ini有更多你希望读到的文档。在我的Visual SourceSafe数据库中,我的Srcsrv.ini看起来如下(在Visual SourceSafe的情况下,等号右边的值应该符合SSDIR环境变量的值,包括尾部的反斜杠):variablesBOOKSRC=TimonSource在几乎所有的例子中,在索引阶段你只需要Srcsrv.ini文件。它将保存BOOKSRC逻辑名字和处理的PDB文件中服务器的实际位置。但是,如果机器TIMON死去而你需要将版本控制移到另一台机器,你可以把Srcsrv.ini文件放到和调试器Srcsrv.dll一样的目录中,这个文件的设置会重写内嵌到PDB文件中的源文件索引的内容,因此,你不需要重新索引PDB文件。调试中Srcsrv.ini文件的另一个用处是让调试器使用一个镜像的只提供只读访问的版本控制系统。这有助于你在公司的不同小组和不同部门之间共享源索引的PDB文件,而每个小组则无需直接访问其他小组的真正的版本控制系统。同时要注意的是,在variables一节下的Srcsrv.ini中包含公司所有的版本控制系统并在公司内部共享这个文件是完全可以接受的。在“用源代码服务器进行调试”一节中我将会讨论Srcsrv.ini的trusted commands部分。当索引时,Srcsrv.ini文件能停留在好几个地方。如果你已将源代码服务器代码目录复制到它自己的位置,就能把你的版本放在那里,而源索引工具会自动恢复。同时也可以把它放在执行索引命令的当前目录。最后,你也能使用命令行选项或设置SRCSRV_INI环境变量告诉源索引工具在哪里寻找Srcsrv.ini文件。对我来说,我会把它放在源代码的根目录(D:Dev)下并从那里运行所有的索引命令。为了开始索引,大多数人会设置命令行选项来告诉工具在哪里寻找源代码、符号等,因此讨论这些命令行选项就非常重要。既然使用Visual SourceSafe,我就会运行Vssindex.cmd来做我的索引,我也可以运行相同的Ssindex.cmd /System=VSS命令。有两个选项可以得到帮助:-? 和 -?,两个问号表明你可以得到更多的帮助。如果你查看这个帮助,就可以知道各种开关和环境变量是怎么去用的。对于Visual SourceSafe来说,有4个非常重要的命令行选项以及一个必要的命令行选项。第一个是/Ini,它指定将要使用的Srcsrv.ini文件。正如我所提到的,这个文件能被放在很多位置并能被自动搜索,但是如果你想指定文件,可以用/Ini来设置Srcsrv.ini文件。/Source转换选项会告诉索引工具源代码从哪里开始,默认情况下是当前目录。索引脚本会将这个指定的目录及其之下的任何源文件与版本控制系统中的文件相关联。/Symbols 转换选项指示寻找PDB文件被发现根目录,与源文件一样,这个目录默认为当前目录。如果PDB文件

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论