Санкт-Петербургская группа тестирования JVM


« Исходники Hotspot в... | Main | Декодер файлов hs_er... »
20070219 понедельник Февраль 19, 2007

Отладка агентов JVMTI

Отладка Java приложений, содержащих native-код, трудоемка и достаточно нетривиальна. Чего только стоит одно описание процесса подготовки к отладке. В некоторых ситуациях без этого действительно не обойтись. Но чаще всего оказывается достаточно просто получить некоторую информацию о вызываемых во время работы функциях и порядке их вызова. Если вы пытаетесь отладить JVMTI-агент, то опция -XX:TraceJVMTI может помочь без лишней головной боли получить много крайне полезной информации об общении вашей библиотеки с JVMTI-интерфейсом.

Флаг объявлен как product:
    product(ccstr, TraceJVMTI, "", "Trace flags for JVMTI functions and events")

Но несмотря на это, в клиентской Java (C1, client JIT-compiler) им можно пользоваться только в debug-версии Hotspot.

Формат опции:
        -XX:TraceJVMTI=[DESC[,DESC[,...[,DESC]...]]]
где
         DESC = domain[action[kind]]]

"domain" определяет набор функций и событий, для которых будет проводиться трассировка, следующим образом:

Значение Пример
имя трассируемой JVMTI функции RawMonitorEnter
имя трассируемого JVMTI события VMInit
"all"—все функции и события all
"allfunc"—только функции allfunc
"event"—только события event
"ec"—контроллер событий (например, регистрация обработчика события) ec

Значение "kind" задает набор флагов, определяющих итоговый формат вывода. Флаги делятся на 2 категории—для функций и для событий.

Для функций:
Значение Описание Пример
"i" имя вызванной функции и значение переданных параметров JVMTI [VM not live] CreateRawMonitor {  name='event_lock'
"e" информация о возникших во время работы ошибках JVMTI [main] SetJNIFunctionTable } JVMTI_ERROR_NULL_POINTER - erroneous arg is function_table
"o" сообщение о возврате из вызванной функции JVMTI [VM not live] CreateRawMonitor }

Для событий:
Значение Описание Пример
"t"  информация о возникновении события JVMTI Trg VM init event triggered
"s" посылка нотификации обработчику события JVMTI Evt VM death event sent

Если в конкретном элементе action и kind не определены, то по умолчанию устанавливаются флаги "ies".

Разница между "t" и "s" заключается в том, что одно событие может быть послано нескольким зарегистрированным обработчикам. Соответственно, с флагом "t" будет выведено одно сообщение. При активации "s" число сообщений будет равняться числу обработчиков.

"action" определяет, будут ли заданные флаги устанавливаться или сбрасываться. Полезно сбрасывать флаги, если хочется выборочно не трассировать ряд конкретных функций.

"+" установить флаги
"-" сбросить флаги


Несколько примеров:

-XX:TraceJVMTI=SetNativeMethodPrefix,ClassLoad трассировать функцию SetNativeMethodPrefix (флаги "ie") и событие ClassLoad (флаг "s")
-XX:TraceJVMTI=all,GetJNIFunctionTable-i,VMDeath-s трассировать все функции и события, за исключением функции GetJNIFunctionTable и события VMDeath
-XX:TraceJVMTI=ec,VMDeath+t трассировать котроллер событий и событие VMDeath (флаг "t")


Похожая опция есть и для JNI (-XX:+TraceJNICalls), но, к сожалению, ничего более вразумительного, чем вывод имени вызванной функции получить нет возможности (печать значений переданных параметров и возвращаемого результата не предусмотрена). Также не поддерживается встроенная фильтрация - будет выводиться информация обо всех обращениях к JNI-интерфейсу.

Для иллюстрации давайте рассмотрим JVMTI-агент gctest, пример из JDK 6 (demo/jvmti/gctest):

$ cat Test.java
public class Test {
    public static void main(String[] args) {
        while(true) {
            new Object();
        }
    }
}


$ LD_LIBRARY_PATH="jdk1.6.0/demo/jvmti/gctest/lib/" jdk1.6.0/bin/java -server -showversion -XX:TraceJVMTI=all+ioets -agentlib:gctest Test
JVMTI Tracing all functions
JVMTI Tracing all events
JVMTI [VM not live] AddCapabilities {  capabilities_ptr=0xb7e021b0
JVMTI [VM not live] AddCapabilities }
JVMTI [VM not live] SetEventCallbacks {  callbacks=0xb7e02120 size_of_callbacks=140
JVMTI [VM not live] SetEventCallbacks }
JVMTI [VM not live] SetEventNotificationMode {  mode=1:JVMTI_ENABLE event_type=50:VMInit
JVMTI [VM not live] SetEventNotificationMode }
JVMTI [VM not live] SetEventNotificationMode {  mode=1:JVMTI_ENABLE event_type=81:GarbageCollectionStart
JVMTI [VM not live] SetEventNotificationMode }
JVMTI [VM not live] SetEventNotificationMode {  mode=1:JVMTI_ENABLE event_type=82:GarbageCollectionFinish
JVMTI [VM not live] SetEventNotificationMode }
JVMTI [VM not live] CreateRawMonitor {  name='lock'
JVMTI [VM not live] CreateRawMonitor }
JVMTI Trg VM start event triggered
JVMTI Trg VM init event triggered
JVMTI Evt VM init event sent
VMInit...
JVMTI [main] RunAgentThread {  arg=0x0 priority=10
JVMTI [main] RunAgentThread }
GC worker started...
JVMTI [Thread-0] RawMonitorEnter {  monitor=(null)
JVMTI [Thread-0] RawMonitorEnter }
JVMTI [Thread-0] RawMonitorWait {  monitor=(null) millis=0
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Server VM (build 1.6.0-b105, mixed mode)

JVMTI [VM Thread] garbage collection start event triggered
JVMTI [VM Thread] garbage collection start event sent
GarbageCollectionStart...
JVMTI [VM Thread] garbage collection finish event triggered
JVMTI [VM Thread] garbage collection finish event sent
GarbageCollectionFinish...
JVMTI [VM Thread] RawMonitorEnter {  monitor=(null)
JVMTI [VM Thread] RawMonitorEnter }
JVMTI [VM Thread] RawMonitorNotify {  monitor=(null)
JVMTI [VM Thread] RawMonitorNotify }
JVMTI [VM Thread] RawMonitorExit {  monitor=(null)
JVMTI [VM Thread] RawMonitorExit }
JVMTI [Thread-0] RawMonitorWait }
JVMTI [Thread-0] RawMonitorExit {  monitor=(null)
JVMTI [Thread-0] RawMonitorExit }
post-GarbageCollectionFinish actions...
JVMTI [Thread-0] RawMonitorEnter {  monitor=(null)
JVMTI [Thread-0] RawMonitorEnter }
JVMTI [Thread-0] RawMonitorWait {  monitor=(null) millis=0
JVMTI [VM Thread] garbage collection start event triggered
JVMTI [VM Thread] garbage collection start event sent
GarbageCollectionStart...
JVMTI [VM Thread] garbage collection finish event triggered
JVMTI [VM Thread] garbage collection finish event sent
GarbageCollectionFinish...
JVMTI [VM Thread] RawMonitorEnter {  monitor=(null)
JVMTI [VM Thread] RawMonitorEnter }
[...]

Владимир Иванов 

опубликовал vmrobot ( фев 19 2007, 03:00:43 AM MSK ) Permalink Комментарии [0]

Trackback URL: http://blogs.sun.com/vmrobot/entry/%D0%BE%D1%82%D0%BB%D0%B0%D0%B4%D0%BA%D0%B0_%D0%B0%D0%B3%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_jvmti
Комментарии:

Опубликовать комментарий:

Имя
E-Mail:
URL:

Ваш комментарий:

HTML Syntax: Отключен

Хиты страниц за сегодня: 69