2009-06-24 10 views
5

Próbuję debugować problem w mojej aplikacji Java, która nie zgłasza żadnych błędów, nie ma wyjątków i nawet nie powoduje awarii aplikacji (wygląda na to, że awaria następuje w osobnym wątku).Jak mogę debugować ciche błędy w aplikacjach Java?

Problem prawdopodobnie pojawia się w wywołaniu funkcji bibliotecznej (to jest JAXBContext.newInstance(String), jeśli to ma znaczenie). Program dotrze do linii tuż przed wywołaniem, ale nie do tej tuż po niej. Moje bloki catch nie są wprowadzane, a program po prostu kontynuuje działanie.

Problem występuje podczas próby renderowania odpowiedzi XML na żądanie sieciowe, które zostało wysłane przez Struts. Żądanie zostało obsłużone, a kod powinien zarządzić obiektem odpowiedzi. Klient otrzymuje odpowiedź od razu (więc kod nie wydaje się zawieszać w pętli), ale jest pusty.

Ustawiłem punkt przerwania tuż przed problematyczną linią, ale debugger po prostu nad nią działa, nie mam pojęcia dlaczego.

Używam Eclipse, a aplikacja działa wewnątrz kontenera OSGi (Apache Felix), który został uruchomiony z -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y. Z poziomu Eclipse I używam ustawień debugowania dla "Remote Java application", aby podłączyć debugger.

Jakie są techniki, aby uzyskać taki problem?

+2

Czy na pewno IDE wskazuje na ten sam kod źródłowy, który tworzy pliki binarne na serwerze? –

+0

Tak, to wszystko na moim lokalnym komputerze, a kontener OSGi uruchamia kod bezpośrednio z katalogu wyjściowego mojego IDE. –

+0

Nie jestem zaznajomiony z kontenerem OSGi, czy to, podobnie jak JBoss, przenosi wdrożone pliki binarne do innego katalogu? Próbowałbym zmienić kod, System.out.println lub coś podobnego, a następnie upewnić się, że zostanie wykonany, aby to potwierdzić. Normalnie znalazłem, że debugger pomijający linie kodu wskazuje, że IDE i serwer nie są zsynchronizowane ze sobą. –

Odpowiedz

0

Być może wewnątrz połączenia jest infititowa pętla i dlatego nie można już nic zrobić - ale nie spowoduje to awarii (chyba że w każdej pętli używana jest pamięć).

+1

Nie, nie sądzę. Błąd pojawia się po obsłużeniu żądania internetowego przychodzącego przez Struts, a klient otrzymuje wynik (który jest pusty) od razu. Aplikacja nie zawiesza się i wyskakuje z przetwarzania. –

1

Jeśli masz pewność, że problem leży gdzieś w tej metodzie, możesz spróbować spojrzeć na numer JAXB source code.

EDIT:

Dobrze, jeśli robi się naprawdę źle, można zbudować swoją własną kopię z debugowania instrumentacji. Mam nadzieję, że nie będziesz musiał się do tego uciekać.

+0

No cóż, spróbuję, ale bez wprowadzenia debuggera, aby tam wkroczyć, być może będę miał problemy. –

2

Możesz spróbować uzyskać Thread Dump - który wskaże Ci, czy jakiekolwiek metody są blokowane (np. Czekanie na dane wejściowe). [Edytuj: ponowne czytanie oryginalnego pytania, uzyskanie zrzutu wątku prawdopodobnie nie pomoże, ponieważ wygląda na to, że nic nie jest blokowane. Ale zostawiam to tutaj, bo uważam, że jest to przydatne w wielu innych sytuacjach!]

Jeśli uważasz, że błąd występuje w innym wątku, możesz również ustawić UncaughtExceptionHandler, aby spróbować go złapać.

+0

Blokowanie: nie, nie tym razem. UncaughtExceptionHandler był fajnym pomysłem, niestety też niczego nie złapał. –

6

Prawdopodobnie oczywiste pytanie, ale czy na pewno łowisz Throwable? Niezaznaczony wyjątek może łatwo spowodować śmierć wątku (zakładając, że nikt nad tobą w stosie wywołań też go nie przechwyci).

Ponieważ zawieszasz maszynę wirtualną przy starcie z argumentami debugowania, zakładam, że potwierdziłeś że debugger jest poprawnie podłączony. Fakt, że mówisz, że debugger omija tuż po wywołaniu jest bardzo podejrzany. Czy jesteś w stanie trafić jakiekolwiek punkty przerwania w tej aplikacji? A co z tą klasą? A co powiesz w tym wątku?

W jaki sposób zawęziłeś linię bez debuggera? println/debugowanie do pliku?

Czy możesz wkleić fragment kodu danej metody?

Można potwierdzić teorię, że wątek umiera, tworząc drugi wątek, zanim wystąpi problem i dołączając do wątku, który według ciebie umiera.Następnie metoda run() drugiego wątku zostanie wywołana, gdy wątek zostanie zamknięty, a wiesz, że to umarło (ale nadal nie wiesz dlaczego.)

W odpowiedzi na ogólne pytanie, kiedy mam błąd w aplikacji Java, której nie mogę odtworzyć w debugerze (co dzieje się od czasu do czasu z różnych powodów), stopniowo modyfikuję mój kod za pomocą sysout printlns lub output do plików. Jeśli to konieczne, mogę również zmodyfikować kod, który wywołuje mój kod. Jeśli nie masz kodu źródłowego do kodu, który wywołujesz, możesz wypróbować jedną z wielu frameworków BCI, aby wprowadzić swój kod bajtowy do metod, o których mowa. Jest to proces żmudny, ale zdarza się tylko sporadycznie.

+0

+1 Nie wszystkie naloty są wyjątkami i zazwyczaj wychwytywamy wyjątki; łatwo może nam się wymknąć. –

Powiązane problemy