6

我正在编写 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 转换为源代码行号,请提供帮助!

[如果有人很了解这个领域,请告诉我,因为我还有一些关于这个过程的问题要问。]

4

1 回答 1

5

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

一个问题是,由于某种原因,AsyncGetCallTrace 始终返回奇怪的 BCI,因此尽管映射给出了精确的源代码行号,但它们仍然不准确,因为原始 BCI 不准确。为什么会这样,我不知道。我希望使用同样使用 AsyncGetCallTrace 的 Sun Studio profiler 来测试返回的行号是否与我的 profiler 相同。在这种情况下,AsyncGetCallTrace 函数不准确。但到目前为止,使用 Sun Studio 本身就是一项挑战。如果有人知道如何使用这个工具,请帮忙!

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

于 2010-08-20T14:28:31.867 回答