Thursday, November 17, 2005

Debug vs Release Mode - StackTrace problem

Recently, I created a base class for a series of components that would replace a Windows DNA architecture written in VB6.  Migrated components are intended to be called from Classic ASP and, as they are rewritten, ASP.NET applications.  The majority of VB6 components used a strongly-typed public property interface.  To consolidate property accessors, I created a method and System.Data.DataSet in a base class that used the System.Diagnostics.StackTrace.

 

One requirement of the base class was to return a default value to Classic ASP clients while raising exceptions to .NET clients that accessed properties with null values.  (The base class also contains a method allowing the caller to determine whether the property is null prior to requesting the value.)  The StackTrace allowed the base class to determine whether the caller was a COM client or .NET client, and return appropriate default values.

 

To my surprise, this worked flawlessly while the components were compiled in Debug mode, but when compiled in Release mode, the code did not work.  After reviewing the instrumentation code, it become obvious that the call stack was different from Debug and Release modes of the code.  A quick check with Reflector revealed that public properties were being in-lined obviously an optimization technique used in Release mode.

 

I was searching for an attribute that would allow me to control the optimization of these properties.  I found the attribute I was looking for [MethodImpl(MethodImplOptions.NoInlining)]; however this does not currently work with properties, only methods.  So, our solution is a little overkill, but under the time constraints seemed to solve our problem by having our base class inherit from System.MarshalByRefObject.  No inlining optimization, and we can continue with the current release.  Since this is a little heavy-handed approach, we may revisit to find a different solution.