views:

1820

answers:

20

We all know that "Debug Mode" should be used for development because compiler produces more debugging information and "Release Mode" should be used for production releases because the compiler produces optimized code.

However, lets say if you are making a software that is only used internally within the organization and code performance is not a huge issue because the software need to do a lot of file I/O and database queries. I will be very tempted to just release the software in "Debug Mode" in this scenario because those extra debugging information makes future maintenance a bit easier.

Are there still any compelling reason for releasing software in release mode in this case?

+4  A: 

I would guess that there is a lot more installed debug code out there than we (developers) are willing to admit.

Personally I know of lots of production systems that deploy to customers with code compiled in debug mode.

Alan Jackson
A: 

If it is a web site or service and performance is not an issue, then by all means release it in debug mode. If it's a desktop application then consider if the debug mode version is user friendly in how it handles errors. If it is then I would release the debug version as well.

Jeffrey Hines
+8  A: 

The mere fact that you're asking suggests there is a benefit of Debug Mode that you want to take advantage of. If these benefits outweigh your moral guilt, then I say go ahead and do it. These benefits are probably mechanical and informational and relevant to your work, while lack of guilt doesn't really help you produce better software. It might help you sleep better, but who cares?

Mark Canlas
+1  A: 

Depends on the user

If the user is technical, supplying an extra debug package for symbols may help them debug on your behalf or submit more technical bug information ... saving you money/time.

If the user is a home user ... they likely won't care if the debug information is there or not. Providing you strip out all your trace-cruft :)

If it is a business looking for a lean-mean no bloat machine, then give them a stripped version.

Depends on where your business/communication goals and constraints are.

Aiden Bell
+10  A: 

Possible reasons:

  1. Debug is not normally compiled for performance
  2. Debug application size (normally) is a lot greater than release compiles.
  3. If anyone tries to reverse engineer your application (for whatever reason) then it becomes a lot easier.

UPDATE: 4. As pointed out, linker performance but I would have thought would be way down the list :p How many times do you release a product compared to doing debug compiles?

If you are willing to forgo the above then there is no real reason why not.

Shane Powell
Don't forget linker performance ;)
Aiden Bell
He already stated that "code performance is not a huge issue" –one would assume "linker performance" even more so. Also, application size due to debugging info is irrelevant in the days of multi-GB hard disks (image and other resources for the app easily dwarf any debugging symbols).
foljs
@Shane: You pay linker performance at runtime if you're dynamically linking. That said, I don't understand how debug information would reduce linking performance, provided you also compile with function inlining (GCC for example lets you turn on optimized and debug at the same time).
Joseph Garvin
+1  A: 

You were platform independent in the question, but this advice on why not to put debug mode in production on ASP.Net demonstrates some of the (admittedly performance related) reasons not to do this.

1) The compilation of ASP.NET pages takes longer (since some batch optimizations are disabled)

2) Code can execute slower (since some additional debug paths are enabled)

3) Much more memory is used within the application at runtime

4) Scripts and images downloaded from the WebResources.axd handler are not cached

The last point is a bit of a perf killer for certain types of controls that are 'expected' functionality in a web2.0 world, even for internal apps. See ScottGu's article for further details on the costs of the last point.

Perhaps the best way to sum up the counter-argument is "it depends how you define code performance".

Tetsujin no Oni
+1  A: 

Compiling any application in Debug mode adds code to the application that is used (almost) exclusively by the compiler or IDE to debug, step through your code, etc. These debugging functions have virtually no use in real life. If you want to release an application to the public, your best bet is to compile it in Release mode. Furthermore, Release-built applications are...

  • Much faster and stable
  • Optimized for the machine
  • Smaller in size
  • More secure (harder to decompile / hack)
  • More efficient and easier on the hardware

If you have the option of a Release mode, why not use it? You'll always have the debug version for development, or if something goes wrong, and you can always package the Debug-built application and/or source code with your Release-built version.

Furthermore, you may also have the option of building the application for certain platforms. Compiling using Release mode will streamline the application for said platform, making it much more stable.

Even if speed is not an issue, there is no reason not to use Release mode when you compile.

Aethex
How does building in debug/release mode make an app more/less stable? If you have stability problems with switching between modes, I think there are deeper issues. Also the OP clearly gave his reason for preferring distributing Debug assemblies.
dss539
The point is that building in Debug mode puts proprietary code into the application. Code + useless code = bad. Furthermore, an application that was built for a specific architecture (e.g. 64-bit instead of 32-bit) is (theoretically) safer.
Aethex
A: 

I think it's important to follow good standards, practices, and procedures. Just because the application is only used internally is not a good reason to let yourself be lazy. Although I have strong feelings about the "right way" of doing things, I believe the habits of writing good software outweigh the benefits, in the long run, of cheating by using a debug release. Add some exception handling, learn the pitfalls of the systems you're coding against - it'll make all the code you write better.

overslacked
+2  A: 

extra debugging information makes future maintenance a bit easier.

It depends on what you mean by "extra debugging information."

If you mean debug messages, you probably should be using Trace, not Debug, and use trace switches and trace listeners defined in the configuration file to control logging behavior at runtime.

If you mean knowing the member name and line number when there's an exception, you don't need to distribute debug builds to get that information; just distribute the .pdb files with your executable. The Exception class uses information from the .pdb file irrespective of whether or not you've set any compilation constants.

Robert Rossney
+3  A: 

I have a vague recollection that if you take binaries compiled under Debug to a computer that doesn't have the debug C runtime libraries installed (which usually means it doesn't have an IDE, so most users fall into this category), it will barf with an error message. I don't know if that's specific to Windows and/or C++. I may also be misremembering... but you should certainly check to see if this happens, as if I'm right it would be a major reason to compile in release mode.

rmeador
Definitely an issue with Visual Studio, in that user machines won't have the DLL version of the debug C and/or C++ libraries installed. Easy to work around by linking the static version of the library, but that contributes to code bloat.
Mark Bessey
+14  A: 

Two concerns I can think of:

  1. Debug builds often add padding to buffers. That's why sometimes you get programs that seem to work in debug but crash in release. Seem is the operative word here, as buffer overflows are just an accident waiting to happen.

  2. Strange things happen in debug builds. I once worked on a long running application that would crash every twenty days or so. It turns out that in the C runtime a counter (used to aid debugging) was being incremented each time a malloc/free was performed. If the counter happened to overflow - kaboom! For this reason alone I would never recommend anyone deploy debug binaries - you just never know what surprises might be waiting for your customer.

Whoa! Good point in #2. Never thought about something like that.
Garrett
#2 is an interesting anecdote for sure, but I don't think it's a compelling reason to avoid deploying debug binaries; I think it's a good reason for debug options that change behavior to be independently toggle-able from plain old embedding function names and line numbers in the executable. GCC's stack protector option is a separate flag from its debug mode, for example.
Joseph Garvin
A: 

My decision tree goes like this:

Is the program written in Java?

Yes - Then release in debug mode is fine. The JIT will take care of optimizations

Otherwise - Is the program CPU Intensive?

No - Release in debug mode is fine.

Yes - Then compile only the hot spot in release mode.

The underlying rationale: It is much easier to maintain code when the bug reports are generated from the exact program as the one you are running in your IDE. In the IDE you use a debug version so you should strive to release in debug mode.

Itay
+5  A: 

I don't have any personal objection to shipping the Debug build internally, provided it works (some Debug versions won't work on non-dev machines w/o also installing the corresponding debug libraries... ran into that when I programmed C++/MFC code).

A slightly more sophisticated approach is to utilize a symbol server, one that is updated with symbols automatically by your build process.

If you were debugging an issue from a client's machine, point the light-weight debugger to your symbol server (make sure the versions match), and then start debugging.

Garrett
+1 for the symbol-server suggestion. But would this mean that you could not, for example, emit stack traces that include line numbers when logging exceptions?
harpo
Garrett
A simpler version of this is to keep binaries with debugger symbols in a special location and deploy binaries that have been stripped. You can strip a debug binary with the 'strip' command on Linux and probably other *nix.
Joseph Garvin
GDB will let you give it an executable and a core file. You can open the core with the unstripped executable, even if the core was produced by the stripped executable.
Joseph Garvin
+3  A: 

Use the release mode, but compile with all debugging information enabled and deploy the pdb files with the executables. You can debug the release binaries the same way as the debug ones - there is no difference, you just have to generate the pdb files when building.

Releasing and running the the debug build may be dangerous because it hides erros in your code that will come in release mode only.

devdimi
There IS a difference between debugging debug or release code, even with full debugging information in the pdb files. In debug mode a lot of no-ops are inserted to let the debugger breakpoint at certain points which will not be available in release builds. Also optimizations will result in the compiled code being different from the source code (e.g. it might skip over certain declarations or assignments deemed redundant).
Lucas
+1  A: 

I have mainly two problems with the debug release:

  1. Debug information might be a big and unnecessary insurance check for future maintenance that can be avoided by other means.
  2. Diagnostics is an aspect of your application that should have no relation to or dependency on the build configuration that you're building

I think it is important to design and keep instrumentation and diagnostics logic in your application as an aspect or cross-cutting concern. If you're relying too much on the information provided by the debug version of your code:

  • Can you guarantee that it will be the debug version that will be released each time a new version of your application is released? poor documentation, someone else doing it, etc.
  • Applications have a tendency to grow in functionality and complexity. While performance and size of your application due to debug version may not be an issue at the moment. Things may add up and lead to potential problems. In case of performance issues, you may not even attribute them to the debug release.

You can still collect valuable information in release version. Stack trace should still be available in case of exceptions. You may not see the source file and line numbers may be but you can still see which methods get called. You should however still produce and keep around debug symbols for your release build. These symbols will allow you to debug your release version (you can even set up a symbol server). Due to code optimization, debugging information will most likely not match 100% of the code e.g. debugging information referring to a statement that's optimized away, etc. but you should still be able to debug most of it ok. For other information, such as user input data, intermediate data, executed database code etc debug release won't help you anyways as it does not capture that information. You need to keep of track of those on your own.

If you're using .NET, you can take a look at Tracing and Instrumentation . You can also consider using an existing framework such as Microsoft Enterprise Library or log4net. If it is a .NET application, you can also request JIT-compiler to generate tracking information for the release version of your application as an option. Check out this MSDN article.

Mehmet Aras
A: 

Are you releasing the software? (This is a "Yes", "No" question, "Yes, but..." doesn't count)

If so, why not do it properly and make it a real release so that you don't have to rely on debug symbols being avaible for your users....

Server Horror
A: 

Here's what I typically do with software that needs to have debug information present (usually development type tools) - I compile my code optimized, but with symbol information, and link such that I keep symbol information. That way, when the software crashes, I can at least get a halfway-decent stacktrace and an idea of where to start putting extra logging information for when I ship the customer a full-debug build.

Sometimes the optimizer causes bugs, sometimes it obscures them, but at least you have the ability to narrow down your problem. This has worked wonders for me in blackbox environments such as Raytheon where getting a core dump was impossible, and the stack trace came faxed with big black marker all over it.

Chris Kaminski
A: 

Other than the already mentioned performance, size, and decompiling...

Security: Debug builds and debugging information (e.g. pdb files) contain lots of information about the source code which not only makes decompiling much easier, but can also let users know internal details such as as filenames and network paths. Many companies may consider this information to be very sensitive.

Lucas
A: 

release two versions, one labeled if bugs appear use this one ..

But depending upon the sensitive data lock the debug version away.

Fred Grott
A: 

I personally believe in a median solution between debug and release, that is, you log enough so you can reproduce the error if it happens. When your app is stable enough, turn off your extra spicy logging with a parameter in your config file. I realise it cannot be done all the time, though. Most often when you have your app running in at one place only.

Also, one golden rule which I've tried hard to implement in my workplace (and have not fully succeeded yet in doing): never ever EVER let your code show. If the user is tech savvy, he'll know what's going on and think poorly of you. If your user is not, he'll think his computer is possessed by the devil, and think poorly of you.

MPelletier