6

私はJavaプログラムをプロファイルするためにJVMTIコードを書いています。これは主に、関数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ですが、これでも私が望むことをしていない可能性があり、追加のインストールが必要であり、データを処理する必要があります、別のJavaプログラムを使用して、C++JMVTIコードによって生成されました。

JVMTI内から(または何らかの方法で)BCIをソースコードの行番号に変換する方法を誰かが知っている場合は、助けてください!

[この分野をよく知っている人がいたら、私に知らせてください。プロセスについてさらにいくつか質問があります。]

4

1 に答える 1

5

私はこれをいくらか理解したと思います。使用する主なメソッドはjvmti->GetLineNumberTable(...)で、これはjvmtiLineNumberEntry配列を埋めます。BCI行番号n(ソース行番号にマップされる)が与えられると、どのintiがjvmtiLineNumberEntryArray[i] <= n <jvmtiLineNumberEntryArray [i+1]であるかをテストできます。このintiは、必要な対応するソースコードの行番号になります。

1つの落とし穴は、何らかの理由でAsyncGetCallTraceが一貫して奇妙なBCIを返すことです。したがって、マッピングでは正確なソースコードの行番号が得られますが、元のBCIが正確でないため、正確ではありません。なぜなのか、わかりません。返される行番号がプロファイラーの場合と同じかどうかをテストするために、AsyncGetCallTraceも使用するSunStudioプロファイラーを使用したいと思っていました。その場合、AsyncGetCallTrace関数は不正確です。しかし、これまでのところ、SunStudioの使用はそれ自体の課題になりました。誰かがこのツールの使い方を知っているなら、助けてください!

より大きな問題は、Javaメソッドがインライン化されることが多いため、行番号が常に正しくマップされるとは限らないことです。実際、これが上記の段落で説明した問題の原因である可能性がありますが、これは私が見た数字に基づくとありそうもないようです。インライン化の問題を解決するための情報は次のとおりです。http://developer.amd.com/documentation/articles/pages/JVMTIEventPiggybacking.aspx

于 2010-08-20T14:28:31.867 に答える