我正在编写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,但即使这可能不是我想要的,也需要额外的安装,并且要求我使用单独的Java程序处理由C ++ JMVTI代码生成的数据。
如果有人知道如何将JCI转换为JVMTI内的源代码行号(或者甚至以任何方式),请帮忙!
[如果有人非常了解这个领域,请告诉我,因为我还有一些问题要问这个过程。]
答案 0 :(得分:5)
我想我有点想通了这个。使用的主要方法是jvmti-> GetLineNumberTable(...),它填充jvmtiLineNumberEntry数组。给定BCI行号n(将映射到源行号),可以测试哪个int i是:jvmtiLineNumberEntryArray [i]< = n< jvmtiLineNumberEntryArray [i + 1]。这个int i是所需的相应源代码行号。
有一个问题是AsyncGetCallTrace由于某种原因,一直会返回奇怪的BCI,所以尽管映射提供了精确源代码行号,但它们仍然不是准确,因为原来的BCI不准确。为什么会这样,我不知道。我希望使用Sun Studio探查器,它也使用AsyncGetCallTrace来测试返回的行号是否与我们的探查器相同。在这种情况下,AsyncGetCallTrace函数不准确。但到目前为止,使用Sun Studio变成了自己的挑战。 如果有人知道如何使用这个工具,请帮助!
更大的问题是Java方法经常被内联,因此行号并不总是正确映射。事实上,这可能是上段所述问题的原因,尽管根据我所看到的数字,这似乎不太可能。以下是有关解决内联问题的一些信息:http://developer.amd.com/documentation/articles/pages/JVMTIEventPiggybacking.aspx