Document directory
Anytao.net |. NET website you must know|Anytao technology blog
Released on: 2009.12.29 by: Anytao
2009 original works of Anytao.com and Anytao. Please refer to the author and source in the post.
Question proposal
When chatting in the group at night, I found an interesting problem: how can I determine whether a dll or exe is a debug build or a release build by coding? I didn't have much discussion, so I had to find a way to solve the problem, which is a little exciting for the nightlife. Therefore, we have explored and analyzed this article.
Of course, in order to fully mobilize everyone's ideas and eliminate unnecessary google operations, I think it is necessary to make a systematic analysis of the similarities and differences between the Debug and Release modes, this lays a solid foundation for the next solution.
Debug & Release
When Visual Studio is used to Build code files, a series of syntax checks, lexical checks, and compilation processes occur. Generally, we have two Build modes, this is often referred to as Debug Build and Release Build. It is expected that the Debug Build mode is usually used in development to facilitate debugging feedback, while the Release Build mode is used in deployment because in the Release mode, the compiler has done a lot of optimization operations (Code redundancy, loop optimization, etc.), saving debugging information records. Therefore, the two Build modes are different. The two Build modes are summarized as follows:
- When Debug is used for development, Release is used for deployment.
- In Debug mode, a pdb file is generated to save the status information and debugging information. In Release mode, no debugging information is generated and no pdb file is available.
- In Debug mode. diagnostics. debug. write (or WriteLine) can Output tracing information to the tracing window (Output). In Release mode. diagnostics. debug. writeLine will be ignored. However, you can consider System. Diagnostics. Trace. Write, which has a good popularity and can output debugging information for both Debug and Release.
- In Debug mode, # define DEBUG will be used as the default predefined constant to participate in the compilation process. In Release mode, this pre-compilation will be omitted. For example, if:
#if DEBUG Console.WriteLine("Hi");#endif
In Debug mode, Console. WriteLine ("Hi") will participate in compilation, while in Release mode, the execution of this statement will be ignored. However, if you manually add
#define DEBUG
In both modes, the compilation of Console. WriteLine ("Hi") is executed. The reason is that Visual Studio predefines # define DEBUG by default. We can set it through the switch:
For more information about precompiled commands, see. NET.
Solution
Since we have a basic understanding of Debug Build and Release Build, we can infer the basis for solving the opening problem. In. NETDebuggableAttributeTo control how CLR processes module code rules, and attributesIsJITTrackingEnabledAttribute to identify whether the Runtime Library tracks debugging information during code generation. If IsJITTrackingEnabled is set to true, it indicates that the Runtime Library tracks debugging information and can be inferred to the Debug Build mode; if IsJITTrackingEnabled is set to false, it indicates that the Runtime Library does not have tracing debugging information and can be pushed to the Release Build mode. Therefore, the solution finally focuses on obtaining IsJITTrackingEnabled information. It is conceivable that the simplest method is reflection.
Let's get started.
Build
First, we create an AnyContext to carry the general context service, which mainly includes:
/// <Summary> // A common context // </summary> /// <remarks> // Anytao, http://www.anytao.com/// </remarks> public class AnyContext: IAnyObject {public static DebugMode GetDebugMode (string assemblyName) {}} where DebugMode is a simple enumeration:
/// <summary>/// Debug mode type/// </summary>/// <remarks>/// Anytao, http://www.anytao.com/// </remarks>public enum DebugMode{ Debug, Release}
To be clear, we need to implement a Helper class that obtains DebuggrableAttribute Based on Assembly information. Since it is a Helper class, we hope to take into account various situations. Therefore, using the generic method is a good choice, the specific implementation is as follows:
/// <summary>/// Common helper/// </summary>/// <remarks>/// Anytao, http://www.anytao.com/// </remarks>public static class Utils{ /// <summary> /// Get GetCustomAttribute /// </summary> /// <typeparam name="T">CustomAttribute Type</typeparam> /// <param name="provider"></param> /// <returns></returns> public static T GetCustomAttribute<T>(this ICustomAttributeProvider provider) where T : Attribute { var attributes = provider.GetCustomAttributes(typeof(T), false); return attributes.Length > 0 ? attributes[0] as T : default(T); }}
GetCustomAttribute is implemented as an extension method. You can obtain customattributeprovider for any Type that implements the ICustomAttributeProvider interface, such as Type, Assembly, Module, and MethodInfo, you can call GetCustomAttribute.
Next, the logic of GetDebugMode becomes very simple. We can pass in the assembly path to get DebuggrableAttribute, and then derive the situation of IsJITTrackingEnabled:
Public static DebugMode GetDebugMode (string assemblyName) {if (string. isNullOrEmpty (assemblyName) {throw new ArgumentNullException ("assemblyName");} DebugMode ret = DebugMode. debug; try {// Get assebly by name Assembly ass = Assembly. loadFile (assemblyName); // Get DebuggableAttribute info DebuggableAttribute att = ass. getCustomAttribute <DebuggableAttribute> (); ret = att. isJITTrackingEnabled? DebugMode. debug: DebugMode. release;} catch (Exception) {throw;} return ret;}. This is a simple judgment logic. AnyContext contains many context definitions, such, getDebugMode provides a solution starting with this document.
Test
- Create two projects and compile them in Debug and Release modes to generate the corresponding exe (or dll ):
- Debugass.exe
- Releaseass.exe
- Create a new TestProject and test GetDebugMode as follows:
[TestClass]public class AnyContextTest{ [TestMethod] public void TestIsDebugOrRelease() { // Arrange string ass1 = @"D:\debugass.exe"; string ass2 = @"D:\releaseass.exe"; // Act string mode1 = AnyContext.GetDebugMode(ass1).ToString(); string mode2 = AnyContext.GetDebugMode(ass2).ToString(); // Asset Assert.AreEqual(mode1, "Debug"); Assert.AreEqual(mode2, "Release"); }}
Everything is OK. Try again.
Note: This test is successful in. NET 2.0 and later versions. If you have more energy, you can analyze the versions below.
References:
- Ms-help: // MS. MSDNQTR. v90.chs/fxref_mscorlib/html/9f109812-3c14-dcb2-9aff-e18e20dc33ff.htm
- Http://blogs.msdn.com/jb/archive/2006/06/14/631469.aspx
For more information, see anytao.net.
Anytao | 2009 Anytao.com
2009/12/29 | http://anytao.net | http://anytao.net/blog/post/2009/12/29/anytao-insidenet-35-is-debug-or-release-in-runtime.aspx
This document is provided as "the status quo" without any guarantee and does not grant any rights. The copyright of this article is owned by the author. You are welcome to repost this article, but you must keep this statement without the author's consent and provide a clear link to the original article on the article page. Otherwise, you will be entitled to pursue legal liability.