2010-08-13 53 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