4

If the release version produces .pdb files and you can step into every line, put breakpoints etc then why ever bother to build a "debug" version of my components?

I'm using c# for my projects and i didn't have problem debugging release versions. In C++ i had problems debugging optimized code but in C# it works fine. I'm not talking about silly code blocks like if(false)...

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
Adi Barda
  • 3,259
  • 11
  • 32
  • 33

8 Answers8

8

The release builds are more optimized, e.g. when I debug release builds it annoys me that local variable's values disappear when their values are not going to be used by the runtime.

Grzenio
  • 35,875
  • 47
  • 158
  • 240
7

One reason is attach vs. launch.

If you launch a Retail process in .Net, the debugging is almost nearly as good as launching a Debug process. You will likely not notice any difference in your debugging experience.

Attach is a completely different ball game. Both C# and VB are passed the /optimize+ flag for retail builds. This will embed the DebuggableAttribute at the assembly level without the DebuggingMode.DisableOptimizations flag. During a process launch, VS / CLR, will communicate to essentially ignore this fact and disable JIT optimizationss that impact debugging. During attach, no such item happens and the JIT/CLR will optimize to it's hearts content. I guarantee you, the debugging experience is much worse in this case.

You can experiment with this in VS

  • Switch build to Release
  • CTRL+F5 to launch with no debugging
  • Attach to the process.
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
5

In (c#) winforms you cannot edit&continue in release builds..

Julian de Wit
  • 3,084
  • 2
  • 29
  • 29
3

Apart from the other answers, I use the automatically generated #define DEBUG to change behaviour when an uncaught Exception occurs:

  • If running in Release mode, show a nice message to the user and optionally log the error,
  • If running in Debug mode, don't do anything (which will cause a break to the debugger)
Lennaert
  • 2,455
  • 15
  • 15
2

There are a few reasons:

  • By default, a release build doesn't include as much debugging information in the PDB file. I believe the option for this used to be more prominent - it's now in the "Advanced settings" under Output, with possible values of "none", "full" (default for debug builds) and "pdb-only" (default for release builds).
  • By default, a release build is optimised: although this doesn't make nearly as much difference in C# as in other languages (e.g. C++) due to the JIT doing most of the work, there may well be some differences which make it harder to debug a release build.
  • By default, the release build doesn't define the DEBUG symbol, so any calls to Debug.Assert etc will be removed.

A lot of this can be changed in the build configuration, of course. One fairly common approach is to leave the default settings alone except for including more debugging information in a release build, which can give you more useful stack traces (and allow a better debugging experience if you do use the debugger).

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I believe you are incorrect on the first point. PDB's are included in the default config of VS for release build (verified with console app). It would be impossible to give locals information otherwise during debugging. – JaredPar Mar 11 '09 at 14:21
  • Now you have me curious. I don't know what full vs pdb-only would do to our PDB generation process. I don't think there is much / any item that is normally included that could be excluded for a PDB. Hopefully I'll have time to play around later and see. – JaredPar Mar 11 '09 at 14:38
  • I believe that in the older versions of VS (2003 for sure, 2005 possibly) pdb files were not generated for release builds (probably this is where you got it from) – Grzenio Mar 11 '09 at 14:49
  • @Grzenio, Can you verify that with 2003? – JaredPar Mar 11 '09 at 15:47
  • @Jared: Are line numbers in PDB-only? – Jon Skeet Mar 11 '09 at 15:53
  • @Jon, yes. PDB contains local variable info, line number mapping tables and namespace information. There is also other data in the PDB that I am unaware of. – JaredPar Mar 11 '09 at 16:37
  • @JaredPar: Building my ProtocolBuffers library, the PDB for the debug build is bigger than the PDB for the release build. My question about line numbers was whether they were included (in the PDB) even in "pdb-only" mode. – Jon Skeet Mar 11 '09 at 17:43
  • @Jon, yes they should be included in PDB-only mode. What's the size diff? – JaredPar Mar 11 '09 at 17:51
  • About 966K to 834K from memory. Hmm. I'll try to work out what the differences are based on experimentation. Local variable names? – Jon Skeet Mar 11 '09 at 18:03
  • Just verified: line numbers and local variables are in the pdb-only version. – Jon Skeet Mar 11 '09 at 18:05
  • @Jon, I believe at least part of the difference is the amount of DebuggerNonUser code and CompilerGenerated attributes that are present. Perhaps a few others. – JaredPar Mar 11 '09 at 18:41
  • Wouldn't those be size differences in the *assembly* file rather than the pdb file though? – Jon Skeet Mar 11 '09 at 19:06
  • @Jon Hmm. I want to say it can also affect PDB size but the reason is escaping me right now. – JaredPar Mar 11 '09 at 21:16
0

Release builds perform additional optimizations than debug builds, however a debug build also slightly changes the behavior of the GC to ensure that you don't get an object collected out from under you while you are in the middle of a debug session. Debug builds also prevent certain optimizations from occuring during JIT which will have a negative impact on your debug session.

Scott Dorman
  • 42,236
  • 12
  • 79
  • 110
0

I agree with Lennaert - I tend to do different error handling between the builds. For example, for some of the apps I am super anal in the debug build. Pre- and post-conditions, assertions, exceptions, etc. I basically am trying to force the developer to use my library correctly. In the release build, on the other hand, I relax the conditions to improve performance.

Filip Frącz
  • 5,881
  • 11
  • 45
  • 67
0

When you use Design by Contract, it is important to have two builds - the release one which doesn't check Preconditions, Postconditions and Class Invariants and the debug one which checks them (via assertions).

In some situations, Precondition checks may be left active in release mode (search for related questions), but that doesn't change the whole story.

In the development phase you check all of your contract assumptions, and when you release, you don't check them anymore - you know you have tested the code and it works, so you just rely on your previous assumptions - that's why they were intended for in the first place.

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116