Java 应用程序探针管理器

Java™ 探测器管理器 (JPM) 支持以与 C 和 C++ 探测器管理器相同的方式探测 Java 应用程序。 单个 Vue 脚本应该可以通过使用不同的 JVM 进程标识,同时跟踪多个 java 应用程序。 可以使用相同的脚本来探测 syscalls 或 C/C++ 应用程序以及 Java 应用程序,并且可以使用其他探测器管理器。

类似于 uft(用户函数跟踪)探针管理器,java 探针管理器还接受以下格式的 5 元组调查规范:

uftjava :< process_ID> :*:< _qualified_function_name >: entry

其中第二个元组是对应于要跟踪的 Java 应用程序的 JVM 进程的进程标识。

第三个字段:保留以供以后使用。

第四个字段:其中,需要指定 java 方法。

此名称是如 java 应用程序中使用的完整名称,如 Mypackage.Myclass.Mymethod。

可能应用的部分限制是

  • 只能调查纯 java 方法,不能跟踪 Native(共享库调用)或已加密的代码。
  • 只支持入口调查。
  • 只能支持 JVM v1.5 和更高版本(支持 JVMTI 接口)。
  • 在任何给定的时间点,没有两个 Probevue 会话可以使用 @@uftjava探测同一个 Java 应用程序。
  • 不支持多形/过载方法。
  • 不支持跟踪/访问外部变量使用与任何 Probevue 关键字或内置名称相同的名称。 这可能需要重命名那些外部符号 (Java 应用程序变量名称)。
  • 此发行版中不支持访问 java 应用程序数组。
  • 此发行版中不支持访问 java 应用程序数组。
  • 此发行版中不支持 java 语言的 get_function () 内置。
注: 在跟踪非静态方法的情况下,自变量编号以 __arg2 开头,如 C++ 的非静态方法。 __arg1 用于自引用 (此指针)。

数据访问:java 调查的操作块可以访问类似于现有行为的以下数据。

  • 操作块可以访问全局、局部和核心脚本变量。
  • 操作块可以访问原语类型的方法参数(入口类变量)。
  • 操作块可以访问内置变量。
  • 操作块可以通过标准名称 (仅静态 (类成员)) 访问 Java 应用程序变量。
    x = some_package.app.class.var_x;    //Access static/class member.
  • 支持访问 java 应用程序原语类型变量;必须隐式转换/提升/转换它们,而不丢失 Vue 语言中等效类型的任何值。 但实际内存使用情况 (大小) 可能与 Java 语言不同。

下表列出了 Java 探针管理器上下文中支持的函数:

表 1. Java 探测器管理器支持的函数
函数 描述
stktrace() 提供正在跟踪的 Java 应用程序 (正在运行的线程) 的堆栈跟踪。
copy_userdata() 将数据从 java 应用程序复制到脚本变量。
get_probe() 返回调查字符串。
get_stktrace 返回运行时堆栈跟踪。
get_location_point() 返回当前调查位置。
get_userstring() 从 java 应用程序复制字符串数据。
exit() 从 probevue 跟踪会话退出。

更改为 Probevue 命令:

表 2。 probevue 命令更改
命令 描述
-X 选项 在当前版本中,用户必须手动传递额外的可选字符串 agentlib:probevuejava 以及运行 java 应用程序所需的所有其他选项。

例如:

probevue -X /usr/java5/bin/java -A  -agentlib:probevuejava myjavaapp  myscript.e

当运行 64 位 JVM 时,我们必须使用“agentlib:probevuejava64”,如下所示:

probevue -X /usr/java5_64/bin/java -A  -agentlib:probevuejava64 myjavaapp  myscript.e 
where myjavaapp is the java class of myjavaapp.java application

示例 ExtendedClass.java 源:

class BaseClass
{
        static int i=10;

        public static void test(int x)
        {
                i += x;
        }
}

public class ExtendedClass extends BaseClass
{
        public static void test(int x, String msg)
        {
                i += x;
                System.out.print("Java: " + msg + "\n\n");
                BaseClass.test(x);
        }

        public static void main(String[] args)
        {
                BaseClass.test(5);
                ExtendedClass.test(10, "hello");
        }
}

针对以上 Java 应用程序的示例 test.e 脚本:

@@uftjava:$__CPID:*:"BaseClass.test":entry
{
        printf("BaseClass.i: %d\n", BaseClass.i);
        printf("BaseClass.test: %d\n", __arg1);
        stktrace(0, -1);
        printf("\n");
}

@@uftjava:$__CPID:*:"ExtendedClass.test":entry
{
        printf("BaseClass.i: %d\n", BaseClass.i);
        printf("ExtendedClass.test: %d, %s\n", __arg1, __arg2);
        stktrace(0, -1);
        printf("\n");
}

包含上述脚本的示例 ProbeVue 会话:

# probevue -X /usr/java5/jre/bin/java \
-A "-agentlib:probevuejava ExtendedClass" test.e
Java: hello

BaseClass.i: 10
BaseClass.test: 5
BaseClass.test()+0
ExtendedClass.main()+1

BaseClass.i: 15
ExtendedClass.test: 10, hello
ExtendedClass.test()+0
ExtendedClass.main()+8

BaseClass.i: 25
BaseClass.test: 10
BaseClass.test()+0
ExtendedClass.test()+39
ExtendedClass.main()+8