pdb文件,在.net项目中生成的pdb(程序数据文件)是什么文件?

前言

熟悉.Net开发的朋友会知道,项目在编译时,除了可执行的.exe文件外,在运行目录常常会生成.pdb的文件,好多人都不知道这个文件是干什么用的,今天就详细介绍一下。

介绍

本文帮助那些处于初级或中级水平的开发人员,但是他们对PDBs的重要性以及为什么需要它们没有太多的理解。

什么是PDB

PDB是程序数据库文件的首字母缩写。

PDB文件通常是在编译期间从源文件创建的。它存储 模块所有符号的列表,其中包含它们的地址,可能还有文件的名称和声明符号的行。

为什么PDB是一个单独的文件?

这些符号本来可以很容易地嵌入到二进制文件中,但反过来又会使二进制文件的大小变得更大(有时是几兆字节)。为了减少文件的大小,现代编译器和早期的大型机调试系统将符号信息输出到一个单独的文件中,对于Microsoft编译器,这个文件称为.PDB文件。

PDB文件包含什么?

以下是PDB文件存储的一些重要信息:

局部变量名——为了证明pdb包含局部变量名,我们将利用反射器将其pdb在与程序集相同的文件夹中进行反编译。反射工具有一个选项,称为“显示PDB符号”,如屏幕截图中所示,当检查时也加载相应的PDB用于该程序集。当您检查选项,你可以看到反编译的代码相同的变量名,你的实际代码,但在缺乏PDB或未经检查该选项时,局部变量反编译的代码中,字符型变量名会被替换成“str”,数值型的则是“num”等等。

在.net项目中生成的pdb(程序数据文件)是什么文件?

源文件名字

源的行号。

源索引(后面部分解释)

要显示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来生成发布代码。

在.net项目中生成的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,所以没有加载。

在.net项目中生成的pdb(程序数据文件)是什么文件?

要加载这些符号,可以去Debugging->Symbols ,并检查微软的符号服务器,并将缓存符号作为任何共享文件夹在这个目录中提供,以便所有的开发人员都可以使用它。

由于这些二进制文件是您的应用程序之外的,所以您还需要在 Debugging->General 菜单中取消 “Enable just my Code” 。

在下面的截图中,您可以看到我已经加载了符号,现在符号的状态显示了“ Symbols loaded ”。

在.net项目中生成的pdb(程序数据文件)是什么文件?

这怎么有用呢?

您可以在代码中放置断点,并在没有加载符号的情况下查看调用堆栈。

下图显示了没有加载符号的调用堆栈,它只是将我的方法和BCL的方法显示为[外部代码]。

在.net项目中生成的pdb(程序数据文件)是什么文件?

在加载了这些符号之后,调用栈将在断点之前显示所有的方法调用(参见下图)。当我们想知道调用的外部方法是什么时,它当然是有帮助的,这样它就可以使用反射器或调试拆解来分析,而在我们的应用程序中,由于外部代码而导致某些行为更改的任何特定问题。

在.net项目中生成的pdb(程序数据文件)是什么文件?

与符号服务器一样,也有称为源服务器的东西,用于检索用于构建任何特定应用程序的源文件的确切版本。在构建时,二进制文件可以被索引,并且该信息存储在PDB文件中,它帮助源服务器找到确切的源文件。

您可以检查MSDN了解更多关于符号和源存储。

PDB文件是微软专有格式的文件,也没有提供什么文档详细介绍。因为微软并未公布PDB内部细节,所以对于这个文件一直是一个迷。

本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:dandanxi6@qq.com

(0)
上一篇 2022-12-11 10:50
下一篇 2022-12-11 10:57

相关推荐

  • 来论|虚假繁荣的“超话榜”,还有存在的必要吗?

    在2019年的第29周,周杰伦在“微博明星超话榜”上排名超越流量偶像蔡徐坤,以1亿影响力跃居榜首。这场“超话榜”排名之争,瞬间引爆舆论。“如何打榜”、“如何做数据”等围绕明星流量的…

    2023-08-21
  • 西南财经大学专科

    近日有网友咨询西南财经大学天府学院转设更名情况,学校在2022年1月17日寄予了回复,根据学校介绍,正在积极进行独立学院转设迎检工作,目前尚未收到教育部来校评估具体时间。不过根据早…

    2022-12-02
  • 金枝欲孽结局好惨,金枝欲孽最后结局

    这座城,有的人想进去,有的人想出去,有的人在里面享尽荣华富贵,有的人丧命于此。 这部剧震撼我的地方非常多,有一个小细节,不知道有没有人注意。 安茜的同乡宫女素樱,被冤枉打碎送子观音…

    用户投稿 2023-09-16
  • 2019国家线,2019年考研国家线是多少分?

    研究生国家线公布时间即近,考生们最想知道的是今年的国家线会涨吗? 据小徐老师分析,国家线的上下浮动,受三个因素影响: 一、报考人数 2019年考研人数大幅度增加,比2018年增长4…

    2022-11-24
  • 初级职称评定,初级职称的认定资格是什么?如何申报?

    初级职称是中级职称申报的前提条件,除了部分高学历人员和特殊人才能够满足跨级申报条件之外,大多数普通人想要评中级职称,只能先评上初级职称,才有评中级的资格。 所以初级职称虽然等级较低…

    2022-12-01
  • 无锡市惠山区人武部政委

    国动委专业办公室开展演练,江苏省无锡市惠山区人武部—— 当好牵头人 拧成一股绳 吴建东 沈凯强 那场公路运输保障演练虽已过去10多天,江苏省无锡市惠山区交通战备办公室专职副主任蒋杏…

    2022-11-24
  • 《雍正王朝》中,如果十四阿哥继承皇位,八阿哥等人结局将如何

    雍正对付八爷,直接原因是八爷逼宫,即便如此,雍正也没有杀他,而是流放他。 假如十四爷继承皇位,以十四爷的性格和心胸,会采取比四爷更残酷的手段对付八爷,直接弄死不是没有可能。为什么这…

    用户投稿 2022-11-25
  • 如何给孩子选零食

    编者的话: 刚刚过去的“六一”儿童节,你给孩子买零食了吗?对很多孩子来说,零食大礼包无疑是一份颇具吸引力的儿童节礼物。然而,在不少家长看来,选购适合孩子的健康零食并非易事。海南日报…

    用户投稿 2023-04-20
  • 十二生肖为什么牛排名第二(十二生肖牛对应的时辰是几点)

    牛在十二生肖中为何排第二 金鼠辞旧岁,金牛报春时。说到牛,大家都再熟悉不过了。它在十二生肖中居次位,与十二地支配属“丑”,所以在十二生肖中,有子鼠,丑牛的说法。 那么牛为什么在十二…

    用户投稿 2023-03-22
  • dnf100巨剑怎么变光剑

    翻到了界巨剑继承到+12的苍穹光剑上?兄弟你应该是个萌新吧,你这么问跟脚踏车的车轮怎么安在新买的五菱宏光上面有什么区别,根本不是同一类型的武器,无法完成继承。 继承武器原则 首先如…

    2022-12-31