1/26/2007

Is Debug Mode Evil?

"On April 29, 1974 when the US Congress refused to authorize emergency funding to support our ally the South Vietnamese, that's when I stopped being a Liberal."
--Mort Kondracke


One of the difficulties in working with .NET, especially ASP.NET, is being able to determine whether an assembly has been compiled in Debug Mode or Release Mode, and especially whether an application is running in Debug Mode (e.g. debug="true" in the compilation element of web.config). This also applies to the Page level attribute, debug="true", in the @Page directive.

It is definitely evil if a production app is being run in debug mode - it will use a lot more memory, stuff that should be cached will not be cached, and a half dozen other generally "evil" things.

Recently I chimed in on a post by MVP Rick Strahl where he posts some code to determine "runtime" debug status via the HttpContext:


if (!HttpContext.Current.IsDebuggingEnabled)
Script = OptimizeScript(Script);




Wilco Bauwer states that this doesn't take the Page - level debug=true attribute into effect, since it basically encapsulates the web.config setting, and he suggests:


bool isDebuggingEnabled = Assembly.GetExecutingAssembly().IsDefined(typeof(DebuggableAttribute));



My suggestion offers another solution using the Global.asax.cs file and a static global application flag being set in the Application_Start event:


public static bool IsDebugMode = false;
protected void Application_Start(object sender, EventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached) IsDebugMode = true;


Rick replied that in his case he's not after knowing whether the user is actually running a debugger or not but rather whether the application is in Debug Mode. Like MS Ajax he is trying to send back Client script code and depending on the debug flag he either wants to mangle the script or not and add the appropriate browser caching flags (public vs. private) so that the content can refresh.

There are slight nuances in all of the above; it's probably a good idea to test your stuff with any or all of these and see what effect each has.

There is one other little item I've started to use. If you look in my assemblyinfo.cs files, you'll see this:


[assembly: AssemblyTitle("WhateverTheTitleIs")]
#if(DEBUG)
[assembly: AssemblyDescription("[DEBUG]")]
#else
[assembly: AssemblyDescription("[RELEASE]")]
#endif


I've started to do this with all my builds. Now, you can just right click on the assembly in Windows Explorer and look at the summary, and you'll see either "RELEASE" or "DEBUG". This really helps in making sure that you have not accidentally deployed an assembly built in debug mode into a production app, something that you really really want to be sure "NOT TO DO"! Bear in mind that it is possible to build a release build of an assembly and have the compiler still emit a PDB (program debug database) file so that your logging framework can report more information on exceptions.

You can also retrieve these properties programmatically through reflection, and have your app be able to "self report" on itself and all the assemblies it uses. If you want to get really creative, you could even add this information to the assemblyinfo VisualStudio project template file, and have it be there automatically for all your new assemblies.