NGWS SDK Documentation  

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Making an Image Easier to Debug

For unmanaged code, you control how easy it is to debug the resulting image via IDE switches, or command-line options. For example, the /Zi command-line option for VC++ asks it to emit debug symbol files (PDBs). Similarly, the /Od command-line option tells the compiler to disable optimization – the resulting code runs more slowly, but it’s easier to debug, should the need arise.

In the NGWS runtime, compilers such as VC++, VB and C# compile their source program into MSIL (Microsoft Intermediate Language). This MSIL is subsequently JIT-compiled, before execution, into native machine code. In the same way as you can trade off performance for ‘debuggability’ with conventional source-to-MSIL compilers, you have that same choice for the JIT-compilers.

There are two aspects to this control:

Normally, your ‘first level’ compiler will set these options automatically, based upon the IDE switches or command-line options you specify (eg /Od)

But, as a programmer, you may wish to change the behavior of the JIT-compiler so that the machine code it generates is easier to debug. You do so with a little text file. If the assembly you wish to debug is called MyApp.Exe, then create a text file called MyApp.Ini, in the same directory as MyApp.Exe, like this:

[NGWS Runtime Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0
Ambivalent=1

You may set the value of each option to 0 or 1, and any option may be absent (their value defaults to 0). Setting GenerateTrackingInfo to 1 and AllowOptimize to 0 provides best debuggability. If the Ambivalent option is present, then the assembly’s modules won’t generate tracking info, and will enable optimizations. If all the assemblies that are loaded into an appdomain have this set, then all the modules will exhibit this behavior. If even a single assembly is marked as Ambivalent=0, then all ambivalent assemblies will follow the behavior specified in their respective .INI files.

[Note: settings for an assembly are carried via the System.Diagnostics.DebuggableAttribute. It has two fields, called m_fEnableJITcompileTracking and m_fDisableJITcompileOptimizer. For a retail build, compilers don’t attach any DebuggableAttribute – this defaults the JIT-compiler to behave as if both fields were false – highest performance, hardest to debug. Enabling tracking lowers performance a little; disabling optimization lowers performance a lot]

The DebuggableAttribute applies to a whole assembly at a time (not to individual modules within the assembly). Tools must therefore attach that Custom Attribute to the Assembly metadata token, if an assembly has already been created, or to the class called System.CompilerServices.AssemblyAttributesGoHere – the ALink tool will then ‘promote’ these DebuggableAttribute attributes from each module to the assembly they become a part of. If there is any conflict, the ALink operation will fail.