2009-11-05 17 views
5

Moja usługa C# ma wewnętrzny błąd wykonania .net, który wskazuje na problem rekursji (np. Przepełnienie stosu). Problem polega na tym, że usługa jest dość duża, więc mam problem ze znalezieniem miejsca, w którym rzeczywiście występuje rekursja.Jak znaleźć rekursję w swojej aplikacji?

Czy ktoś z masywnym mosem regex może mnie zaatakować za pomocą ciągu wyszukiwania, który znajdzie to, czego potrzebuję?

+0

Brak śledzenia stosu? –

+0

Nie, jedyny powód, dla którego wiem, że aplikacja się zawiesiła, to że w dzienniku zdarzeń znajduje się wpis informujący, że wystąpił wewnętrzny błąd sieci .net i podaje kod, który wykrywałem, powodując problemy z przepełnieniem stosu. – AngryHacker

+1

Czy kiedykolwiek znalazłeś ten problem? Jeśli tak to jak?Myślę, że większość osób nie rozumiała, że ​​program ulega awarii bez logowania, z wyjątkiem ogólnego błędu przepełnienia stosu w dzienniku zdarzeń usługi. –

Odpowiedz

5

rekursji nie jest łatwo znaleźć w niektórych sytuacjach, takich jak:

method1() { 
    method2() 
} 

method2() { 
    method1() 
} 

Więc regex prawdopodobnie nie pomóc go znaleźć, chyba że jest to banalna sprawa.

+1

Tak. Zbuduj wykres połączeń i szukaj cykli. – ephemient

+0

I mam nadzieję, że rekurencja nie będzie odwoływać się do systemu operacyjnego;) – Cogwheel

4

Co powiesz na używanie narzędzia do profilowania, takiego jak RedGate's Ants profiler lub dotTrace?

Obie oferują bezpłatne wersje próbne. Po prostu uruchom kod z uruchomionym profilerem, który szybko wskaże, gdzie spędzasz swój czas/pamięć.

Założę się, że Twój problem z funkcją rekursywną będzie się mocno pojawiał.

Dodatkowo, z jakiego systemu rejestrowania błędów korzystasz? Jeśli odpowiedź nie jest żadna, rozważ zastosowanie jej. This Question deals with the options. Przy dobrym systemie powinieneś być w stanie uzyskać ślad stosu, który, jeśli masz szczęście, może dać ci wskazówki, gdzie występuje wyjątek.

+0

Mam setki instalacji w USA, to jedyna instancja, która daje mi pasowania. Nie mogę zreplikować problemu, ale chciałbym przynajmniej zbliżyć się do niego, lokalizując rekursję – AngryHacker

6

Jest to pytanie, na które nie można odpowiedzieć w ogólnym przypadku. Z wyjątkiem najprostszych przykładów (na przykład funkcji wywołującej się bezpośrednio), nie ma możliwości analizy programu i określenia, czy występuje rekursja. Będziesz po prostu musiał zacząć uderzać w debugger lub inne narzędzia uruchomieniowe. Jest to przykład halting problem.

+1

Tak - bardzo prawdziwa. Usługi debugowania są jednak trudniejsze niż w przypadku zwykłych aplikacji, dlatego mogą wymagać tego. –

+0

Myślę, że przesadzasz z tym trochę. W większości przypadków myślę o statycznej analizie i znajduję cykle - nie byłoby to takie trudne. Czy byłby wyczerpujący? Nie, ale myślę, że sprawdzenie praktycznej tego nie byłoby takie trudne. Korzystanie z wyrażenia regularnego nie nastąpi jednak. – Tim

+1

Myślę, że "niektóre cykle" pasują do "najprostszych przykładów", które starałem się przezwyciężyć. Ale tak, nawet jeśli chcesz zacząć, prawdopodobnie będziesz potrzebował pełnego parsera. – Cogwheel

2

Dołącz do the service in the debugger i odpowiednio debuguj. Przekonasz się, że jest to łatwiejsze niż wyszukiwanie kodu każdego projektu o rozsądnej wielkości.

4

Zgadzam się, że regexp nie zamierza tego tutaj przyciąć.

Bardziej bezpośredni sposób na uzyskanie pliku zrzutu i sprawdzenie, gdzie został zgłoszony wyjątek.

Można również spojrzeć na narzędzie do analizy statycznej, takie jak NDepend, aby sprawdzić przepływ programów.

1

Najprostszym sposobem, aby to zrobić, jest pobranie śladu stosu rzeczy, która ulega awarii. Śledzenie stosu będzie wyglądać następująco:

Blah 
Foo 
Baz 
Hello 
... 
Frob 
Frob 
Frob 
Frob 
[several hundred more Frobs] 
Frob 
Frob 
... 
Frob 
Something -- crash! 

"Frob" jest funkcją rekursywną. :-)

Powiązane problemy