DebuggableAttribute Attribute

DebuggableAttribute Attribute

Just-in-time (JIT) optimizations are defined in the DebuggableAttribute custom attribute. When compiled in debug mode, this attribute is added to the metadata of the application with any optimizations disabled. The DebuggableAttribute attribute contains the IsJITOptimizerDisabled and IsJITTrackingEnabled properties, which indicate the status of JIT optimizations.

These optimizations can make debugging a production application difficult. Fortunately, you can create an application initialization file that disables the optimization of a release product. The initialization file must be in the same directory as the application, have the same root name of the application, and have the .ini extension. For myapp.exe, the filename would be myapp.ini. The initialization file has two entries. The GenerateTrackingInfo entry enables or disables generating complete tracking information. This entry is redundant in .NET 2.0, where tracking information is always generated. The AllowOptimize entry controls code optimization. In the initialization file, 1 is true and 0 is false. The following is an initialization file that disables both JIT optimizations:

[.NET Framework Debugging Control]

This is a partial listing of assembly code generated by the JIT compiler with optimizations enabled:

00e40a0b 8b45b8           mov     eax,[ebp-0x48]
00e40a0e 8b8854010000     mov     ecx,[eax+0x154]
00e40a14 8b15086c3902     mov     edx,[02396c08] ("Transaction cancelled")
00e40a1a 8b01             mov     eax,[ecx]
00e40a1c ff9068010000     call    dword ptr [eax+0x168]
00e40a22 83c301           add     ebx,0x1
00e40a25 3b5ddc           cmp     ebx,[ebp-0x24]
00e40a28 0f8c58fdffff     jl      00e40786
00e40a2e 8d65f4           lea     esp,[ebp-0xc]
00e40a31 5b               pop     ebx
00e40a32 5e               pop     esi
00e40a33 5f               pop     edi
00e40a34 5d               pop     ebp
00e40a35 c20400           ret     0x4
00e40a38 e8713f2579       call    mscorwks!JIT_RngChkFail (7a0949ae)
00e40a3d cc               int     3

The following assembly originated from the same Microsoft intermediate language (MSIL) code as the preceding assembly code. For this assembly, the JIT optimizations are disabled. I will not torment you with the intricacies of assembly code. However, compare the before and after code—and note the differences. Obviously, disabling optimizations made a considerable difference in the assembly code generated.

01050aba 90               nop
01050abb eb17             jmp     01050ad4
01050abd 8b45c0           mov     eax,[ebp-0x40]
01050ac0 8b8854010000     mov     ecx,[eax+0x154]
01050ac6 8b15086c3902     mov     edx,[02396c08] ("Transaction cancelled")
01050acc 8b01             mov     eax,[ecx]
01050ace ff9068010000     call    dword ptr [eax+0x168]
01050ad4 ff45d4           inc     dword ptr [ebp-0x2c]
01050ad7 8b45d4           mov     eax,[ebp-0x2c]
01050ada 3b45d8           cmp     eax,[ebp-0x28]
01050add 0f8c1efdffff     jl      01050801
01050ae3 90               nop
01050ae4 8d65f4           lea     esp,[ebp-0xc]
01050ae7 5b               pop     ebx
01050ae8 5e               pop     esi
01050ae9 5f               pop     edi
01050aea 5d               pop     ebp
01050aeb c20400           ret     0x4

Other differences can exist between release and debug products. Debug methods are likely to be omitted from the release version. Trace methods are probably included in the release build, but that is not guaranteed. These and other dissimilarities sometimes amount to relevant differences between a release and debug version of a product. For that reason, an abnormal condition in a production application may mysteriously disappear in a debug version. The opposite also applies. Errors in a debug version might disappear in the release product. Make sure that Debug and Trace methods cause no side effects. This will eliminate most cross-build problems. It's important to always extensively test both the debug and release versions of products. After exhaustive unit testing of the debug build, submit the release build to identical tests.