2016-01-27 17 views
6

Mam aplikację asp.net, która ulega awarii. Jest wejście na ten cel w dziennikach zdarzeń okna, które zawiera ten callstack:Czy to normalne, widzieć interfejs w kliencie call clr?

Exception type: EntryPointNotFoundException 
    Exception message: Entry point was not found. 
    at ***.Interfaces.Portal.Repository.ILookup.get_LookupDataCollection() 
    at ***.Portal.Repository.Lookup.GetLookUpValue(ILookup lookup, Int32 index) 
    at ***.Portal.Repository.Lookup.GetLookUpValue(ILookup lookup) 
    at ***.HttpModules.RuntimeHttpModule.SetPageUrlInfoInContext(PageUrlInfo pinfo) 
    at ***PortalRuntime.HttpModules.RuntimeHttpModule.BeginRequest(Object sender, EventArgs e) 
    at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

Dzieje się tak tylko na komputerze klienta i nie byłem w stanie odtworzyć go lokalnie. Jak widać na górze jest interfejs (ILookup, który jest naprawdę interfejsem, a nie klasą).

Zbudowałem podobną próbkę (metoda wywołana przez interfejs). Visual Studio 2015 jest wystarczająco inteligentny, aby to pokazać:

ConsoleApplication2.exe!ConsoleApplication2.Lookup.GetLookupId(ConsoleApplication2.ILookup lookup) Line 37 C# 

Ale nadal widzisz klasę, która implementuje tę metodę. Dołączałem także do mojej próbki z windbg i drukowałem stos, gdy aplikacja znajduje się w punkcie przerwania w metodzie, która została wywołana przez interfejs: interfejs nie był na stosie.

Oto moje pytanie:

  • Czy to normalne, aby zobaczyć interfejs w callstack clr (zwłaszcza bez klasy, która implementuje go)? Chyba nigdy wcześniej nie widziałem takiego stożka ... Ktoś jeszcze? (Mam na myśli to ogólnie, niezależnie od drugiej części mojego pytania)

  • Here to bardzo podobne pytanie: @Hans Passant w swoim pierwszym komentarzu mówi "brak rozwiązania metody implementacji dla metody interfejsu" i OP mówi, że "już odpowiedziałeś na moje pytanie swoim pierwszym komentarzem". Czy to naprawdę jest główna przyczyna? Czy ktoś wie o poprawce? A może jest to tylko specjalna wersja CLR?

Odpowiedz

7

Mogę wyjaśnić, dlaczego widzisz to trochę, to nie pomoże w rozwiązaniu twojego problemu. Nie wiem wystarczająco dużo o tym, w jaki sposób CLR wiąże metody interfejsu z ich implementacją, jest szalenie zoptymalizowany.

Kwestia jest taka, że ​​fluktuacje muszą generować kod metody zawierającej wywołanie metody interfejsu. Ale nie może jeszcze znać tożsamości obiektu odniesienia. Nie jest to w 100% prawdziwe, dopóki kod faktycznie nie zostanie wykonany. Więc to, co robi, to przydzielenie kodu pośredniczącego, symbolu miejsca dla metody docelowej. I generuje instrukcję CALL do tego kodu pośredniczącego. Rzeczywista nazwa tej metody jest nieistotna, zniknie ponownie, gdy zostanie rozwiązana prawdziwa metoda docelowa.

Słupek sam generuje wywołanie do środowiska CLR, aby rozwiązać metodę docelową, znając teraz prawdziwą tożsamość odwołania do obiektu i tym samym, która konkretna metoda implementacji musi zostać wykonana. I łata kod maszynowy, aby adres CALL został zastąpiony. Tak więc, gdy metoda wykona ciebie, nie płacisz ceny metody wiązania, a wywołanie działa z maksymalną możliwą prędkością warp.

Jak podano, nazwa odcinka nie ma znaczenia, ponieważ jest tymczasowa. Podanie nazwy metody interfejsu jest pomocne w diagnozowaniu wyjątku MissingMethodException. Dobry pomysł.

Prawdziwym problemem jest to, że załadowany zespół nie jest tym, z którym zbudowałeś swój kod. Prawdopodobnie stary, o którym zapomniałeś przerobić. Lub po prostu zapomniałeś go odbudować po zmianie interfejsu, ponieważ nie jest to częścią rozwiązania. Tak więc nie ma implementacji metody interfejsu, CLR odkrywa to bardzo późno, po wykonaniu kodu pośredniczącego.Widzisz więc nazwę metody pośredniczącej na stosie wywołań.

+0

Wielkie dzięki za wyjaśnienie! Jasno wyjaśnia, dlaczego widzimy interfejs na szczycie stosu. Może jeden komentarz: "I łata kod maszynowy, aby adres CALL został zastąpiony. Tak więc przy następnym wykonaniu metody nie zapłacisz ceny metody wiązania "Tak, ale co jeśli następnym razem metoda zostanie wywołana z innego typu, który implementuje interfejs? Zrobiony kod nie może mieć połączenia z poprawką do jednej implementacji. Ale w każdym razie, rozumiem twój punkt widzenia. Dzięki jeszcze raz! – gregkalapos

+0

Ta część, o której nie wiem wystarczająco dużo. To działa. –

Powiązane problemy