Как использовать датчики HotSpot DTrace в SmartOS?

В Mac OS X я могу найти пробы HotSpot для запуска программ Java, запустив:

cody.mello@ashur ~ (1) % sudo dtrace -ln 'hotspot*:::'
Password:
Invalid connection: com.apple.coresymbolicationd
   ID   PROVIDER            MODULE                          FUNCTION NAME
165084  hotspot46      libjvm.dylib _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread [instanceKlass::initialize_impl(instanceKlassHandle, Thread*)] class-initialization-clinit
165085  hotspot46      libjvm.dylib _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread [instanceKlass::initialize_impl(instanceKlassHandle, Thread*)] class-initialization-concurrent
165086  hotspot46      libjvm.dylib _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread [instanceKlass::initialize_impl(instanceKlassHandle, Thread*)] class-initialization-end
165087  hotspot46      libjvm.dylib _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread [instanceKlass::initialize_impl(instanceKlassHandle, Thread*)] class-initialization-erroneous
165088  hotspot46      libjvm.dylib _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread [instanceKlass::initialize_impl(instanceKlassHandle, Thread*)] class-initialization-error
165089  hotspot46      libjvm.dylib _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread [instanceKlass::initialize_impl(instanceKlassHandle, Thread*)] class-initialization-recursive
...

Но если я создам простую Java-программу и запускаю ее на SmartOS:

cody@101901c9-6d66-ea32-fe42-f1fbebd4bf99 ~ % cat Loop.java 
class Loop {

    public static void main(String[] args) throws InterruptedException {
        while (true) {
                Thread.sleep(5000);
        }
    }
}
cody@101901c9-6d66-ea32-fe42-f1fbebd4bf99 ~ % javac Loop.java 
cody@101901c9-6d66-ea32-fe42-f1fbebd4bf99 ~ % java Loop

Я не могу найти никаких зондов:

cody@101901c9-6d66-ea32-fe42-f1fbebd4bf99 ~ (255) % pfexec dtrace -ln 'hotspot*:::'
   ID   PROVIDER            MODULE                          FUNCTION NAME
dtrace: failed to match hotspot*:::: No probe matches description

Что-нибудь особенное, что мне нужно сделать, чтобы увидеть их?

1 ответ

Решение

Проблема здесь в том, что на SmartOS (и других вариантах illumos - а также их проприетарных собратьях Solaris) модуль DTrace в JVM загружается лениво (то есть DOF был скомпилирован с -x lazyload). В результате зонды DTrace не загружаются, пока не будут явно включены. Есть два способа справиться с этим. Во-первых, вы можете указать DTrace самому включить определенные тесты, заставляя целевой процесс загружать свои тесты. Для этого требуется (как минимум) идентификатор целевого процесса; чтобы описать это в примере, приведенном в вопросе, это будет что-то вроде:

% pfexec dtrace -ln 'hotspot*$target:::' -p `pgrep -fn "java Loop"`

Это подхватит hotspot (а также hotspot_jni) USDT проверяет, но все еще оставляет использование jstack() трудное действие на машине, заполненной ничего не подозревающими процессами Java. (То есть это работает, когда вы хотите использовать зонды USDT в известном процессе, а не когда вы хотите использовать профиль помощника ustack для всех процессов Java.) Если это проблема, которая вас волнует, в вариантах illumos (SmartOS, OmniOS и т. Д.) Вы можете эффективно отменить ленивую загрузку зондов DTrace (и помощника по стеку) с помощью библиотеки аудита, разработанной для этой задачи. Эта библиотека - /usr/lib/dtrace/libdtrace_forceload.so и его 64-битный вариант, /usr/lib/dtrace/64/libdtrace_forceload.so - эффективно заставит датчики DTrace загружаться при запуске процесса, давая вам зонды USDT и jstack() действие для всех таких процессов. Чтобы сделать это для 32-битных JVM, запустите java с LD_AUDIT_32 набор переменных среды:

export LD_AUDIT_32=/usr/lib/dtrace/libdtrace_forceload.so

Для 64-битных JVM:

export LD_AUDIT_64=/usr/lib/dtrace/64/libdtrace_forceload.so
Другие вопросы по тегам