前言
熟悉.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内部细节,所以对于这个文件一直是一个迷。
团队建设的好坏 ,象征着一个企业后继发展是否有实力 ,也是这个企业凝聚力和战斗力的充分体现。团队建设首先应该从班子做起 ,班子之间亲密团结 ,协作到位 ,管理者心里始终要装着员工 ,支持员工的工作 ,关心员工的生活 ,用管理者的行动和真情去感染身边的每位员工 ,平时多与员工沟通交流 ,给员工以示范性...
因为比较受到环境限制,所以小城市可落地的项目真的不是很多,你会发现,小城市,人流基本都聚集在学校附近,或者景区附近,或者儿童游乐场,这些地方,并且大多数的孩子是由爷爷奶奶来照顾的,所以消费能力基本比较有限制,所以能落地的,就会较少了。 看市场 前面我们有说到过,小城市,基本都是爷爷奶奶在照顾...
你能相信,4年前发布的OPPO A5,在二手市场依旧是“神”一样的存在吗? 近日,转转集团发布的Q1手机行情报告显示,OPPO A5在二手市场继续续写销量神话,单机销量堪称“国产之光”。 对此,转转集团数据部的分析师认为,这不仅与OPPO A5本身的续航、颜值有关,还和OPPO...
在淘宝上购物的次数多了之后难免会有需要换货的情况,因为现在很多店铺的规格太多了,一不小心就可能下错单,导致需要换货,很多人还不知道怎么去进行换货,下面说说淘宝换货的流程吧。我们如果 在淘宝上购物的次数多了之后难免会有需要换货的情况,因为现在很多店铺的规格太多了,一不小心就可能下错单,导致需要换货,...
三联屏封面的设置首先,保存一张三联屏封面的底图下载一个叫美图秀秀的软件,点开美图秀秀,在首页点击图片美化然后选择我们刚刚保存好的底图,点击进去,然后选择底下工具栏里的编辑功能进入之 三联屏封面的设置 首先,保存一张三联屏封面的底图 下载一个叫美图秀秀的软件,点开美图秀秀,在首页点击图片美化...
闲鱼是阿里巴巴旗下闲置交易平台。使用淘宝或支付宝账户登录,无需经过复杂的开店流程,即可达成包括一键转卖个人淘宝账号中“已买到宝贝”、自主手机拍照上传二手闲置物品、以及在线交易等诸多 闲鱼是阿里巴巴旗下闲置交易平台。使用淘宝或支付宝账户登录,无需经过复杂的开店流程,即可达成包括一键转卖个人淘宝账号中...
随着搜索引擎系统的不断优化和完善,在当前互联网用户数量和使用频率不断增加的情况下,站点也越来越多的情况下,seo优化如何做好网站排名,让用户更能注意到我们呢?接下来小编就跟大家分 随着搜索引擎系统的不断优化和完善,在当前互联网用户数量和使用频率不断增加的情况下,站点也越来越多的情况下,seo优化...
(本文由公众号越声策略(yslc188)整理,仅供参考,不构成操作建议。如自行操作,注意仓位控制和风险自负。)今天给大家分享的指标是关于OBV的指标,这里特命名为“极品OBV”,该指标是由OBV演变而来,还是非常具有借鉴 (本文由公众号越声策略(yslc188)整理,仅供参考,不构成操作建议。如自...
十月初一送寒衣是很多北方地区都有的习俗,但由于该节日作为四大鬼节之一,所以很多讲究都会出现在我们生活中,那么2022年寒衣节的禁忌可信吗成了很多人都有的疑问,下面小编就和大家一起看看。2022年寒衣节的禁忌可信吗见仁见智 十月初一送寒衣是很多北方地区都有的习俗,但由于该节日作为四大鬼节之一,所以很...
板栗是生活中比较常见的一种食物,它吃起来粉粉糯糯的,含有多种营养成分,适量食用对身体有一定好处。板栗一般要吃熟的,不建议吃生的,半生半熟的板栗也可以吃,但是不容易消化,可能会引起肠胃不适。红薯和螃蟹可以一起吃吗红薯和螃蟹 板栗是生活中比较常见的一种食物,它吃起来粉粉糯糯的,含有多种营养成分,适量食...
窦性心律不齐是心脏的一种表现,这个是属于正常的,大家也不用太担心,这和自己的心理情况也有很大的关系。那么,窦性心律不齐会引起胸闷气短呼吸困难吗?窦性心律不齐有什么危害?一起来看看久久派带来的详细介绍吧!窦性心律不齐会引 窦性心律不齐是心脏的一种表现,这个是属于正常的,大家也不用太担心,这和自己的心...
红薯是生活中比较常见的一种食物,它的吃法比较多,营养价值高,含有丰富的膳食纤维、矿物质以及其他微量元素等,很多人都会煮红薯吃。煮熟的红薯吃不完是可以放冰箱冷藏的,一般可以放三五天左右,具体看保存的方法。煮熟的红薯能放冰箱 红薯是生活中比较常见的一种食物,它的吃法比较多,营养价值高,含有丰富的膳食纤...
蜜蜂保存方法和注意事项,蜜蜂如何保存。小编带你了解更多相关信息。 1、蜂蜜中富含有机酸等酸性物质,事实上蜂蜜的pH值介于3~4之间,因此不能用铜、铁等金属容器长期储存,否则蜂蜜容易因氧化反应而提前变质,长期储存蜂蜜最好的容器是陶瓷容器和玻璃容器,另外干净且无毒的塑料容器也适合用来储存蜂蜜。...
我们平时用的手机微信由于长时间没有清理,保存有很多的聊天数据,导致内存不够,如果遇到一些16G或者手机内存不大的手机,微信运行久了,就会变得很慢,我们可以通过以下3种方法给手机省点内存。方法很简单,请往下看…… 操作方法 01第一、打开微信,点击微信页面“我”→“设置”→“通用”,然后选择...
怎样才能快速练好劈叉,快速练好劈叉的技巧。小编带你了解更多相关信息。 1、先做热身活动,先跳绳五分钟,不要太快也不要太慢,保持心率在110~130之间,然后,把身体的腰部,膝盖,脖子这三个部位旋转一下,放松一下身体肌肉,防止拉伤。先试着将腿放到适当的高度,窗户,墙壁等。一般16岁以上的建议采用...