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.aspx

一 什么是PDB文件

大部分的开发人员应该都知道PDB文件是用来帮助软件的调试的。但是他究竟是如何工作的呢,我们可能并不熟悉。本文描述了PDB文件的存储和内容。同时还描 述了debugger如何找到binay相应的PDB文件,以及debugger如何找到与binay对应的源代码文件。本文适用于所有的Native和 Managed的开发人员。
在开始前,我们先定义2个术语:private build, 用来表示在开发人员自己机器上生成的build;public build,表示在公用的build机器上生成的build。private build相对来说比较简单,因为PDB和binay在相同的地方,通常地我们遇到的问题都是关于public build。
所有的的开发人员需要知道的最重要的事情是”PDB文件跟源代码同样的重要“, 没有PDB文件,你甚至不能debugging。对于public build,需要symbol server存储所有的PDB,然后当用户报告错误的时候,debugger才可以自动地找到binay相应的PDB文件, visual studio 和 windbg都知道如何访问symbol server。在将PDB和binay存储到symbol server前,还需要对PDB运行进行source indexing, source indexing的作用是将PDB和source关联起来。 
接下来的部分假设有已经设置好了symbol server和source server indexing。TFS2010中可以很简单地完成对一个新的build的source indexing 和 symbol server copying。

二 PDB文件的内容

正式开始PDB的内容,PDB不是公开的文件格式,但是Microsoft提供了API来帮助从PDB中获取数据。
Native C++ PDB包含了如下的信息:
* public,private 和static函数地址;
* 全局变量的名字和地址;
* 参数和局部变量的名字和在堆栈的偏移量;
* class,structure 和数据的类型定义;
* Frame Pointer Omission 数据,用来在x86上的native堆栈的遍历;
* 源代码文件的名字和行数;
.NET PDB只包含了2部分信息:
* 源代码文件名字和行数;
* 和局部变量的名字;
* 所有的其他的数据都已经包含在了.NET Metadata中了;

三 PDB如何工作

当你加载一个模块到进程的地址空间的时候,debugger用2中信息来找到相应的PDB文件。第一个毫无疑问就是文件的名字,如果加载 zzz.dll,debugger则查找zzz.pdb文件。在文件名字相同的情况下debugger还通过嵌入到PDB和binay的GUID来确保 PDB和binay的真正的匹配。 所以即使没有任何的代码修改,昨天的binay和今天的PDB是不能匹配的。可以使用dempbin.exe来查看binary的GUID。
在VisualStudio中的modules窗口的symbol file列可以查看PDB的load顺序。第一个搜索的路径是binary所在的路径,如果不在binary所在的路径,则查找binary中hardcode记录的build目录,例如obj\debug\*.pdb, 如果以上两个路径都没有找到PDB,则根据symbol server的设置,在本地的symbol server的cache中查找,如果在本地的symbol server的cache中没有对应的PDB,则最后才到远程的symbol server中查找。通过上面的查找顺序我们可以看出为什么public build和private build的PDB查找不会冲突。
对于private build有时我们需要在别人的机器上debug的情况,需要将相应的PDB与binary一起拷贝,对于加入GAC的.NET的binary,需要将PDB文件拷贝到C:\Windows\assembly\GAC_MSIL\Example\1.0.0.0__682bc775ff82796a类似的binary所在的目录。另一个变通的方法是定义环境变量DEVPATH,从而代替使用命令GACUTIL将binary放入GAC中。在定义DEVPATH后,只需要将binary和PDB放到DEVPATH的路径,在DEVPATH下的binary相当于在GAC下。使用DEVPATH,首先需要创建目录且对当前build用户有写权限,然后创建环境变量DEVPATH且值为刚才创建的目录,然后在web.config,app.config或machine.config中开启development模式,启动对DEVPATH的使用
<configuration>
   <runtime>
      <developmentMode developerInstallation="true"/>
   </runtime>
</configuration>
在你打开了development模式后,如果DEVPATH没有定义或路径不存在的话会导致程序启动时异常"Invalid value for registry"。而且如果在machine.config中开启DEVPATH的使用会影响其他的所有的程序,所以要慎重使用machine.config。
最后开发人员需要知道的是源代码信息是如何存储在PDB文件中的。对于public builds,在运行source indexing tool后,版本控制工具将代码存储到你设置的代码cache中。对于private builds,只是存储了PDB文件的全路径,例如在c:\foo下的源文件mycode.cpp,在pdb文件中存储的路径为c:\foo\mycode.cpp。对于private builds可以使用虚拟盘来增加PDB对绝对路径的依赖,例如可以使用subst.exe将源代码路径挂载为V:,在别人的机器上debug的时候也挂载V:。

PDB文件:每个开发人员都必须知道的的更多相关文章

  1. 【vs调试】PDB 文件:每个开发人员都必须知道的

    [vs调试]PDB文件:每个开发人员都必须知道的 GDB:The GNU Project Debugger, 将会包含代码中符号(自定义变量, 数据类型), 还有函数调用或类引用的关联性, 有了pdb ...

  2. PDB文件:每个开发人员都必须知道的 PDB Files

    PDB文件:每个开发人员都必须知道的   PDB Files: What Every Developer Must Knowhttp://www.wintellect.com/CS/blogs/jro ...

  3. pdb文件 PDB文件:每个开发人员都必须知道的 .NET PDB文件到底是什么?

    pdb文件包含了编译后程序指向源代码的位置信息,用于调试的时候定位到源代码,主要是用来方便调试的. 在程序发布为release模式时,建议将 pdb文件删除, 同时,对外发布的时候,也把 pdb删除, ...

  4. 每个Java开发人员都应该知道的10个基本工具

    大家好,我们已经在2019年的第9个月,我相信你们所有人已经在2019年学到了什么,以及如何实现这些目标.我一直在写一系列文章,为你提供一些关于你可以学习和改进的想法,以便在2019年成为一个更好的. ...

  5. 每个Java开发人员都应该知道的4个Spring注解

    这是每个Java开发人员都应该知道的最重要的Spring注解.感谢优锐课老师对本文提供的一些帮助. 随着越来越多的功能被打包到单个应用程序或一组应用程序中,现代应用程序的复杂性从未停止增长.尽管这种增 ...

  6. 每个开发人员都应该知道的11个Linux命令

    本文主要挑选出读者有必要首先学习的 11 个 Linux 命令,如果不熟悉的读者可以在虚拟机或云服务器上实操下,对于开发人员来说,能熟练掌握 Linux 做一些基本的操作是必要的! 事不宜迟,这里有 ...

  7. 每个开发人员都应该知道的WebSockets知识

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://blog.bitsrc.io/deep-dive-into-websockets- ...

  8. HarmonyOS分布式任务调度开发之--你必须知道的bundleName

    背景 最近基于HarmonyOS在写一个通讯录的项目,已经完成了一个java版本的通讯录,通讯录数据全部存储在sqlite数据库中.现在在着手写一个JS版本的通讯录,这时候关于JS版本中数据的读取,我 ...

  9. 每一位想有所成就的程序员都必须知道的15件事(走不一样的路,要去做,实践实践再实践,推销自己,关注市场)good

    从 为之漫笔作者:为之漫笔 有超过 100 人喜欢此条目 原文地址:How to advance your career? Read the Passionate Programmer! 我刚看完Ch ...

随机推荐

  1. Zookeeper笔记(四)Zookeeper在Dubbo中的应用

    Zookeeper在Dubbo中的应用 Dubbo的架构 节点角色说明: Provider: 暴露服务的服务提供方.Consumer: 调用远程服务的服务消费方.Registry: 服务注册与发现的注 ...

  2. javascript二叉树基本功能实现

    都是常用的功能. 删除是最复杂的.. <!DOCTYPE html> <html lang="en"> <head> <meta char ...

  3. Java Hour 28 HashSet

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. Hour 28 HashSet 为查找而生 LinkedList查找效率低下, ...

  4. 2016.6.20 计算机网络复习要点第三章之CSMA/CD协议

    1.最早的以太网是将许多计算机都连接到一根总线上: (1)总线的特点是:当一台计算机发送数据时,总线上的所有计算机都检测到这个数据,这种就是广播通信方式: (2)为了实现在总线上的一对一通信,可以使每 ...

  5. json学习系列(6)JSONObject和JSONArray是JDK的集合部分延伸

    我一直觉得JSONObject和JSONArray是JDK集合部分的延伸,它们与JDK的List和Map一脉相承.通过研究JSONObject和JSONArray的结构,我们顺便也复习一下JDK的内容 ...

  6. Redis Key 命令

      Redis Key 命令     del key1 key2 - keyn 删除键为key1,key2-keyn,空格分隔. persist key 移除给定 key 的生存时间,将这个 key ...

  7. BST & Treap

    二叉查找树递归定义: 二叉查找树是空树或不是空树二叉查找树的左二叉查找树的值一定小于二叉查找树的值或左二叉查找树为空树二叉查找树的右二叉查找树的值一定大于二叉查找树的值或右二叉查找树为空树 不维护父亲 ...

  8. c#中的partial关键字(转)

    c#中的partial关键字 Partial:      这是C#2.0的新特性 Partial关键字起到把一个class分段组合作用,能用于多个接口或一个继承 代码片断: namespace Com ...

  9. winform学习-----理解小概念-20160518

    一.设置滚动,滚动列遮住内容的解决办法 1.datagridview三个属性:autosizecolumsmode none autosizeRowsmode   none dock  fill 2. ...

  10. jQuery加载外部文件的方式get、post、ajax、load的区别及异步加载的实现

    一.$.post(url, [data], [callback], [type])  url (String) : 发送请求的URL地址. data (Map) : (可选) 要发送给服务器的数据,以 ...