Mam rekurencyjne wywołanie metody, która zgłasza wyjątek przepełnienia stosu. Pierwsze wywołanie jest otoczone blokiem try catch, ale wyjątek nie jest przechwytywany.
Czy wyjątek przepełnienia stosu zachowuje się w specjalny sposób? Czy mogę prawidłowo złapać / obsłużyć wyjątek?
Nie wiem, czy to istotne, ale dodatkowe informacje:
wyjątek nie jest zgłaszany w głównym wątku
obiekt, w którym kod rzuca wyjątek, jest ładowany ręcznie przez Assembly.LoadFrom (...). CreateInstance (...)
c#
try-catch
stack-overflow
Toto
źródło
źródło
Assert.Fail
zamiast tego. A więc poważnie - jak to zrobimy?Odpowiedzi:
Począwszy od wersji 2,0, wyjątek StackOverflow można wykryć tylko w następujących okolicznościach.
* „środowisko hostowane” na przykład „mój kod obsługuje środowisko CLR i konfiguruję opcje środowiska CLR”, a nie „mój kod działa na hostingu współdzielonym”
źródło
Starting with 2.0 ...
, Jestem ciekaw, co powstrzymuje ich przed złapaniem SO i jak to było możliwe1.1
(wspomniałeś o tym w komentarzu)?Właściwy sposób to naprawić przelew, ale ....
Możesz dać sobie większy stack: -
Możesz użyć właściwości System.Diagnostics.StackTrace FrameCount, aby policzyć użyte klatki i zgłosić własny wyjątek po osiągnięciu limitu klatek.
Lub możesz obliczyć rozmiar pozostałego stosu i zgłosić własny wyjątek, gdy spadnie poniżej progu: -
Po prostu złap ser. ;)
źródło
Cheese
nie jest konkretna. Pójdę zathrow new CheeseException("Gouda");
Ze strony MSDN na StackOverflowException s:
źródło
Jak już powiedziało kilku użytkowników, nie można złapać wyjątku. Jeśli jednak starasz się dowiedzieć, gdzie to się dzieje, możesz skonfigurować Visual Studio tak, aby pękało, gdy zostanie rzucone.
Aby to zrobić, musisz otworzyć Ustawienia wyjątków z menu „Debuguj”. W starszych wersjach programu Visual Studio jest to „Debuguj” - „Wyjątki”; w nowszych wersjach znajduje się w „Debuguj” - „Windows” - „Ustawienia wyjątków”.
Po otwarciu ustawień rozwiń „Wyjątki środowiska uruchomieniowego języka wspólnego”, rozwiń „System”, przewiń w dół i zaznacz „System.StackOverflowException”. Następnie możesz spojrzeć na stos wywołań i poszukać powtarzającego się wzorca wywołań. To powinno dać ci wyobrażenie o tym, gdzie szukać, aby naprawić kod, który powoduje przepełnienie stosu.
źródło
Jak wspomniano powyżej kilka razy, nie jest możliwe przechwycenie wyjątku StackOverflowException, który został zgłoszony przez system z powodu uszkodzonego stanu procesu. Ale jest sposób, aby zauważyć wyjątek jako wydarzenie:
Niemniej jednak Twoja aplikacja zakończy działanie po wyjściu z funkcji zdarzenia (BARDZO brudnym obejściem było ponowne uruchomienie aplikacji w ramach tego zdarzenia, haha, nie zrobiłem tego i nigdy tego nie zrobisz). Ale wystarczy do logowania!
źródło
Tak, przepełnienie stosu CLR 2.0 jest uważane za sytuację, której nie można odzyskać. Tak więc środowisko wykonawcze nadal zamyka proces.
Szczegółowe informacje można znaleźć w dokumentacji http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx
źródło
StackOverflowException
domyślnie kończy proces.Nie możesz. CLR ci nie pozwoli. Przepełnienie stosu jest błędem krytycznym i nie można go naprawić.
źródło
Nie możesz, jak wyjaśnia większość postów, pozwól mi dodać kolejny obszar:
Na wielu stronach internetowych można znaleźć ludzi, którzy mówią, że sposobem na uniknięcie tego jest użycie innej domeny AppDomain, więc jeśli tak się stanie, domena zostanie rozładowana. Jest to absolutnie błędne (chyba że hostujesz swoje CLR), ponieważ domyślne zachowanie CLR spowoduje zgłoszenie zdarzenia KillProcess, obniżając domyślną AppDomain.
źródło
To niemożliwe i nie bez powodu (po pierwsze, pomyśl o tych wszystkich złapanych (wyjątkach) {} wokół).
Jeśli chcesz kontynuować wykonywanie po przepełnieniu stosu, uruchom niebezpieczny kod w innej domenie aplikacji. Zasady CLR można ustawić tak, aby przerywały bieżącą domenę AppDomain w przypadku przepełnienia bez wpływu na oryginalną domenę.
źródło