.NET 1.x/2.x, Assembly, StackTrace and possible bug...

Yesterday I spent one hour to investigate a problem in a software I developed. The issue is about a strange behaviour that happens when I build the project in Release mode, rather than in Debug.

Here is the code (you can download a full working sample from here):

using System;
using System.Reflection;
using System.Diagnostics;
namespace ClassLibraryTest
{
 public class TestClass
 {
  public String ExecutingAssemblyName(Boolean showProblem)
  {
   if (showProblem)
    return(GetExecutingAssemblyKo(2).FullName);
   else
    return(GetExecutingAssemblyOk(2).FullName);
  }
  private System.Reflection.Assembly GetExecutingAssemblyKo(Int32 stackWalkLevel)
  {
   // I get the stack
   StackTrace stack = new StackTrace(stackWalkLevel, false);
   // I get the frame
   StackFrame frame = stack.GetFrame(0);
   // I get the method
   MethodBase method = frame.GetMethod();
   // I get the assembly containing the method's type   
   return(method.DeclaringType.Assembly);
  }
  private System.Reflection.Assembly GetExecutingAssemblyOk(Int32 stackWalkLevel)
  {
   // I get the stack
   StackTrace stack = new StackTrace(stackWalkLevel, false);
   // I get the frame
   StackFrame frame = stack.GetFrame(0);
   // I get the method
   MethodBase method = frame.GetMethod();
   // I get the assembly containing the method's type, this time with an Assembly.Load
   return(Assembly.Load(method.DeclaringType.Assembly.FullName));
  }
 }
}

If you build this code and call the method ExecutingAssemblyName from an ASP.NET class (for instance an ASPX page) you get a different result if you're in Debug or in Release, calling GetExecutingAssemblyKo, while GetExecutingAssemblyOk works well in both cases. It sounds like the Jitter losees something while returning the assembly reference directly from method.DeclaringType.Assembly.
It seems to be a bug of the Jitter, even if I'm not completely sure about that.

Does someone has any idea?

2 Comments

  • If you are using stack-trace objects - than you probably need to use

    [MethodImpl(MethodImplOptions.NoInlining)] attribute as an workaround.



    The source of this "bug" is the way JIT does inlining. In case if your method will be too long - this method will NOT be inlined and result in one stack-frames. But if it will be short - it will be inlined.



    That's why you are observing the difference beetwean method with Assembly.Load() and without it. One get inlined - another nope.



    If this is a bug or nope - I do not know. I do not know if StackTrace must include inlined frames or nope.



    I hope you will find my information valuable. This will clarify mystery of your report.

  • Thanks for your comment. I think that this behaviour should be classified as a side effect of Jitter, rather than a bug, by the way starting from now I think that I won't ever trust on StackFrame.

Comments have been disabled for this content.