2010-08-13 108 views
5

我正在编写JVMTI代码来剖析Java程序,这些程序通常需要使用函数AsyncGetCallTrace以固定时间间隔从随机线程获取堆栈跟踪。因此,我可以获得CallTrace结构,每个结构都包含一个CallFrame结构数组,其中包含有关堆栈跟踪中各个帧的数据。具体来说,这些数据由jmethodID method_id(框架所在的java方法的ID)和jint lineno(.class文件中方法的BCI,据我了解文档)组成。我似乎无法找到一种方法来使用JVMTI框架将此“lineno”转换为相应的源代码行号(至少位于/ usr/lib/jvm/java-6-sun/include中的文件jvmti.h在Linux上)。事实上,即使在JVMTI框架之外,我目前在网络上唯一能找到的东西是:http://jakarta.apache.org/bcel/apidocs/org/apache/bcel/classfile/LineNumberTable.html,但即使这可能不是我想要的,并且需要额外的安装,并且需要我处理数据,它是由C++ JMVTI代码使用独立的Java程序生成的。将BCI(字节码索引)转换为源代码行号

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

[如果有人知道这个领域工作,请让我知道,因为我有几个问题想请教一下过程。]

回答

5

我想我有点想通了这一点。使用的主要方法是jvmti-> GetLineNumberTable(...),它填充了一个jvmtiLineNumberEntry数组。给定BCI行号n(要映射到源行号),可以测试哪个int i是:jvmtiLineNumberEntryArray [i] < = n < jvmtiLineNumberEntryArray [i + 1]。这个int就是所需的对应源代码行号。

一个美中不足的是,AsyncGetCallTrace,出于某种原因,始终返回怪异的景气指数,所以虽然映射给精确源代码行号,他们仍然没有准确,因为原来的景气指数是不准确的。为什么这是,我不知道。我希望使用Sun Studio Profiler,它也使用AsyncGetCallTrace来测试返回的行号是否与我的分析器相同。在这种情况下,AsyncGetCallTrace函数是不准确的。但到目前为止,使用Sun Studio变成了自己的挑战。 如果有人知道如何使用此工具,请帮助!

更大的问题是Java方法经常内联,因此行号并不总是正确映射。事实上,这可能是上述段落中描述的问题的原因,尽管这基于我所看到的数字似乎不太可能。以下是有关解决内联问题的一些信息:http://developer.amd.com/documentation/articles/pages/JVMTIEventPiggybacking.aspx