前言
熟悉.Net开发的朋友会知道,项目在编译时,除了可执行的.exe文件外,在运行目录常常会生成.pdb的文件,好多人都不知道这个文件是干什么用的,今天就详细介绍一下。
介绍
本文帮助那些处于初级或中级水平的开发人员,但是他们对PDBs的重要性以及为什么需要它们没有太多的理解。
什么是PDB
PDB是程序数据库文件的首字母缩写。
PDB文件通常是在编译期间从源文件创建的。它存储模块所有符号的列表,其中包含它们的地址,可能还有文件的名称和声明符号的行。
为什么PDB是一个单独的文件?
这些符号本来可以很容易地嵌入到二进制文件中,但反过来又会使二进制文件的大小变得更大(有时是几兆字节)。为了减少文件的大小,现代编译器和早期的大型机调试系统将符号信息输出到一个单独的文件中,对于Microsoft编译器,这个文件称为.PDB文件。
PDB文件包含什么?
以下是PDB文件存储的一些重要信息:
局部变量名——为了证明pdb包含局部变量名,我们将利用反射器将其pdb在与程序集相同的文件夹中进行反编译。反射工具有一个选项,称为“显示PDB符号”,如屏幕截图中所示,当检查时也加载相应的PDB用于该程序集。当您检查选项,你可以看到反编译的代码相同的变量名,你的实际代码,但在缺乏PDB或未经检查该选项时,局部变量反编译的代码中,字符型变量名会被替换成“str”,数值型的则是“num”等等。
源文件名字
源的行号。
源索引(后面部分解释)
要显示PDB包含源文件名称和源文件的行号(第2和第3),首先在相同的文件夹中运行以下控制台应用程序,然后删除PDB文件。
namespace UnderstandingPDBs { class Program { static void Main(string[] args) { try { int sum = Add(5, 10); decimal value = Divide(10, 0); } catch { } } private static int Add(int i, int j) { return i + j; } private static decimal Divide(int i, int j) { try { return i / j; } catch (Exception ex) { LogError(ex); throw ex; } } private static void LogError(Exception ex) { using (var txtWriter = new StreamWriter(@"dump.txt",true)) { string error = "Exception:" + ex.Message + Environment.NewLine + "StackTrace:" + ex.StackTrace if(ex.InnerException!=null) error=error+"INNER EXCEPTION:"+ex.InnerException; txtWriter.WriteLine(error); } } } }
如果目录中存在PDB文件,下面是应用程序抛出的异常:
Exception:Attempted to divide by zero. StackTrace: at UnderstandingPDBs.Program.Divide(Int32 i, Int32 j) in C:UsersRishiDocumentsVisual Studio 2010ProjectsUnderstandingPDBsProgram.cs:line 33
如果没有PDB文件,异常信息如下:
Exception:Attempted to divide by zero. StackTrace: at UnderstandingPDBs.Program.Divide(Int32 i, Int32 j) ---------
显然,带有PDB的文件显示了异常被抛出的类的行号和文件名。
调试器如何加载PDB ?
Visual Studio调试器假设PDB文件位于与DLL或EXE相同的文件夹下。每一次程序集编译生成唯一的PDB文件,这意味着,即使没有代码改变,也不能使用在以前的编译中创建的PDB文件。调试器通过将PDB中的特定GUID与二进制的GUID进行比较,发现PDB是否跟二进制文件相匹配。这个Guid在编译过程中嵌入到二进制和PDB中,并将PDB与二进制文件紧密连接。
Visual Studio中不同的Build设置。
Visual Studio有3种不同的Build选项,可以控制调试符号的生成:
none:PDB文件将不会生成。
pdbonly:调试符号只能在PDB文件中,而不是二进制文件中。
Full:与PDB二进制中的符号一起也包含一些调试符号。
Full是Visual Studio中设置的默认选项。
参考MSDN文档:
如果您使用/调试:full,请注意,JIT优化代码的速度和大小会受到一定的影响,并且对代码质量的影响很小。我们建议/调试:pdbonly或没有PDB来生成发布代码。
我们应该和二进制文件一起部署PDBs吗?
如果交付件的大小不是问题,最好将PDB和其他二进制文件一起部署,因为它有助于提供更多关于异常的信息,就像我们在上面的例子中看到的那样。这些PDBs对于某些用户在某些情况下会非常有用,因为某些用户没有PDB会使生活变得困难。
这并不是说您必须拥有PDBs和二进制部署来获得关于异常的额外信息。同样可以使用符号服务器和源索引来实现,我将在下面的主题中讨论。
和PDB安全风险吗?
任何使用DLL/EXE的人都可以很容易地进行反向工程,使用诸如反射器之类的工具来生成带有或不带PDB的源代码。因此,在这种情况下,不提供PDB将不会有多大帮助。
如果PDB被部署,并且用户无法访问二进制文件,那么向他们显示堆栈跟踪信息并让他们知道应用程序的内部信息不是一个好主意。
Symbol Server
符号服务器
符号服务器用来存储被调试器所知道的pdb文件,可以用来查找更详细的调用堆栈信息。
我们可以使用symstore.exe设置自己的符号服务器,它允许调试器找到与二进制相关的实际PDB。symstore.exe包含在窗口包的调试工具中。
微软还保留了符号服务器,我们可以通过从微软的符号服务器加载PDBs来使用它。
如何以及为什么加载微软符号存储?
当您在debug点和open Modules窗口停止执行时(如下所示),您将会发现所有的dll(外部或内部)加载到该断点之前,但是默认情况下的符号状态将显示“无法找到或打开pdb文件”,除了您的pdb。这些是Microsoft BCL二进制文件,因为我们的调试器找不到相关的PDBs,所以没有加载。
要加载这些符号,可以去Debugging->Symbols ,并检查微软的符号服务器,并将缓存符号作为任何共享文件夹在这个目录中提供,以便所有的开发人员都可以使用它。
由于这些二进制文件是您的应用程序之外的,所以您还需要在Debugging->General 菜单中取消 “Enable just my Code” 。
在下面的截图中,您可以看到我已经加载了符号,现在符号的状态显示了“Symbols loaded”。
这怎么有用呢?
您可以在代码中放置断点,并在没有加载符号的情况下查看调用堆栈。
下图显示了没有加载符号的调用堆栈,它只是将我的方法和BCL的方法显示为[外部代码]。
在加载了这些符号之后,调用栈将在断点之前显示所有的方法调用(参见下图)。当我们想知道调用的外部方法是什么时,它当然是有帮助的,这样它就可以使用反射器或调试拆解来分析,而在我们的应用程序中,由于外部代码而导致某些行为更改的任何特定问题。
与符号服务器一样,也有称为源服务器的东西,用于检索用于构建任何特定应用程序的源文件的确切版本。在构建时,二进制文件可以被索引,并且该信息存储在PDB文件中,它帮助源服务器找到确切的源文件。
您可以检查MSDN了解更多关于符号和源存储。
PDB文件是微软专有格式的文件,也没有提供什么文档详细介绍。因为微软并未公布PDB内部细节,所以对于这个文件一直是一个迷。
一切从一个"小黄片"的谎言开始,由各种入侵为过程,最后,谁能想到,机缘巧合中,竟扣开了一扇数亿元的黑产大门… 那个再平凡不过的夜里,我一如既往的用手机刷着新闻。点击了一篇名为“深圳房价下跌,…”的新闻。 就在我认真的关注房价时,弹出了这样的东西。 其实这种伪装成qq信息的链接早已经司空见惯...
你能相信,4年前发布的OPPO A5,在二手市场依旧是“神”一样的存在吗? 近日,转转集团发布的Q1手机行情报告显示,OPPO A5在二手市场继续续写销量神话,单机销量堪称“国产之光”。 对此,转转集团数据部的分析师认为,这不仅与OPPO A5本身的续航、颜值有关,还和OPPO...
炎炎夏日去上海旅游哪里好玩?除了外滩、东方明珠之外,今年暑期上海还有不少值得一去的新晋网红打卡地!不论是潮男潮女还是亲子带娃,都能找到适合自己的地方! ·上海天文馆:探索无垠宇宙的奥秘 天文迷们盼望已久的上海天文馆7月17日正式开馆!作为全球建筑规模最大的天文馆,绝对是近距离接...
快手和抖音是现在发展的比较好的短视频平台,越来越多的商家们开始利用这些平台达到带货的目的,也有很多的达人愿意利用自己的名气来接广告获取佣金,快手直播带货平台怎么收费?一、快手直播带 快手和抖音是现在发展的比较好的短视频平台,越来越多的商家们开始利用这些平台达到带货的目的,也有很多的达人愿意利用自己...
随着互联网的快速发展,网络推广已经成为许多企业推广销售的方式之一,对于商家而言,也是最有效的推广渠道了。网络推广渠道多种多样,下面为大家列举一下当前最常用的集中推广渠道:第一,搜 随着互联网的快速发展,网络推广已经成为许多企业推广销售的方式之一, 对于商家而言,也是最有效的推广渠道了。网络推广渠道...
随着搜索引擎系统的不断优化和完善,在当前互联网用户数量和使用频率不断增加的情况下,站点也越来越多的情况下,seo优化如何做好网站排名,让用户更能注意到我们呢?接下来小编就跟大家分 随着搜索引擎系统的不断优化和完善,在当前互联网用户数量和使用频率不断增加的情况下,站点也越来越多的情况下,seo优化...
现代潮流真的是变化太大,以往不是的主流单品开始成为女性的穿衣必备,还时常被拿来当作日常穿搭,真是叫人大开眼界,就拿睡衣来说吧,利用材质还有时尚元素的特殊性,让整个造型变得更加惊艳吸 现代潮流真的是变化太大,以往不是的主流单品开始成为女性的穿衣必备,还时常被拿来当作日常穿搭,真是叫人大开眼界,就拿睡...
看到有人将用了5年的AppleWatch一代转出去,还值三百块钱。这是几年前的产品,而且苹果公司每年都推出换代新品,到现在竟然还能值几百块钱。你觉得AppleWatch保值吗? 看到有人将用了5年的Apple Watch一代转出去,还值三百块钱。这是几年前的产品,而且苹果公司每年都推出换代新品,到...
武汉公积金利率下调至3.1%可以说是难得一见了,因为武汉公积金利率3.25%保持了很多年,如今下调后,每个月少还50元对个人来说也是一项不错的福利政策,原来在还房贷的朋友们需要等明年1月1日再正式执行。武汉公积金利率下调 武汉公积金利率下调至3.1%可以说是难得一见了,因为武汉公积金利率3.25%...
买奥迪A8的人基本都是老板级别的了,因为奥迪A8本身就不便宜,今年推出新款,也有很多营销出来。不过奥迪A8是属于比较低调的车型,同等价位的都会去买奔驰或者宝马了。买奥迪A8都是什么人奥迪A8的知名度不亚于奔驰S级,车子正 买奥迪A8的人基本都是老板级别的了,因为奥迪A8本身就不便宜,今年推出新款,...
羊血是比较少见的一种动物血液,它里面也含有丰富的营养成分,可以起到很不错的功效与作用,适量食用可以补血止血、祛瘀解毒等,补充人体所需的营养,但是服用不当,也可能会增加肠胃负担,引起消化不良以及肠胃不适。羊血的功效与作用及 羊血是比较少见的一种动物血液,它里面也含有丰富的营养成分,可以起到很不错的功...
iPhone14promax在官方直营店依旧没现货,包括京东或者天猫旗舰店,想买现货的朋友们在官网蹲到了吗?目前,iPhone14promax黄牛加价1200,可以自己卖赚点钱,如果自己加钱买的话就没必要了。iPhone iPhone14promax在官方直营店依旧没现货,包括京东或者天猫旗舰店,...
2022年12月30日入宅吉利吗是大家常问的,虽说搬家入宅和结婚相比甚是渺小,但是呢为了讨个吉利大家每每入宅的时候不仅会选个良辰吉日进行,而且还会有各种的习俗,下面小编就和大家一起看看11月23日乔迁入宅哪些是要注意的 2022年12月30日入宅吉利吗 是大家常问的,虽说搬家入宅和结婚相比甚是渺小...
寒露节气是一年之中比较特别的一个节气,一般是在每年十月初,这个时候的气温会慢慢下降,大多数地区不会出现高温天气了,开始进入秋天。根据相关信息显示,今年寒露节气的温度大概是20度左右,北方在10度左右。2022寒露温度大约 寒露节气是一年之中比较特别的一个节气,一般是在每年十月初,这个时候的气温会慢...
冬至烧纸钱是很多地区都有的习俗之一,但由于这是祭祀祖先,所以烧纸的时辰也成了大家茶余饭后讨论的焦点,下面小编就和大家一起看看2022冬至烧纸钱可以提前烧吗宜什么时间点烧。2022冬至烧纸钱可以提前烧吗看地方的讲究,毕竟十 冬至烧纸钱是很多地区都有的习俗之一,但由于这是祭祀祖先,所以烧纸的时辰也成了...