标签: jvmti

从JNI方法中创建JVM

是否可以使用JNI API从JNI方法中创建JVM?

我试图使用JNI函数"JNI_CreateJavaVM()"来做到这一点,但它不起作用(函数保持返回小于零的值).

这是我正在使用的基本代码(C++):

JNIEnv *env;
JavaVM *jvm;
jint res;

#ifdef JNI_VERSION_1_2
JavaVMInitArgs vm_args;
JavaVMOption options[2];
options[0].optionString =
    "-Djava.class.path=" USER_CLASSPATH;
options[1].optionString = "-verbose:jni";
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = 2;
vm_args.ignoreUnrecognized = JNI_TRUE;
/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

#else

JDK1_1InitArgs vm_args;
char classpath[1024];
vm_args.version = 0x00010001;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
/* Append USER_CLASSPATH to the default system class path */
sprintf(classpath, "%s%c%s",
        vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH);
vm_args.classpath = classpath;
/* Create the Java VM */
res …
Run Code Online (Sandbox Code Playgroud)

java java-native-interface jvm jvm-arguments jvmti

7
推荐指数
1
解决办法
4254
查看次数

通过JVM TI代理将invokestatic添加到java/lang/Object.<init>会导致JVM因segfault而崩溃

我试图跟踪JVM中所有对象的分配.

在有关分配剖析器的几个文档中,有人提到最简单的方法是:添加invokestatic Tracker.trackAllocation()V指令java/lang/Object.<init>(通常它由单个return指令组成,我们invokestatic在它之前添加,因此现在是2个指令).

(我知道这种方法很慢,不会跟踪数组分配,但我想从最简单的解决方案开始.另外,我不会将对已分配对象的引用传递给跟踪器,但稍后会添加.)

类文件在onClassLoaded挂钩中使用JVM TI代理进行检测.

但是,添加了invokestatic指令JVM与segfault崩溃后.Tracker对象被添加到bootstrap类加载器中,因此它应该在任何阶段都可见.我尝试添加nop而不是invokestatic,并且JVM与修改后的Object类一起工作正常.所以问题特别在于调用一些静态方法.

我还试图检测应用程序(不是基础的一部分)类,它工作正常 - 跟踪器被调用,没有发生崩溃.此外,我尝试在2点重新定义Object:当它最初加载(第一个加载的类)时,或者在vmInit事件之后(当加载所有基类并且解除对jni的限制时).

关于检测java.lang.Object有什么我遗漏的吗?

代理的代码在这里:https: //gist.github.com/Korobochka/3bf2f906f6ab85b22dec (错误检查被剥离,更改类的代码也不包括在内,但它适用于其他类)

java instrumentation jvm jvmti .class-file

7
推荐指数
1
解决办法
163
查看次数

JVMTI代理如何在启动时设置JVM标志?

为了支持更好的分析数据,我希望我的JVMTI代理能够启用几个JVM标志.有问题的代理是Honest-Profiler,它只能在启动时加载.

我想启用标志: -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints

根据此处记录的问题,如果标志不在,我们会得到一个有偏见的配置文件.最好不要警告用户并启用标志.

java jvm jvmti

7
推荐指数
1
解决办法
688
查看次数

将BCI(字节码索引)转换为源代码行号

我正在编写JVMTI代码来编写Java程序,这主要是使用函数AsyncGetCallTrace以固定的时间间隔从随机线程获取堆栈跟踪.因此,我能够获得CallTrace结构,每个结构都包含一个CallFrame结构数组,其中包含有关堆栈跟踪中各个帧的数据.具体来说,这些数据包括:jmethodID method_id(框架所在的java方法的ID),以及:jint lineno(.class文件中方法的BCI,据我所知文档).我似乎找不到使用JVMTI框架将这个"lineno"转换为相应的源代码行号的方法(参见文件jvmti.h,位于/ usr/lib/jvm/java-6-sun/include,至少在Linux上).实际上,即使在JVMTI框架之外,http://jakarta.apache.org/bcel/apidocs/org/apache/bcel/classfile/LineNumberTable.html,但即使这可能不是我想要的,并需要额外的安装,并要求我处理数据,这是由C++ JMVTI代码生成的,使用单独的Java程序.

如果有人知道如何从JVMTI内部(甚至以任何方式)将BCI转换为源代码行号,请帮忙!

[如果有人非常了解这个领域,请告诉我,因为我还有一些问题要问这个过程.]

code-analysis line-numbers jvmti

6
推荐指数
1
解决办法
1257
查看次数

用于JVM的lsof对应物?

lsof 是一个很好的Unix工具,显示所有当前打开的文件句柄.

有没有人知道一个类似的工具,可以在运行的JVM中显示所有打开的文件(通过JVMTI或任何类似的界面)?

在这种特殊情况下,只要知道哪个类有句柄打开就足够了.方法/行甚至整个链到GC根目录都很棒,但处理程序所有者类已经是一个好的开始.

我知道我可以进行堆转储,在分析器中打开并找到它,但这是一项繁琐的工作,特别是对于大堆.

java debugging lsof jvmti

6
推荐指数
1
解决办法
997
查看次数

JDI:如何在调试器中暂停Java应用程序(JVM)

我正在寻找可能的JDI API来在执行期间的任意点暂停JVM.查看BreakPointRequest createBreakpointRequest方法需要一个特定的位置.是否有任何其他API不需要位置或某种方式来获取可以传递以创建断点的当前位置.

我基本上寻找一种方法来附加和暂停应用程序,然后使用JVMTI代理接收BreakPoint事件的回调以执行进一步处理.谢谢

java jdi jvmti

6
推荐指数
1
解决办法
1902
查看次数

如何唯一地区分Java的对象实例

我目前正在为Java 1.7构建一个本机JVMTI代理.问题是我需要索引有关特定Java对象实例的一些数据.所以我的问题是我可以使用jobject类型的值作为对象的实例ID来检索我的索引数据吗?

我已经查找了有关jobject类型的语义的任何信息.它是Object的内存位置的指针吗?它是一个堆栈指针地址吗?它是JVM内部结构的地址吗?所以我无法弄清楚jobject的值是否是Java对象生命中唯一且不可变的.

谢谢你的帮助.

编辑

根据JNI在这里找到的规范,jobject似乎是Object实例的指针.

java jvmti

6
推荐指数
1
解决办法
3356
查看次数

Java Attach API:UnsatisfiedLinkError

使用时Java Attach API,我在Linux上遇到以下链接错误(仅在不同的机器上试过):

Exception in thread "main" java.lang.UnsatisfiedLinkError: sun.tools.attach.WindowsAttachProvider.tempPath()Ljava/lang/String;
        at sun.tools.attach.WindowsAttachProvider.tempPath(Native Method)
        at sun.tools.attach.WindowsAttachProvider.isTempPathSecure(WindowsAttachProvider.java:74)
        at sun.tools.attach.WindowsAttachProvider.listVirtualMachines(WindowsAttachProvider.java:58)
        at com.sun.tools.attach.VirtualMachine.list(VirtualMachine.java:134)
        at sun.tools.jconsole.LocalVirtualMachine.getAttachableVMs(LocalVirtualMachine.java:151)
        at sun.tools.jconsole.LocalVirtualMachine.getAllVirtualMachines(LocalVirtualMachine.java:110)
        ...
Run Code Online (Sandbox Code Playgroud)

有趣的是,在Solaris和Windows上,它开箱即用.

我尝试了几种指定的组合java.library.path指向包含libattach.so但没有运气的目录.

这有什么不对?

作为一个额外的问题:
有没有办法看到哪个本地库实际上绑定到java类?

java linux java-native-interface dynamic-linking jvmti

6
推荐指数
1
解决办法
2033
查看次数

javac可以提供类的“源调试扩展信息”属性吗?

Java类文件格式支持称为“源调试扩展名”的属性(请参见Java语言规范§4.7.11“ SourceDebugExtension属性”)。

在支持JVMTI这方面的JVM中,您可以使用来查询此字符串jvmtiError GetSourceDebugExtension(jvmtiEnv *, jclass, char **)

我的问题是,是否存在一种使用普通javac语言和Java语言将“源调试扩展”信息嵌入.class文件的方法。核心Java语言中似乎没有可以执行此操作的注释(的javadocjava.lang.Annotation的“所有已知的实现类”列表中没有明显的候选)。

java annotations jvmti

6
推荐指数
1
解决办法
313
查看次数

如何在 com.sun.jdi.ObjectReference 上中止长时间运行的 invokeMethod?

我有自己的 JDI 调试器,它toString在某些对象上调用该方法:

com.sun.jdi.ObjectReferenceobject object = ...
ThreadReference threadRef = frameProxy.threadProxy().getThreadReference();
Value value = object.invokeMethod(threadRef, toStringMethod,
                    Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED);
Run Code Online (Sandbox Code Playgroud)

问题是即使在 toString() 方法中没有设置断点, invokeMethod 也永远不会终止,所以我的调试器挂起。例如,当我在Double对象上调用 this 时会发生这种情况。

如何invokeMethod在一段时间后终止执行?

更新:我尝试实现我自己的Double对象并System.out.println()在方法的开头和结尾放置了一些语句,toString()看起来该方法执行得很好,但由于某种原因调试器没有收到结果。也许这是 JDI 中的一个错误,因为有很多这样的错误,但我不是在为此寻找解决方案,我只是在寻找一种方法来中止执行,invokeMethod()如果它花费太多时间。

更新 2:我尝试了ThierryB 的建议,但我只能frameProxy.threadProxy().stop(object);在经理线程中调用。并且管理器线程被阻塞,invokeMethod()因此它不会执行我的命令。我试过这样的事情:

boolean[] isFinished = new boolean[2];
isFinished[0] = false;

DebuggerManagerThreadImpl managerThread = debugProcess.getManagerThread();
new Thread(() - > {
    try {
        Thread.sleep(2000);
        if (!isFinished[0]) {
            System.out.println("Invoked"); …
Run Code Online (Sandbox Code Playgroud)

java debugging breakpoints jdi jvmti

6
推荐指数
1
解决办法
253
查看次数