First, you need to define exactly what is meant by "Debug" vs. "Release"...
- Do you mean that the app is configured with code optimization?
- Do you mean that you can attach the VS/JIT Debugger to it?
- Do you mean that it generates DebugOutput?
- Do you mean that it defines the DEBUG constant? Remember that you can conditionally compile Methods with the System.Diagnostics.Conditional() attribute.
Sooo, do you want to do this manually or programmatically?
Manually:
You need to view the value of the DebuggableAttribute bitmask for the assembly's metadata. Here's how to do it:
- Open the assembly in ILDASM
- Open the Manifest
- Look at the DebuggableAttribute bitmask. If the DebuggableAttribute is not present, it is definitely an Optimized assembly.
- If it is present, look at the 4th byte - if it is a '0' it is JIT Optimized - anything else, it is not:
....
Programmatically: assuming that you want to know programmatically if the code is JITOptimized, here is the correct implementation:
void Main() { var HasDebuggableAttribute = false; var IsJITOptimized = false; var IsJITTrackingEnabled = false; var BuildType = ""; var DebugOutput = ""; var ReflectedAssembly = Assembly.LoadFile(@"C:\src\TMDE\Git\RedisScalingTest\bin\Release\netcoreapp3.1\RedisScalingTest.dll"); // var ReflectedAssembly = Assembly.LoadFile(@"path to the dll you are testing"); object[] attribs = ReflectedAssembly.GetCustomAttributes(typeof(DebuggableAttribute), false); // If the 'DebuggableAttribute' is not found then it is definitely an OPTIMIZED build if (attribs.Length > 0) { // Just because the 'DebuggableAttribute' is found doesn't necessarily mean // it's a DEBUG build; we have to check the JIT Optimization flag // i.e. it could have the "generate PDB" checked but have JIT Optimization enabled DebuggableAttribute debuggableAttribute = attribs[0] as DebuggableAttribute; if (debuggableAttribute != null) { HasDebuggableAttribute = true; IsJITOptimized = !debuggableAttribute.IsJITOptimizerDisabled; // IsJITTrackingEnabled - Gets a value that indicates whether the runtime will track information during code generation for the debugger. IsJITTrackingEnabled = debuggableAttribute.IsJITTrackingEnabled; BuildType = debuggableAttribute.IsJITOptimizerDisabled ? "Debug" : "Release"; // check for Debug Output "full" or "pdb-only" DebugOutput = (debuggableAttribute.DebuggingFlags & DebuggableAttribute.DebuggingModes.Default) != DebuggableAttribute.DebuggingModes.None ? "Full" : "pdb-only"; } } else { IsJITOptimized = true; BuildType = "Release"; } Console.WriteLine($"{nameof(HasDebuggableAttribute)}: {HasDebuggableAttribute}"); Console.WriteLine($"{nameof(IsJITOptimized)}: {IsJITOptimized}"); Console.WriteLine($"{nameof(IsJITTrackingEnabled)}: {IsJITTrackingEnabled}"); Console.WriteLine($"{nameof(BuildType)}: {BuildType}"); Console.WriteLine($"{nameof(DebugOutput)}: {DebugOutput}"); }
There is no "else" for the "if (debuggableAttribute != null)" so it is unclear what to set the various values too in this case.
ReplyDeleteOther than that very helpful write up.
Thanks
Hugh
Thanks for this wonderful piece of code!!
ReplyDeleteI checked. It's working right. Thank you.
ReplyDeleteHi, very important - instead of LoadFile use LoadFrom - because it helps in the case of referenced assemblies. It resolves file not found exception thrown by get attributes. GLHF!!!
ReplyDelete