前言
熟悉.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内部细节,所以对于这个文件一直是一个迷。
又跟大家见面了,今天小编就来给大家送上三国塔防蜀传攻略之第十五关图文攻略,今天爆发啦,请大家继续关注! 1 今天第十五关就是收服马超法正啦,张鲁没想到派出马超是肉包子打狗有去无回呀。 2 这一关出场钱数比较多,我们先把张飞放到中间路线上,在上面进攻路线放置一个3级枪兵,一个3级弓兵,一个3级术士。...
6 年前,的上线,几乎是一夜之间,拉动了微信用户绑定了 2 亿张银行卡,生生从阿里看似固若金汤的地盘上抢下山头,如今已是分庭而治之势。 此事给阿里带来的震动是核弹级别的,本以为已经结束的网络支付战争硝烟再起,马云痛斥此事为「珍珠港偷袭」,可见微信红包的奇袭打得阿里有多痛。反过来也说明,微信红包这一...
一切从一个"小黄片"的谎言开始,由各种入侵为过程,最后,谁能想到,机缘巧合中,竟扣开了一扇数亿元的黑产大门… 那个再平凡不过的夜里,我一如既往的用手机刷着新闻。点击了一篇名为“深圳房价下跌,…”的新闻。 就在我认真的关注房价时,弹出了这样的东西。 其实这种伪装成qq信息的链接早已经司空见惯...
Hugging Face公司的提供了向全网开放DALL·E Mini的demo。输入一个英文描述,生成对应的图片,可以天马星空的描述,比如:A zebra that looks like a corgi(看起来像柯基犬的斑马),或者Court sketch of godzilla on tr...
讲真,如果说你安装监控的地方没有WiFi,没有无线网络,有想要远程查看实时视频,这种情况下有没有符合条件的摄像头呢?不要怀疑,这种还真的有。毕竟在科技高度发展的今天,上太空的飞船都造出来,还造不出这种物联网技术运用的无线传输设备吗?所以,今天速名网要说到的话题就是在没有网络的情况下,我们可以...
近期,在抖音热评上面总是看到有网友评论主线任务夺回秋雅,很多人看到都很懵,不知道夺回秋雅到底是什么梗什么意思,不用担心,久久派为您带来详细介绍啦!夺回秋雅是什么梗9月15日有博主发了8bit版本的一剪梅曲子风格非常像红 近期,在抖音热评上面总是看到有网友评论主线任务夺回秋雅,很多人看到都很懵,不知...
随着互联网的高速发展,企业网站建设早已成为企业运营的一种必要手段。企业拥有一个自己的官网是非常重要的,也是一个企业互联网战略的基础。任何一个企业都应该有一个属于自己的网站,这个网站 随着互联网的高速发展,企业网站建设早已成为企业运营的一种必要手段。企业拥有一个自己的官网是非常重要的,也是一个企业互...
在之前的文章中,作者和大家聊了一系列关于我国河北省各个城市区划形成的故事,例如石家庄市、保定市、邯郸市等等。今天,我们聊聊河北省的沧州市,沧州市经济发达、人口众多,属于河北省的第三 在之前的文章中,作者和大家聊了一系列关于我国河北省各个城市区划形成的故事,例如石家庄市、保定市、邯郸市等等。今天...
三联屏封面的设置首先,保存一张三联屏封面的底图下载一个叫美图秀秀的软件,点开美图秀秀,在首页点击图片美化然后选择我们刚刚保存好的底图,点击进去,然后选择底下工具栏里的编辑功能进入之 三联屏封面的设置 首先,保存一张三联屏封面的底图 下载一个叫美图秀秀的软件,点开美图秀秀,在首页点击图片美化...
虽然很多人非常喜欢翡翠,但他们担心翡翠首饰的选择。翡翠作为最具东方魅力的首饰,一直以优雅典雅为标志。如果珠宝很差,很容易出国。今日来看看这些翡翠分配的忌讳,翡翠朋友在日常佩戴时一定 虽然很多人非常喜欢翡翠,但他们担心翡翠首饰的选择。翡翠作为最具东方魅力的首饰,一直以优雅典雅为标志。如果珠宝很差,很...
百度到目前为止拥有超过8亿万用户,是巨大的流量池,利用好它可以帮助广告主实现产品的变现和产品的转化。所以,我们一起来看下关于百度产品推广效果这方面的知识点吧。一、百度产品推 百度到目前为止拥有超过8亿万用户,是巨大的流量池,利用好它可以帮助广告主实现产品的变现和产品的转化。所以,我们一起来看下...
(本文由公众号越声策略(yslc188)整理,仅供参考,不构成操作建议。如自行操作,注意仓位控制和风险自负。)今天给大家分享的指标是关于OBV的指标,这里特命名为“极品OBV”,该指标是由OBV演变而来,还是非常具有借鉴 (本文由公众号越声策略(yslc188)整理,仅供参考,不构成操作建议。如自...
武汉公积金利率下调至3.1%可以说是难得一见了,因为武汉公积金利率3.25%保持了很多年,如今下调后,每个月少还50元对个人来说也是一项不错的福利政策,原来在还房贷的朋友们需要等明年1月1日再正式执行。武汉公积金利率下调 武汉公积金利率下调至3.1%可以说是难得一见了,因为武汉公积金利率3.25%...
转眼一个月又过去了,2022年已经过去一半。按照惯例,今天芝麻科技讯更新一下手机CPU天梯图。本月芯片厂商发布的新处理器不多,所以文章相对简单一些,手机CPU天梯图2022年6月最新版来了,快来看看都有哪些新变 转眼一个月又过去了,2022 年已经过去一半。按照惯例,今天芝麻科技讯更新一下手机CP...
2022年12月30日入宅吉利吗是大家常问的,虽说搬家入宅和结婚相比甚是渺小,但是呢为了讨个吉利大家每每入宅的时候不仅会选个良辰吉日进行,而且还会有各种的习俗,下面小编就和大家一起看看11月23日乔迁入宅哪些是要注意的 2022年12月30日入宅吉利吗 是大家常问的,虽说搬家入宅和结婚相比甚是渺小...