Вопрос или проблема
Динамически прикрепленный агент не может добавить возможность can_generate_breakpoint_events
(ответ – JVMTI_ERROR_NOT_AVAILABLE
). Прямая причина кроется в исходном коде JVM:
jvmtiCapabilities JvmtiManageCapabilities::init_onload_solo_capabilities() {
jvmtiCapabilities jc;
memset(&jc, 0, sizeof(jc));
jc.can_generate_field_modification_events = 1;
jc.can_generate_field_access_events = 1;
jc.can_generate_breakpoint_events = 1;
return jc;
}
В приведенном выше коде указано, что возможность can_generate_breakpoint_events
и метод SetBreakpoint разрешены только для агентов, которые запускаются на фазе OnLoad
(в отличие от динамически прикрепленных агентов, которые запускаются на фазе Live
).
Вопрос: Существует ли причина для описанного поведения JVM? Может быть, какие-то технические ограничения? Или проблемы безопасности?
Ответ или решение
Вопрос о том, почему динамически подключённые агенты не могут использовать точки останова, является важным аспектом работы с Java Virtual Machine Tool Interface (JVMTI). Давайте подробно рассмотрим причины, лежащие в основе этого ограничения.
1. Техническое ограничение
Динамически подключённые агенты, которые инициализируются в фазе Live, не имеют доступа к функциональности, связанной с возможностью генерации событий на основе остановки (breakpoint events). Это связано с тем, что соответствующая возможность — can_generate_breakpoint_events
— и функция установки точек останова (SetBreakpoint) доступны только для агентов, загружаемых на этапе OnLoad.
Исходный код Java отображает эту архитектурную логику. В коде управления способностями JVM, конкретно в методе init_onload_solo_capabilities
, мы видим, что данная способность инициализируется только для агентов OnLoad:
jvmtiCapabilities JvmtiManageCapabilities::init_onload_solo_capabilities() {
jvmtiCapabilities jc;
memset(&jc, 0, sizeof(jc));
jc.can_generate_field_modification_events = 1;
jc.can_generate_field_access_events = 1;
jc.can_generate_breakpoint_events = 1;
return jc;
}
Это чётко указывает на то, что архитектурно агенты, подгружающиеся вовремя выполнения, не предназначены для управления критическими аспектами выполнения программы, как это делает использование точек останова.
2. Соображения безопасности
Имеются также серьезные соображения в отношении безопасности. Использование точек останова в рамках динамических агентов может представлять потенциальную угрозу для целостности работающих приложений. Если любой агент, подключённый на этапе Live, мог бы установить точки останова, это создало бы возможности для злоумышленников, чтобы вмешиваться в выполнение кода, что могло бы привести к компрометации данных и безопасности системы в целом.
3. Перфоманс и стабильность
Агенты, подключённые в момент выполнения, должны работать в минимально нарушающем режиме для основного процесса. Если бы они могли устанавливать точки останова, это существенно увеличило бы сложность и потенциальные риски, связанные с производительностью и стабильностью приложений. Это также привело бы к необходимости реализации сложных механизмов, предназначенных для управления конфликтами между точками останова, установленными различными агентами.
Заключение
В результате, ограничение в использовании точек останова для динамически подключённых агентов в JVM обусловлено как техническими характеристиками и архитектурными решениями, так и соображениями безопасности и производительности. Этот подход обеспечивает защиту системы и поддерживает стабильность выполнения приложений, гарантируя, что только тщательно контролируемые агентов на этапе загрузки могут повлиять на работу программы на низком уровне.
Таким образом, для специалистов в области информационных технологий важно учитывать эти ограничения при разработке и внедрении агентов в сравнении с традиционными методами отладки и мониторинга приложений на Java.