After a detour into Historical Debugging, it’s time to come back to return to answering questions about PDB files. Here’s a question from Justin:

Thanks for the great post once again. I was looking forward to your debugging virtual training, but unfortunately it was cancelled.

The company I work for is pushing pack against building release mode
binaries with debug information generated, one of the reasons I signed
up for the class :). They are afraid performance will be affected.


My question is what are the best command line arguments for
generating symbols in release mode? Also is there somewhere I can
reference to show that there should be no performance hits.

I’m sorry about the canceled class, but the good news is that Mastering .NET Debugging was rescheduled to July 14-15.

The executive summary answer: no, generating PDB files will have no
impact on performance whatsoever. As for references that I can point you
too, I haven’t found any on the web that answer the exact question so
let me take both .NET and native development in turn.

Recently, the always-readable Eric Lippert wrote a great post What Does the Optimize Switch Do?
where he discusses the optimizations done by the compiler and Just in
Time (JIT) compiler. (Basically, you can sum it up as the JITter does
all the real optimization work.) There’s a bit of confusion on the C#
and VB.NET compiler switches around as there are four different /debug
switches, /debug, /debug+, /debug:full, and /debug:pdb-only. I
contributed to that confusion because I thought /debug:pdb-only did
something different that was better for release builds than the other
three /debug switches.

All four switches all do the same thing in that they cause a PDB file
to be generated but why are there four switches to do the same thing?
Do Microsoft developers really love parsing slightly different command
line options? The real reason: history. Back in .NET 1.0 there were
differences, but in .NET 2.0 there isn’t. It looks like .NET 4.0 will
follow the same pattern. After double-checking with the CLR Debugging
Team, there is no difference at all.

What controls whether the JITter does a debug build is the /optimize switch. Building with /optimize- will add an attribute, DebuggableAttribute, in the assembly and setting the DebuggingMode
parameter to DisableOptimizations. It doesn’t take a Rhodes Scholar to
figure out that DisableOptimizations does exactly what it says.

The bottom line is that you want to build your release builds with
/optimize+ and any of the /debug switches so you can debug with source
code. Read the Visual Studio documentation to see how where to set those switches in the different types of projects.

It’s easy to prove these are the optimal switches. Taking my Paraffin program, I compiled one build with /optimize+ and /debug, and another with just /optimize+.

which is the same as /debug+ and /debug, and the other with /optimize+ /debug:pdbonly to show the differences, which is the root of how we got it wrong. After compiling, I used ILDASM with the following command line to get the raw information from the binaries

ILDASM /out=Paraffin.IL Paraffin.exe

Using a diff tool you’ll see that the IL itself is identical between both builds. The main difference will be in the DebuggableAttribute declaration for the assembly. When built /optimize+ and a /debug switch, a DebuggingMode.IgnoreSequencePoints is passed to the DebuggableAttribute to tell the JIT compiler that it doesn’t need to load the PDB file in order to correctly JIT the IL. A value of DebuggingMode.Default is also OR’d in, but that value is ignored.

Like .NET, building PDB files has nothing to do with optimizations so have zero impact on the performance of an application. If you have a manager who in Justin’s words is “afraid performance will be affected” here’s what I tell them.  (Sadly, I’ve run into a few more managers who say that than I care to count).

That might be true on other operating systems, but not Windows. If you think they do, then why does Microsoft build every single product they ship with PDB files turned on for both debug and release builds? They wrote the compiler, they wrote the linker, and they wrote the operating system so they know exactly what the effects are. Microsoft has more people focused on performance than any other software company in the world. If there were any performance impact at all, they wouldn’t do it. Period. Performance isn’t the only thing at Microsoft, it’s everything.

Where .NET is pretty simple as there’s really only two switches, the appropriate optimization switches are dependent on many individual application factors. What I can tell you is what the switches you need to set to generate PDB files correctly in release builds.

For CL.EXE, the compiler, you need to add /Zi to have it put debugging symbols into the .OBJ file. For LINK.EXE, the linker, you need to specify three options. The first is /DEBUG, that tells the linker to generate a PDB file. However, that switch also tells the linker that this is a debug build. That’s not so good because that will affect the performance of your binary. Basically what happens when you use /DEBUG is the linker links faster because it no longer looks for individual references. If you use one function from a OBJ the linker throws the whole OBJ into the output binary so you now have a bunch of dead functions.

To tell the linker you want only the referenced functions, you need to add /OPT:REF as the second switch. The third switch is /OPT:ICF, which enabled COMDAT folding. There’s a term you don’t hear every day. Basically what this means is that when generating the binary, the linker will look for functions that have identical code and only generate one function but make multiple symbols point to the one function.

If you want to test the difference yourself on a native binary to see what affects generating PDB files will have, it’s nearly as easy as a .NET binary. Visual Studio comes with a nice little program, DUMPBIN, which can tell you more than you ever wanted to know about a Portable Executable file. Run it with /DISASM switch to get the disassembly of a binary.

Please keep those PDB related questions coming. Of course, if you have any other questions, I’ll be happy to take a crack at those also. Gee, I better draw the line: no investment or relationship questions. <grin>

Do PDB Files Affect Performance?的更多相关文章

  1. PDB Files: What Every Developer Must Know

    Reference:  http://www.wintellect.com/blogs/jrobbins/pdb-files-what-every-developer-must-know Most d ...

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

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

  3. PDB files out of the debugger

    我想我不需要强调在调试时拥有有效的PDB文件有多重要.通常,PDB文件是由调试器静默加载的,并且您很高兴在modules窗口中看到解析的所有符号.不幸的是,您还可能遇到调试器找不到匹配符号的情况.其原 ...

  4. Why is Visual Studio 2015 not able to find or open PDB files?

    first change parameters, Tools->Options->Debugging->Symbols->Microsoft Symbol Server, ye ...

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

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

  6. 【C# 调试】.net中的 .pdb文件是什么,有什么用

    mscn:在 Visual Studio 调试器(C#)中指定符号 (.pdb) 和源文件 PDB全称Program Database,程序数据库 ( .pdb) 文件(也称为符号文件)将项目源代码中 ...

  7. 网站发布IIS后堆栈追踪无法获取出错的行号

    一.问题起因 系统发布上线后,有时会发生错误,那么错误的记录就很重要,它对于错误的排查和问题的发现有着重要的作用,通常我们采取的方式为Log日志文件记录和数据库错误记录.文本不会讨论错误记录的方式以及 ...

  8. PostgreSQL Hardware Performance Tuning

    Bruce Momjian POSTGRESQL is an object-relational database developed on the Internet by a group of de ...

  9. Chapter 6 — Improving ASP.NET Performance

    https://msdn.microsoft.com/en-us/library/ff647787.aspx Retired Content This content is outdated and ...

随机推荐

  1. 藏书馆App基于Rainbond实现云原生DevOps的实践

    我们需要的不是精通Kubernetes的工程师,我们需要一款小白都能用好的管理工具. -- 厦门正观易知科技有限公司运维负责人 郭传壕 大家好,我是厦门正观易知科技有限公司运维负责人郭传壕. 藏书馆是 ...

  2. Redis 很屌,不懂使用规范就糟蹋了

    这可能是最中肯的 Redis 使用规范了 码哥,昨天我被公司 Leader 批评了. 我在单身红娘婚恋类型互联网公司工作,在双十一推出下单就送女朋友的活动. 谁曾想,凌晨 12 点之后,用户量暴增,出 ...

  3. webpack--css、html 和 js 代码的常用处理

    前言 本文来总结下webpack中 css.js.html 代码常见的处理方式,学习笔记仅供参考. 正文 1.css样式文件处理 (1)提取css为一个单独的文件 在我们前面学习了webpack的基础 ...

  4. python函数理解 json.dump()

    信息来自python说明文档(https://docs.python.org/3/library/json.html) 函数功能 输出一个python对象到文件 函数声明 json.dump(obj, ...

  5. Pacbio三代基因组组装简介

    参考: 视频PPT来自欧易生物讲座:如何开启一个动植物基因组三代de novo项目?

  6. pheatmap() 的热图制作

    1.数据准备 2.画图 3.参数调整 (转自百迈克公众号) 关注下方公众号可获得更多精彩

  7. C/C++ Qt 数据库QSql增删改查组件应用

    Qt SQL模块是Qt中用来操作数据库的类,该类封装了各种SQL数据库接口,可以很方便的链接并使用,数据的获取也使用了典型的Model/View结构,通过MV结构映射我们可以实现数据与通用组件的灵活绑 ...

  8. .NET Core基础篇之:集成Swagger文档与自定义Swagger UI

    Swagger大家都不陌生,Swagger (OpenAPI) 是一个与编程语言无关的接口规范,用于描述项目中的 REST API.它的出现主要是节约了开发人员编写接口文档的时间,可以根据项目中的注释 ...

  9. SpringBoot Profiles 多环境配置及切换

    目录 前言 默认环境配置 多环境配置 多环境切换 小结 前言 大部分情况下,我们开发的产品应用都会根据不同的目的,支持运行在不同的环境(Profile)下,比如: 开发环境(dev) 测试环境(tes ...

  10. Oracle——生成Awr报告

    Oracle--生成Awr报告 AWR的概念 Oracle数据库是一个使用量很多的数据库,关于Oracle数据库的性能.Oracle10g以后,Oracle提供了一个性能检测的工具:AWR(Autom ...