2016-01-08 2 views
5

У меня есть классический пример Гейзенбюга, который вызван условием, которого я раньше не видел. Мое устаревшее приложение (около 100K sloc старого кода) не работает должным образом в определенном экземпляре и просто позволяет удаленной отладке JPDA изменяет поведение достаточно, заставляя приложение работать правильно: ничего не делать, кроме добавления «-Xdebug -Xnoagent -Xrunjdwp: transport = dt_socket, server = y, suspend = n, address = 6666 "в командной строке vm скрывает ошибку (с или без фактического соединения). Учитывая, что у меня есть полностью повторяемый тестовый пример, я ненавижу сильно беспокоить его с изменениями кода, если он снова скрывается. И, конечно же, это происходит только в производстве.Вероятные и маловероятные причины Heisenbugs в Java?

Обычно я сразу принимаю проблему с потоками, но а) поведение 100% -ая ошибка и 100% -ная работа, и б) явно не используется поток в рассматриваемом коде. Наша команда тогда пыталась придумать список других причин такого поведения, поэтому я подумал, что, возможно, групповой ум Stack Overflow может добавить еще немного.

Heisenbugs в Java:

  • Темы: плохая синхронизация, условия гонки, неявные допущения заказа.
  • Явный код отладки/регистрации: изменения в пути кода вызывают/предотвращают проблему. Менее часто изменения в уровне журнала могут приводить к изменениям времени (повторение потоков) и различиям в использовании ресурсов ввода-вывода.
  • Библиотеки исходных кодов могут перетаскивать объекты, не связанные с java-файлами Heisenbug.
  • Ожидание выполнения финализаторов для прогнозирования.
  • неправильные предположения о слабых ссылках.
  • Предположим, что кеш фиксированного размера никогда не заполняется.
  • ожидая уникальности хэш-кодов.
  • Предполагает, что == работает с Строками (или не работает на Строках, которые могут быть интернированы в некоторых случаях).
  • VM ошибка (нет, это никогда бывает;).
  • ошибка методологии теста. Особенно, когда есть скрытые переменные, которые зависят от успеха теста. (это выглядит нашей актуальной проблемой. Успех одного теста привел к тому, что клиент выполнил следующий тест, который не прошел из-за проблем с политикой. Неудача привела к запуску в режиме отладки в соответствии с политикой, что привело к успеху. sigh)

Любые другие случаи, которые стоит изучить?

редактирует:

  • да, JPDA включить код использует старый синтаксис. Я не проверял, не влияет ли использование современного синтаксиса на поведение.
  • Эта специфическая машина использует 1.8.0_45-b14 для JRE, и HotSpot 64-разрядный сервер VM (сборка 25.45-B02)
  • а вопрос предназначен для общего, вопрос подстрекательство является реальным и текущим. Поскольку проблема проявляется в развернутой системе, я разрывается между желанием оставить ее запущенной с -Xdebug в качестве обходного пути, так что она остается работоспособной и хочет отслеживать базовую ошибку и убивать ее.
  • рассматриваемая неисправная программа является частью многоступенчатого конвейера обработки данных - детали не должны иметь значения, но лучше всего понимать как автономное приложение, которое получает некоторую информацию из базы данных, а затем использует его для изменения некоторых файлов ,Часть системы, которая ломается, по-видимому, заключается в том, что информация из базы данных не интерпретируется должным образом - что-либо из сломанного объекта ORM или кеша. Когда он «сломан», логика приложения, определяющая, должна ли она работать (на основе содержимого db), делает неправильный выбор для всех итераций (тысячи итераций, включая множественные вызовы программы). Когда он «работает» (единственное различие заключается в том, что vm работает с -Xdebug или нет), приложение делает правильный выбор для всех итераций. В этой конфигурации он полностью согласован. Тот же код, который работает с различными базами данных, не подлежит. Есть некоторые свидетельства (предшествующие моему участию в этом коде), что подобное поведение было замечено в прошлом, которое таинственным образом начало работать после кажущихся незначительными изменений кода ... см. «Heisenbug»
+0

Я по возможности разделил бы флажки. Отладка, в частности, заставляет меня подозревать JIT. – chrylis

+0

Этот вопрос может получить интересную информацию для многих из нас. Почему кто-то хочет его закрыть? – Andres

+0

@ m.thome, не могли бы вы немного объяснить, что вы подразумеваете под «поведением на 100% неудачу против 100% работы»? Под этим я имею в виду то, что именно является поведением, которое терпит неудачу в 100% случаев или проходит 100% времени? Кроме того, каково ваше приложение (например, рабочий стол, веб-сервис, автономное однопоточное приложение командной строки и т. Д.)? Я не ищу конфиденциальную деловую информацию, но немного больше контекста поможет мне сузить некоторые возможные курящие пушки в ответ. – entpnerd

ответ

3

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

+0

Это интересно. Каково было оборудование и какая функция энергосбережения? – entpnerd

+2

Это было около 15 лет назад. Это был толстый клиент точки продажи, работающий на ПК Compaq. Каждый раз, когда оператор покидает ПК, активируется функция энергосбережения (диски, монитор и процессор) и система зависания. Мы не исправили это, просто отключили энергосбережение. – Andres

4

-Xdebug похоже на переключатель изменения поведения. What are Java command line options to set to allow JVM to be remotely debugged? утверждает, что добавление его превращает вас из JIT во все интерпретируемые. Другие oracle java docs (for jrocket admittedly), по-видимому, указывают, что он медленнее по какой-то неопределенной причине и не подходит для развернутых систем.

Я могу представить, что различные схемы GC могут вносить изменения.