How to tell if a .NET Assembly is debug or release
Yesterday, I was asked by a ISV developer to check to see if their product was built in debug or release. I didn't question why a ISV development team would package and deliver debug assemblies to a customer...
The first thing that I did was open up .NET Reflector - a great product from Lutz Roeder that I've used for years. However, I wasn't exactly sure what I was looking for. And the .NET Reflector can't show attributes that don't exist, so I didn't see the Debuggable attribute.
If the assembly was built for debug, then the .NET Reflector would show this line on the Disassembler window:
[assembly: Debuggable(...)]
So since I wasn't 100% sure of what I was looking for, I wrote a simple function to load an assembly and check to see if it was debug or release.
Assembly assemb = Assembly.LoadFile(Path.GetFullPath(fileName)); bool isDebug = false; foreach (object att in assemb.GetCustomAttributes(false)) if (att is DebuggableAttribute) isDebug = ((DebuggableAttribute)att).IsJITTrackingEnabled; Console.WriteLine("Assembly is {0}.", isDebug ? "debug" : "release");
The above code takes the file name of a .NET assembly and then loops through each of the custom attributes assigned to the assembly. If the assembly was built for debug, then one of the attributes is the type of DebuggableAttribute. Otherwise, if it was built for release, then the DebuggableAttribute will not be found.
Update 9/6/2007: Changed logic to support assemblies using .NET 1.x and 2.0 Frameworks.



September 1st, 2007 - 06:13
I have no idea what you just said…but I kicked it none the less.
September 4th, 2007 - 09:05
nice trick and a kick from me
September 6th, 2007 - 13:32
Great tip, very appropriate for what I was working on today. But, I’m not sure it’s entirely accurate, perhaps you can clarify or check on this?
As far as I can tell when building for release in .NET 2.0, the following attribute is added:
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
Where when building for debug, the following is added:
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.EnableEditAndContinue | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.Default)]
My point being that I’m not sure if you can rely on the presence or absence of that attribute to know for sure. I did this with Visual Studio 2005 switching between debug and release builds. I’m not sure how the ISV built their assembly to not have that attribute, though I have seen similar in other 3rd party assemblies (like nunit and TypeMock). the docs) may be of some help, but didn’t completely clear it up for me, sounds like with 2.0 the attribute will always be there.
September 6th, 2007 - 13:39
Ryan,
That’s a good point. I looked into it and the original assembly was done using .NET version 1.0, so it wasn’t there.
In my original code, I had a little bit more information that I stripped out for the blog post. I had hoped to simplify the code for ease of understanding.
I’ll add in the new check above that will work for 1.x and 2.0 assemblies.
thanks
September 6th, 2007 - 14:07
Great, thanks for updating so quick.
September 9th, 2007 - 20:14
Give this a shot.
http://blogs.msdn.com/jb/archive/2006/06/14/631469.aspx
September 9th, 2007 - 21:55
Thanks for the link JB and good write up on determining whether an assembly is debug or release. I wish I had stumbled upon that a few weeks ago
October 17th, 2007 - 01:24
You can still use Reflector to check it, if your code looks for missing Debuggable attrib, then if it’s missing in Reflector you know all you need to know, right?
October 17th, 2007 - 06:13
Mike,
That’s true with version 1.x, but with 2.0 the Debuggable attribute will always be present. Then you’ll just need to check to see if the attribute has IsJITTrackingEnabled and then you should be able to tell from that (enabled=true=debug;enabled=false=release).
Jim
October 29th, 2007 - 20:05
Thanks for putting me on to this protip – one of my favorite tiny utilities from my .Net 1.1 days was IsDebug, which ceased to work in .Net 2.0 because stuff changed.
I took this and updated it to work in a handy little GUI – http://48klocs.blogspot.com/2007/10/marginal-utility-isdebug-for-net-20.html
March 21st, 2009 - 05:32
Here is what I found using VB.Net 3.5
DEBUG
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 )
RELEASE
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 03 00 00 00 00 00 )
However, notice in both cases the IL has the attribute commented out. So I don’t see what the difference is between pdb-only and full.
June 10th, 2011 - 05:57
James – this is two years late but for anyone looking for more details on the attributes if using reflector check out http://completedevelopment.blogspot.com/2009/07/determining-if-assembly-is-compiled-in.html
March 31st, 2009 - 02:12
Nice work Jim, nice to see clean simple code, saved me an hours digging at least.
Thanks,
Niall.