Как отлаживать тихие сбои в приложениях Java? - PullRequest
5 голосов
/ 24 июня 2009

Я пытаюсь отладить проблему в моем Java-приложении, которая не выдает ошибок, исключений и даже не приводит к сбою приложения (кажется, что сбой происходит в отдельном потоке).

Кажется, проблема в вызове библиотечной функции (это JAXBContext.newInstance(String), если это имеет значение). Программа достигнет линии непосредственно перед вызовом, но не сразу после него. Мои блоки catch не введены, и программа просто продолжает работать.

Проблема возникает при попытке отобразить XML-ответ на веб-запрос, поступивший через Struts. Запрос обработан, и код должен маршалировать объект ответа. Клиент сразу получает ответ (так что код, похоже, не зацикливается), но он просто пустой.

Я установил точку останова непосредственно перед проблемной строкой, но отладчик просто запускает ее, я понятия не имею, почему.

Я использую eclipse, и приложение запускается внутри контейнера OSGi (Apache Felix), который был запущен с -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y. Из Eclipse я затем использую параметры отладки для «Удаленного Java-приложения» для подключения отладчика.

Какими методами можно решить такую ​​проблему?

Ответы [ 4 ]

6 голосов
/ 16 июля 2009

Вероятно, очевидный вопрос, но вы уверены, что ловите Throwable? Непроверенное исключение может легко привести к смерти рассматриваемого потока (при условии, что никто из вас в стеке вызовов его не перехватит).

Поскольку вы приостанавливаете виртуальную машину при запуске с аргументами отладки, я предполагаю, что вы подтвердили, что отладчик подключается правильно. Тот факт, что вы говорите, что отладчик пропускает сразу после вызова, очень подозрительно. Вы можете достичь каких-либо точек останова в этом приложении? Как насчет этого класса? Как насчет этой темы?

Как вы сузили строку без отладчика? println / отладка в файл?

Можете ли вы вставить фрагмент кода рассматриваемого метода?

Вы можете подтвердить теорию о том, что поток умирает, создав второй поток до того, как возникнет проблема, и подключив его к потоку, который, по вашему мнению, умирает. Тогда метод run () второго потока будет вызываться при выходе из рассматриваемого потока, и вы будете знать, что он умер (но все равно не будет знать, почему.)

В ответ на ваш общий вопрос, когда у меня есть ошибка в приложении Java, которую я не могу воспроизвести в отладчике (что происходит время от времени по разным причинам), я постепенно изменяю свой код с помощью команды sysout printlns или вывода к файлам. При необходимости я также могу изменить код, который вызывает мой код. Если у вас нет исходного кода для кода, который вы вызываете, вы можете попробовать одну из многих инфраструктур BCI, чтобы внедрить ваш байт-код в рассматриваемые методы. Это утомительный процесс, но только изредка.

2 голосов
/ 24 июня 2009

Вы можете попробовать получить Thread Dump - который сообщит вам, блокируются ли какие-либо методы (например, ожидание ввода). [Правка: перечитывание исходного вопроса, получение дампа потока, вероятно, не поможет, так как похоже, что на самом деле ничего не блокирует. Но я оставляю это здесь, поскольку нахожу это полезным во многих других ситуациях!]

Если вы считаете, что ошибка происходит в другом потоке, вы также можете установить UncaughtExceptionHandler , чтобы попытаться ее перехватить.

1 голос
/ 24 июня 2009

Если вы уверены, что проблема где-то в этом методе, вы можете попробовать посмотреть исходный код JAXB .

РЕДАКТИРОВАТЬ:

Что ж, если все станет действительно плохо, вы можете создать свою личную копию с помощью инструментов отладки. Надеюсь, вам не придется прибегать к этому.

0 голосов
/ 24 июня 2009

возможно, внутри звонка происходит бесконечный цикл, и поэтому вы не можете двигаться дальше - но это может не вызвать сбой (если память не используется в каждом цикле).

...