如何在SmartOS上使用HotSpot DTrace探针?

7
在 Mac OS X 上,我可以通过运行以下命令查找正在运行的 Java 程序的 HotSpot 探针:
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个回答

15

问题在于,在SmartOS(以及其他illumos变体,以及它们的专有Solaris同胞中),JVM中的DTrace模块是惰性加载的(也就是说,DOF是使用-x lazyload编译的)。因此,DTrace探针直到显式启用才会被加载。有两种处理方法。第一种方法是告诉DTrace自身启用特定的探针, 强制目标进程加载其探针。这需要(至少)目标进程的ID;在本文提供的示例中,它可能是以下内容:

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

这将捕获hotspot(和hotspot_jni)的USDT探测器,但在充斥着无辜Java进程的机器上使用jstack()操作仍然很困难。(也就是说,在你想在已知进程上使用USDT探针时有效,而不是在想为所有Java进程使用ustack helper配置文件时。)如果这是您关心的问题,对于illumos变体(SmartOS、OmniOS等),您可以使用设计用于此任务的审核库有效地撤销DTrace探测器(和堆栈帮助程序)的懒加载。该库--/usr/lib/dtrace/libdtrace_forceload.so及其64位变体/usr/lib/dtrace/64/libdtrace_forceload.so--将在进程启动时强制加载DTrace探测器,从而为所有这样的进程提供USDT探针和jstack()操作。要在32位JVM中执行此操作,请使用设置了LD_AUDIT_32环境变量的java启动命令:

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

对于64位JVM:

export LD_AUDIT_64=/usr/lib/dtrace/64/libdtrace_forceload.so

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接