If you do one or both of the above it can cause a number of non-optimal things to
happen including:
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
5) When debug is set to true, asp.net requests will not time out. This is for easier
debugging but you don't want it in production!
If you have debug=true, you create one assembly dll per aspx, asax, or ascx page
and this dll is compiled in debug mode, so if you have 100 web pages, you will
have 100 assemblies, and they are generated as the pages are requested.
With debug=false, everything gets batch compiled into a single assembly (with some
exceptions). This means less overhead in your app.
So how can you be sure that your deployed app is OK without having to jump through
hoops? I've created a simple "script only" (no codebehind) page
that you can drop into any production web app. It will report any debug-built
assemblies, and also will report on the setting of your compilation element in
web.config to let you know if debug=true or debug=false.
To get an understanding of how I engineered this, we need to look at the differences
between release build and debug build assemblies as shown in Reflector:
DEBUG
// Assembly debugcheck, Version 1.0.0.0
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyTitle("debugcheck")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("debugcheck")]
[assembly: AssemblyCopyright("Copyright \x00a9 Microsoft 2011")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("18ee114d-54a6-43c3-8613-29dd338c7adb")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.0", FrameworkDisplayName=".NET
Framework 4")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.EnableEditAndContinue | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.Default)]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows=true)]
RELEASE
// Assembly debugcheck, Version 1.0.0.0
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyTitle("debugcheck")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("debugcheck")]
[assembly: AssemblyCopyright("Copyright \x00a9 Microsoft 2011")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("18ee114d-54a6-43c3-8613-29dd338c7adb")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.0", FrameworkDisplayName=".NET
Framework 4")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows=true)]
In both the release build and debug build, the IgnoreSymbolSequencePoints DebuggingModes
flag will be present. However, in a debug build, the DisableOptimizations attribute
will also be present. This is necessary because optimizations result in code
rearrangement in the output file, which can make debugging difficult. Optimization
is normally disabled while debugging.
The HttpContext.Current.IsDebuggingEnabled property seen below actually reads the
<compilation.. debug attribute from your web.config file.
You can copy all the code that follows, paste it into a text file and save it as
DebugBuild.aspx and you are "good to go". Just drop it into any web
application, and request the page to see the state of your app.
<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="System.Reflection" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Web.Configuration" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>DEbug Build Checker</title>
<script runat=server language="C#">
protected void Page_Load( object sender, EventArgs e)
{
DoDebugCheck();
}
public class Info
{
public string AssemblyName { get; set; }
public bool IsDebug { get; set; }
}
private bool IsAssemblyDebugBuild(string filepath)
{
return IsAssemblyDebugBuild(Assembly.LoadFile(Path.GetFullPath(filepath)));
}
private bool IsAssemblyDebugBuild(Assembly assembly)
{
foreach (var attribute in assembly.GetCustomAttributes(false))
{
var debuggableAttribute = attribute as DebuggableAttribute;
// if IgnoreSymbolStoreSequencePoints and DisableOptimizations flags are both present,
the assembly was built in debug mode
if (debuggableAttribute != null)
{
return
debuggableAttribute.DebuggingFlags.HasFlag(
DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)
&&
debuggableAttribute.DebuggingFlags.HasFlag(
DebuggableAttribute.DebuggingModes.DisableOptimizations);
}
}
return false;
}
private void DoDebugCheck()
{
var infos = new List<Info>();
string path = Server.MapPath("~/") + @"\bin\";
var di = new DirectoryInfo(path);
FileInfo[] files = di.GetFiles();
foreach(FileInfo fi in files)
{
if( (fi.Name.ToLower().Contains(".dll") || fi.Name.ToLower().Contains(".exe")) &&
(!fi.Name.ToLower( ).Contains(".config") && !fi.Name.ToLower( ).Contains(".manifest")) )
{
string name = fi.Name;
bool isDebug = IsAssemblyDebugBuild(Path.Combine(path, fi.Name));
if (isDebug)
{
var ai = new Info() {IsDebug = isDebug, AssemblyName = name};
infos.Add(ai);
}
}
}
this.GridView1.DataSource = infos;
GridView1.DataBind();
if (infos.Count == 0)
label1.Text = "No Debug Build Assemblies found.";
label1.Text += "<br/>Web.Config Debug Setting = " + HttpContext.Current.IsDebuggingEnabled.ToString();
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>DEBUG BUILD CHECKER</h1>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns=true>
</asp:GridView>
<asp:Label id=label1 runat=server />
</div>
</form>
</body>
</html>
Get in the habit of requesting this page after every deployment. If you don't see this:
DEBUG BUILD CHECKER
No Debug Build Assemblies found.
Web.Config
Debug Setting = False
-- Then you have a problem!