Код выхода JVM 8 -559038737 (0xDEADBEEF)

Мое приложение начало недетерминированно давать сбой после обновления до Java 8. Оно не генерирует исключение и не печатает сообщение об ошибке. Единственным признаком его отказа является код выхода -559038737. Кто-нибудь сталкивался с этим?


person Aleksandr Dubinsky    schedule 29.04.2014    source источник
comment
Если вы прочтете шестнадцатеричное сообщение, там написано «мертвая говядина». Это распространенный трюк, используемый профилировщиками памяти для указания недопустимой памяти.   -  person Sergey Kalinichenko    schedule 29.04.2014
comment
@dasblinkenlight Это код выхода, не имеющий ничего общего с содержимым оперативной памяти. Должно быть лучшее объяснение.   -  person Marko Topolnik    schedule 29.04.2014
comment
OP, ваше приложение может на самом деле вызывать System.exit(0xDEADBEEF) где-то внутри стороннего кода.   -  person Marko Topolnik    schedule 29.04.2014
comment
@MarkoTopolnik Я убью автора библиотеки, который использовал System.exit, если я когда-нибудь его найду. Я полагаю, что могу попробовать установить точку останова для этой функции. Кажется странным использовать это магическое число в исходном коде Java, а не в C.   -  person Aleksandr Dubinsky    schedule 30.04.2014
comment
Если мое предположение верно, вы используете библиотеку Java, написанную энтузиастом C. Посыпать немного магии C на Java, должно быть, было приятно :)   -  person Marko Topolnik    schedule 30.04.2014
comment
Я не нашел никаких понятий 0xDEADBEEF как кода выхода ни в источниках JDK, ни в HotSpot. Это может быть библиотека. Поместите точку останова на java.lang.Runtime.exit и на java.lang.Runtime.halt, если это возможно. Если невозможно установить точку останова в производственной системе, вы можете перекомпилировать класс Runtime.java, чтобы распечатать трассировку стека для exit и halt.   -  person apangin    schedule 30.04.2014
comment
@apangin Что вы имеете в виду под перекомпиляцией классов tgose? Есть ли способ включить их в свой исходный код и использовать вместо официальных?   -  person Aleksandr Dubinsky    schedule 30.04.2014
comment
Да, ты можешь. Извлеките java/lang/Runtime.java из src.zip, включенного в JDK, измените его по своему усмотрению, скомпилируйте с помощью javac и, наконец, включите в путь к классам начальной загрузки при запуске приложения с помощью параметра командной строки -Xbootclasspath/p:/path/to/alt/classes.   -  person apangin    schedule 30.04.2014
comment
Для справки, OXCAFEBABE кажется более популярным в средах JVM.   -  person Totoro    schedule 01.05.2014
comment
@apangin, если я просто включу его в src/main/java/java/lang/Runtime.java в свой проект Maven и создам банку, какой флаг JVM мне следует использовать?   -  person Aleksandr Dubinsky    schedule 01.05.2014
comment
@АлександрДубинский -Xbootclasspath/p:/path/to/project.jar   -  person apangin    schedule 01.05.2014
comment
Какие библиотеки вы используете?   -  person Anubian Noob    schedule 02.05.2014
comment
@Totoro Первые 4 байта каждого действительного файла .class Java - это 0xCAFEBABE.   -  person Jeff Scott Brown    schedule 06.05.2014
comment
Используйте SecurityManager и обработайте выход из системы — остальное оставьте нетронутым, это всего несколько строк кода, и их можно использовать в производственной среде.   -  person bestsss    schedule 06.05.2014
comment
Что-то похожее.   -  person Syam S    schedule 07.05.2014
comment
@AleksandrDubinsky отлаживает свое приложение и публикует фрагмент, где встречается dead beef.   -  person Vishrant    schedule 08.05.2014
comment
Да, DEADBEEF обычно используется для инициализации кучи и т. д., для обнаружения недопустимых ссылок (из-за оборванных указателей и т. д.). Я бы не ожидал, что опытный программист преднамеренно использует это значение как код возврата exit, так что либо выход происходит из-за неквалифицированного программиста, либо действительно была какая-то дикая ссылка.   -  person Hot Licks    schedule 08.05.2014
comment
@Totoro - это был бы довольно неопытный программист, который инициализировал бы хранилище в CAFEBABE, так как это привело бы к путанице относительно того, было ли значение каким-либо образом скопировано из заголовка файла .class.   -  person Hot Licks    schedule 08.05.2014


Ответы (1)


Этот код выхода, вероятно, взят из Apache Commons Exec:

public interface Executor {

/** Invalid exit code. */
int INVALID_EXITVALUE = 0xdeadbeef;
...

Есть некоторые изменения в Java 8, которые могли вызвать ошибку.

Но не зная вашего пути к классам и кода, это всего лишь обоснованное предположение.

Возможно, вы используете асинхронный способ использования Commons Exec:

DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();

Executor executor = new DefaultExecutor();
executor.execute(cmdLine, resultHandler);

int exitValue = resultHandler.waitFor();

return exitValue;

Таким образом, исключение фиксируется только в обработчике результатов, но не печатается автоматически в stderr?

person DiegoG    schedule 08.05.2014
comment
Я использую Commons Exec для запуска процесса JVM. Как вы думаете, приведет ли сбой JVM к тому, что Exec вернет этот код выхода, но не зафиксирует вывод ошибки, который распечатывает JVM? Я видел аналогичную проблему в Java 8, где вывод stderr не записывается, когда вызываемое java-приложение использует System.Exit(). Однако вывод трассировки стека необработанного исключения, похоже, записывается. - person Aleksandr Dubinsky; 08.05.2014
comment
Я отредактировал ответ, чтобы ответить на этот вопрос, возможно, вы используете неблокирующий способ использования этой библиотеки, который не печатает трассировку стека автоматически. - person DiegoG; 09.05.2014
comment
Отсутствие (некоторых) вывода stderr (или stdout, если на то пошло) совсем не удивительно для System.exit(), поскольку буферы вывода не будут очищаться или могут не сбрасываться на некоторых JVM. - person Lawrence Dol; 09.05.2014