The stack trace I get back from an ASP.NET application, generated from an ArgumentNullException, gives the impression that an error occurs on the last line of the code below. As far as I can see, that is impossible, but if the JIT optimized out the call to Bar
, which would result in a different stack trace, it would explain all. I know for sure its not the c# compiler, as the CIL looks like I would expect. Is it possible the JIT compiler removed the call to Bar?
c# 4, .NET 4.0.30319.1, ASP.NET 4.0.30319.1
EDIT: I should have mentioned this is a release configuration, with Optimize code = on, Debug Info = pdb-only.
Stack Trace:
[ArgumentNullException: Value cannot be null. Parameter name: value]
CreateHiddenField(HtmlTextWriter tr, String name, String value) in Foo.cs:129
Foo(IHttpContext context, HtmlTextWriter writer) in Foo.cs:106
private static void Foo(IHttpContext context, HtmlTextWriter writer)
{ // line 103
Bar(writer, AuthorizationServerResponseDetailsHttpRequestParser.RequestSAMLFieldName, context);
Bar(writer, AuthorizationServerResponseDetailsHttpRequestParser.RequestTargetFieldName, context);
// line 106 - blank line in source code.
CreateHiddenField(tr, name, string.Empty); // looks like its here
}
private static void Bar(HtmlTextWriter tr,string name, IHttpContext context)
{ // line 116
#region Sanitation
if (tr == null) { throw new System.ArgumentNullException("tr"); }
if (name == null) { throw new System.ArgumentNullException("name"); }
if (context == null) { throw new System.ArgumentNullException("context"); }
#endregion
CreateHiddenField(tr, name, context.RequestQueryString(name));
}
private static void CreateHiddenField(HtmlTextWriter tr, string name, string value)
{ // line 127
#region Sanitation
if (tr == null) { throw new System.ArgumentNullException("tr"); }
if (name == null) { throw new System.ArgumentNullException("name"); }
if (value == null) { throw new System.ArgumentNullException("value"); }
#endregion
// payload...
}
Working of JIT Compiler: The JIT compiler is required to speed up the code execution and provide support for multiple platforms. Its working is given as follows: The JIT compiler converts the Microsoft Intermediate Language(MSIL) or Common Intermediate Language(CIL) into the machine code.
JIT compiler monitors the java program and compiles the bytecode of hot methods (i.e. methods that get called frequently) into machine specific code (i.e. platform binary or native code). This compilation of bytecode into native code occurs as the program executes.
The JIT compiler translates the MSIL code of an assembly to native code and uses the CPU architecture of the target machine to execute a . NET application. It also stores the resulting native code so that it is accessible for subsequent calls.
If it was compiled once for the first machine's specific processor, it would not be able to take advantage of a (possibly) more advanced or efficient instruction set available on the new processor.
According to http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx, if the JITter inlines a method call, it will indeed be collapsed in the stack trace. If you don't want it to inline (which is probably not a good idea), you can use
[MethodImpl(MethodImplOptions.NoInlining)]
on the method. For an exe, you can also use an INI file to tell the JITter to generate tracking information (at the bottom of the linked page), but I'm not sure how that would work for an ASP.NET app.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With