2013-10-03 9 views
21

Mam od dawna działającą aplikację .NET 4.5, która ulega awarii losowo, pozostawiając komunikat wymieniony w tytule pytania w dzienniku zdarzeń . Problem jest odtwarzany na 3 różnych maszynach i 2 różnych systemach (2008 R2 i 2012). Aplikacja nie używa żadnych niebezpiecznych/niezarządzanych komponentów, jest czysto zarządzanym .NET, a jedyną niezarządzaną rzeczą jest sam CLR..NET 4.5: błąd wewnętrzny w środowisku wykonawczym .NET (80131506)/wyłączanie współbieżnego GC

Oto ślad stosu miejscu katastrofy, że mam pochodzących z wysypiska:

clr.dll!MethodTable::GetCanonicalMethodTable() 
clr.dll!SVR::CFinalize::ScanForFinalization() - 0x1a31b bytes 
clr.dll!SVR::gc_heap::mark_phase() + 0x328 bytes 
clr.dll!SVR::gc_heap::gc1() + 0x95 bytes 
clr.dll!SVR::gc_heap::garbage_collect() + 0x16e bytes 
clr.dll!SVR::gc_heap::gc_thread_function() + 0x3e bytes  
clr.dll!SVR::gc_heap::gc_thread_stub() + 0x77 bytes  
kernel32.dll!BaseThreadInitThunk() + 0x1a bytes  
ntdll.dll!RtlUserThreadStart() + 0x21 bytes  

Kwestia ta bardzo przypomina ten, który został omówiony here, więc próbowałem rozwiązania zaproponowane w tym temacie, ale żaden z nich nie pomógł:

  • próbowałem instalacji this poprawkę, ale nie można zainstalować na żadnym z moich maszyn (KB2640103 nie stosuje się, czy jest zablokowany przez inny stanie na komputerze), które faktycznie ma sens, być ponieważ używam 4.5, a nie 4.0.

  • Próbowałem wyłączyć wyłączanie współbieżnego GC i/lub włączanie GC serwera. Teraz odpowiednia część mojego app.config wygląda następująco:

    <?xml version="1.0"?> 
    <configuration>   
        <runtime> 
         <gcConcurrent enabled="false"/> 
         <gcServer enabled="true" /> 
        </runtime> 
    <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/> </startup></configuration> 
    

Chociaż dziwne jest to, że jeszcze znaleźć wiele wątków związanych z GC-w wysypisko procesowego. Poza jednym katastrofa ma miejsce w, istnieje 7 nici z poniższego śladu stosu:

ntdll.dll!NtWaitForSingleObject() + 0xa bytes 
KERNELBASE.dll!WaitForSingleObjectEx() + 0x9a bytes  
clr.dll!CLREventBase::WaitEx() + 0x13f bytes 
clr.dll!CLREventBase::WaitEx() + 0xf7 bytes  
clr.dll!CLREventBase::WaitEx() + 0x78 bytes  
clr.dll!SVR::t_join::join() + 0xd8 bytes 
clr.dll!SVR::gc_heap::scan_dependent_handles() + 0x65 bytes  
clr.dll!SVR::gc_heap::mark_phase() + 0x347 bytes 
clr.dll!SVR::gc_heap::gc1() + 0x95 bytes 
clr.dll!SVR::gc_heap::garbage_collect() + 0x16e bytes 
clr.dll!SVR::gc_heap::gc_thread_function() + 0x3e bytes  
clr.dll!SVR::gc_heap::gc_thread_stub() + 0x77 bytes  
kernel32.dll!BaseThreadInitThunk() + 0x1a bytes  
ntdll.dll!RtlUserThreadStart() + 0x21 bytes  

Który sprawia, że ​​zastanawiam się, czy mogę jakoś zepsuć wyłączenie współbieżne GC (to co ja faktycznie wymienione config za).

Myślę, że podsumowuje to, co udało mi się znaleźć do tej pory. Naprawdę mógłbym skorzystać z pomocy, jak postępować w rozwiązywaniu tego problemu.

+4

Nagłówek obiektu zarządzanego obiektu na stercie GC został uszkodzony, nie może już znaleźć tablicy metod danego typu. Zawsze najpierw szukasz niezarządzanego kodu, z którym współdziałasz, aby wyglądać Z jakiegoś powodu, majsterkowanie z konfiguracją gc nie rozwiązuje problemu –

+0

Może problem w finalizatorze? Możesz spróbować ustawić punkty przerwania w finalizerach lub komentować je. – DSway

+0

'scan_dependent_handles': zależne uchwyty zostały ostatnio dodane do CLR (4.0?) Może jest to prawdziwy błąd w CLR. – usr

Odpowiedz

3

Korzystam z moich wcześniejszych doświadczeń w naszej aplikacji. Może to być spowodowane, jeśli wyjątek zostanie nieobsługiwany do poziomu Finalizera, a jeśli się uda ... spowoduje awarię aplikacji.

Zanim cokolwiek od konfiguracji GC ..

Jeden szybki check ... Używasz biblioteki równoległe zadanie?. Jeśli tak, upewnij się, że obsługujesz wyjątki prawidłowo. Jeśli wyjątki z różnych wątków pozostaną nieobsługiwane, przechodzi do Finalizera, co powoduje awarię aplikacji. Istnieje kilka sposobów, aby dobrze się z nimi obchodzić. Obsługa wyjątku "Aggregate" jest jednym ze sposobów (który użyliśmy do rozwiązania!).

http://msdn.microsoft.com/en-us/library/dd537614.aspx

nie mam 50 punktów, aby dodać komentarz, więc dodanie go jako odpowiedź ...

+0

Ta kwestia rzeczywiście zaczęła się pojawiać po aktywowaniu komponentu, który aktywnie korzysta z TPL, ale nie sądzę, że są tu nieobsługiwane wyjątki. Powody są następujące: 1. Wszystkie wywołania zwrotne wykonywane na zadaniach są umieszczane w blokach try-catch; 2. Zaprenumerowałem AppDomain.Current.UnhandledException, a AFAIR jest uruchamiany w tym zadaniu wyjątek + przypadek finalizatora; 3. Nie widzę sposobu, w jaki mogłaby ona uszkodzić sterowaną stertę, co wydaje się tu zachodzić. – HellBrick

+0

1) Czy wywoływany jest wyjątek AppDomain.Current.UnhandledException? to znaczy, że coś pozostało nieobsługiwane, zaloguj się i uzyskaj więcej danych tutaj. 2) Wyjątki w Finalizerze są śmiertelne. 3) W swojej analizie zrzutowej '! Threads' i sprawdź wątek Finalizer i! Pe powinieneś zobaczyć wyjątek. Jeśli tak jest w tym przypadku :) .. Poinformuj mnie .. – SridharVenkat

+0

Chodzi mi o to, że mam obsługę AppDomain.Current.UnhandledException, ale NIE jest ona uruchamiana w mojej aplikacji, mimo że powinna być, jeśli był to prosty wyjątek finalizatora (I Właśnie sprawdziliśmy to dwukrotnie w następującej aplikacji testowej: [http://pastebin.com/9EgzBZQA](http://pastebin.com/9EgzBZQA)). Czy są nieobsługiwane wyjątki zadań propagowane w jakiś inny sposób, który nie obejmuje wyrzucania ich z finalizatora? O sugestiach eksploracji zrzutu: Spróbuję ich później, najpierw muszę zbadać, co przez ciebie nawet znaczysz =) (Ta cała rzecz zrzutu jest dla mnie zupełnie nowa) – HellBrick

0

rozwiązanie, które pomogło mi: odinstaluj NET 4.5.1, zainstaluj 4.0 , zainstaluj wspomnianą poprawkę, zainstaluj ponownie 4.5.1.

0

Właśnie zakończyłem rozmowę z firmą Microsoft, ponieważ udało mi się odtworzyć problem, który jest podobny.

W moim przypadku był to błąd w środowisku wykonawczym .NET, który ma związek z mieszaniem typów dynamicznych i kodu niedynamicznego. Nie jestem pewien, czy jest to również w przypadku scenariusza, ale są pewne rzeczy warto spróbować:

  • Uruchomienie kodu w systemie Windows 8.1 (najnowsze aktualizacje). Podobno Windows 8.1 ma nowszą wersję .NET niż inne wersje systemu Windows.
  • Jeśli używasz AssemblyBuilder (tak jak ja), spróbuj zmienić go na tryb Run zamiast RunAndCollect.
  • Zmień środowisko wykonawcze na x86 lub x64 i spróbuj ponownie; możesz również zadzierać z równoczesnymi ustawieniami GC, tak jak już próbowałeś.
  • Mój błąd jest naprawiany, gdy mówimy, co w zasadzie oznacza, że ​​pojawi się aktualizacja systemu Windows, która się nim zajmie. Być może jest to również opcja po prostu na to czekać; Nie spodziewam się, że potrwa to zbyt długo, ponieważ jest to bardzo ważne w przypadku wielu programów.
0

Zdaję sobie sprawę, że jest to stary post, jednak wpadłem na tym samym numerze jak PO. Punktem atlaste wykonany:

Zmień środowisko wykonawcze do x86 lub x64 i spróbuj jeszcze raz; możesz również zadzierać z równoczesnymi ustawieniami GC, tak jak już próbowałeś.

Był kluczem do mnie. Wszystkie moje projekty zostały ustawione na Dowolny procesor z wyjątkiem jednego (przypadkowo punkt wejścia dla aplikacji, która jest projektem aplikacji konsolowej). Ten projekt został ustawiony na x86. Po zmianie na Any CPU aplikacja działała poprawnie.

0

Ten sam problem wystąpił w naszej aplikacji komputerowej .NET 4.5 - skrobaczki internetowej. Rozbił się losowo pod dużym obciążeniem. Szukaliśmy więc sposobów, aby dowiedzieć się, co było przyczyną przez kilka miesięcy: próbowaliśmy wszystkiego! Wyłączanie współbieżnego GC, ustawienie go w tryb serwera i wiele innych obejść, dopóki nie stwierdzimy, że nastąpiły awarie z powodu modułu PhantomJS . Używa pewnych niezarządzanych zasobów i nie usuwa ich później :(Stworzyliśmy więc autonomiczną aplikację konsolową do integracji PhantomJS.Następnie uruchamiamy tę aplikację konsolową z Process.Start z zewnętrznego skrobaka i zabijamy ją później. do skrobania, ale nie więcej awarii!