2013-04-11 15 views
5

Śledzenie stosu, które otrzymuję z aplikacji ASP.NET, wygenerowane z ArgumentNullException, daje wrażenie, że wystąpił błąd w ostatnim wierszu poniższego kodu. O ile widzę, jest to niemożliwe, ale gdyby JIT zoptymalizował wywołanie do Bar, co skutkowałoby innym śladem stosu, wyjaśniałoby to wszystko. Wiem na pewno, że nie jest to kompilator C#, ponieważ CIL wygląda tak, jak bym się spodziewał. Czy jest możliwe, że kompilator JIT usunął wywołanie do paska?Czy kompilator .NET JIT zoptymalizuje wywołanie metody?

C# 4, .NET 4.0.30319.1, ASP.NET 4.0.30319.1

EDIT: powinny wspomniałem jest to konfiguracja release, z kodem Optymalizacja = on, Debug Info = PDB tylko .

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... 
} 
+1

Czy możesz podać ślad stosu? JIT może wbudować metodę, jeśli spełnia ona wymagania - co może spowodować "zniknięcie" ze śladu stosu ... Myślę. – Joshua

+0

jest tam, w pierwszym bloku kodu. Usunąłem nazwy przestrzeni/plików, aby były czytelne. – jasper

+1

Co wiesz, nie sądziłem, że był to ślad stosu, ponieważ był tak mały. Domyślam się, że został on zainicjowany, ale nie wiem, czy kompilator emituje kod, aby zachować "właściwy" ślad stosu, czy nie. Czy śledzenie stosu ma jakiś numer linii lub przesunięcia bajtów? – Joshua

Odpowiedz

4

Według http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx, jeżeli jitter inlines wywołanie metody, to rzeczywiście będzie zwinięte w ślad stosu. Jeśli nie chcesz, aby był wbudowany (co prawdopodobnie nie jest dobrym pomysłem), możesz użyć metody na metodzie. W przypadku pliku exe można również użyć pliku INI, aby JITter mógł wygenerować informacje śledzenia (na dole połączonej strony), ale nie jestem pewien, jak to by działało dla aplikacji ASP.NET.

+0

Dokładnie tego szukałem, ale nie mogłem go znaleźć. – Joshua

+0

doskonały. URL potwierdza to, co podejrzewałem, ale nie mogłem znaleźć czegoś takiego jak ten artykuł podczas wyszukiwania. – jasper

2

Nigdy nie widziałem, aby JIT usunął wywołanie metody, wystarczy wpisać to. Często usunie nieużywane zmienne lokalne, ale jestem prawie pewien, że JIT nie może statycznie analizować wszystkich skutków ubocznych wywołania metody, więc nie sądzę, że kiedykolwiek usunie wywołanie metody.

Domyślam się, że wartość pusta jest przekazywana do metody, która jest wywoływana wewnątrz CreateHiddenField, która ma również parametr value. Ponieważ opcja wstawiania jest domyślnie włączona w trybach Release, nie można naprawdę zaufać śledzeniu stosu (lub rzekomym numerom linii, w których wystąpił wyjątek). Prawdopodobnie twój problem leży wewnątrz CreateHiddenField lub w głąb niewidzialnego stosu. :)

Możesz wyłączyć optymalizacje, aby uzyskać lepszy obraz śledzenia stosu. MSDN has some instructions here

Powiązane problemy