BTraceダイナミックトラッキング技術

直接操作バイトコード

Javaは、JVMは、最終的に機械語に解釈されるクラスのバイトコードを読み取ることができ、クラスのJVMバイトコード言語を読み取ることができ、言語を読み取ることができるソフトウェア開発者です。どのような言語、すべての人間の創造。だから、それを読むことができるので、これらの言語のいずれかを読み取ることができる人(実際には真の)理論的には、自然に変更します。限り、我々が望むように、我々はファイルの書き込みに直接Javaコンパイラ、バイトコードをスキップすることができますが、これは時代の何に沿っていない、すべての後に、高レベルの言語設計の始まりは、機械よりも人間性、その開発効率を提供することです多くの高い言語。

人間の場合は、読み込み可能なバイトコードファイルには、はるかに高いJavaコードです。それにもかかわらず、そこに、いくつかの優れたプログラマが直接バイトコードを編集するために使用することができるフレームワークを作成している残っているインタフェースは、私たちは簡単に新しい動的に作成、クラスの進行に変更注入することによって、バイトコードファイルを操作することができます提供しますクラスなどの操作。フレームの最も有名なのはASMに基づいてバイトコード上の他の操作のためのASM、CGLIB、春のフレームワークである必要があります。

我々は、すべてのプロキシに基づいて実行方法の前と後に、春は実行時に動的プロキシクラスでの動的プロキシの実装を作成し、SpringのAOPは、プロキシクラスはプロキシクラスで参照されているいくつかの神秘的な操作を知っています。さて、春には、実行時にプロキシクラスを作成する方法ですか?動的プロキシの美しさは、私たちはそれぞれのエージェントクラスが必要に春として実行時に動的にクラスを作成するプロキシクラスのコードを記述するために手動でする必要がないということです、ここでの処理は、文字列で作成されたJavaファイルを書くことではありませんその後、クラスファイルにコンパイルして、ロードされました。「作成」クラスファイルを指示してからロードし、ツールクラスファイルを作成します。春はASMです。

ここでは、私たちが直接操作クラスファイルとASMの枠組みを知って、クラスコードで印刷ログの作品を追加し、retransformClassesにそれを呼び出します。

BTrace

今まで、我々はすべての理論的な説明のレベルで滞在しています。それでは、どのようにそれを達成するには?いくつかの質問を初めて目:

  1. それを、バイトコードを見つけるために、これを行うバイトコードを変更し、再変換動作します私たちのプロジェクトでは?私たちは預言者ではないが、将来は資料の冒頭に、この問題が発生する可能性がないことを知っていることはできません。価格を考えると、我々は、いくつかの特別なバイトコードのためにこれらの変更を行うコードバイトコードをリロードするために、各プロジェクトで開発されていませんでした。
  2. JVMは、その中に、リモート、ローカルでない場合は?
  3. でもASMは、それを使用しない場合は?より一般的な多くの「愚か者」のいくつかのいくつかのことができます。

幸い、理由BTraceの存在を、我々はそのようなツールの独自のセットを記述する必要はありません。それは何であるBTrace?BTraceプロジェクトの既に開いて、非常に簡単な説明:

Javaプラットフォームのための安全、動的トレースツール。

BTraceツールは、動的トラッキングサービスを提供し、セキュアなJava言語に基づいています。BTraceベースのASMは、Javaはインスツルメンツは、ノートの多くをユーザーに提供するために開発され、APIを取り付けます。これらのノートに依存している、我々は自分自身を救い出すことができませんASMバイトコードに深い動作しなくても、私たちが望む結果を達成するためにBTraceスクリプト(単純なJavaコード)を書くことができます。

読み取りを開始するすべてのクラスのメソッドにすべてのjava.ioパッケージブロック、クラス名、メソッド名やパラメータ名を印刷:BTraceの公式の単純な例を見てください。プログラムIO負荷が比較的高いとき、あなたはクラスによって引き起こされるの情報出力から見ることができ、それは非常に便利ではないでしょうか?


package com.sun.btrace.samples;

import com.sun.btrace.annotations.*;
import com.sun.btrace.AnyType;
import static com.sun.btrace.BTraceUtils.*; /** * This sample demonstrates regular expression * probe matching and getting input arguments * as an array - so that any overload variant * can be traced in "one place". This example * traces any "readXX" method on any class in * java.io package. Probed class, method and arg * array is printed in the action. */ @BTrace public class ArgArray { @OnMethod( clazz="/java\\.io\\..*/", method="/read.*/" ) public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn, AnyType[] args) { println(pcn); println(pmn); printArray(args); } } 

別の例を見てみましょう:2秒ごとに、現在までに作成されたスレッドの数をオフに印刷します。


package com.sun.btrace.samples;

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.Export; /** * This sample creates a jvmstat counter and * increments it everytime Thread.start() is * called. This thread count may be accessed * from outside the process. The @Export annotated * fields are mapped to jvmstat counters. The counter * name is "btrace." + <className> + "." + <fieldName> */ @BTrace public class ThreadCounter { // create a jvmstat counter using @Export @Export private static long count; @OnMethod( clazz="java.lang.Thread", method="start" ) public static void onnewThread(@Self Thread t) { // updating counter is easy. Just assign to // the static field! count++; } @OnTimer(2000) public static void ontimer() { // we can access counter as "count" as well // as from jvmstat counter directly. println(count); // or equivalently ... println(Counters.perfLong("btrace.com.sun.btrace.samples.ThreadCounter.count")); } } 

上記使用量が鼓舞されていない読みますか?私は助けるが、多くのアイデアを思い付くことができませんでした。このような、それは焼き直しをトリガする際にHashMapを見て、この時間はコンテナどのように多くの要素などなど。

BTraceでは、資料の冒頭に問題は完璧な解決策になることができます。特定の機能は、スクリプトを書く方法、GitはBTraceにこれらのプロジェクトは、説明と例の多くを持ってBTraceとして、オンラインプレゼンテーションBTraceの物品の使用は、ここではそれらを繰り返すない、数え切れないほどあります。

私たちは原理を理解するだけでなく、ツールのサポートを使用して簡単に、そして残りは私たちの創造性を再生することです、そして唯一の合理的に適切な場面で使用することができます。

BTraceは、我々は、上記のすべての問題を解決することができるので、BTraceアーキテクチャは、それは何ですか?

BTraceは、以下のモジュールです。

  1. BTraceスクリプト:必要に応じてBTrace定義されたアノテーションを使用し、我々は簡単にスクリプトを開発することができます。
  2. コンパイラ:BTraceクラスファイルにコンパイルBTraceスクリプト。
  3. クライアント:クラスのエージェントにファイルを送信します。
  4. エージェント:Attach APIをJavaベース、エージェントは動的にJVMに実行を添付して、BTraceサーバを開くことができ、受信側のクライアントが送ってくれたBTraceスクリプト、スクリプトを解析し、次にあなたがルールのスクリプトに応じてクラスを変更したい、単語を修正コードセクションの後に、再変換インタフェースのJavaのインストゥルメントは、オブジェクトの動作に影響をとり呼び出し、修正を行います。

次のようにBTrace全体のアーキテクチャは次のとおりです。

BTraceワークフロー

BTraceワークフロー

 

BTraceは、最終的にクラスを達成するために楽器に置き換え。先に述べたように、セキュリティ上の理由から、楽器の多くの制限がBTrace例外なく、使用上に存在します。JVM BTraceので、次のようにBTraceスクリプトがある制限、「読み取り専用」です。

  1. オブジェクトを作成することは許されません
  2. 配列を作成することはできません
  3. 例外をスローすることはできません
  4. 異常をキャッチすることはできません
  5. 静的メソッドは、呼び出しのcom.sun.btrace.BTraceUtilsが提供のみを許可し、他のオブジェクトやクラスのメソッドを呼び出すことはできません(一部のデータ処理と情報出力手段)
  6. クラスのプロパティを変更することはできません
  7. メンバ変数やメソッドを許可していない、唯一の静的パブリックvoidメソッドを可能に
  8. これは、内部クラス、ネストされたクラスを許可していません
  9. この方法は、同期と同期のブロックを許可していません
  10. それは循環を許可していません
  11. (java.lang.Object上位を除いて、もちろん)他のクラスから継承することはできません。
  12. インターフェイスを実装することはできません。
  13. 許可されていませんアサート
  14. Classオブジェクトが許可されていません

非常に多くの制限が、実際には、理解することができます。BTraceは、バイトコードを変更しているが、しかし、情報要求出力に加えて、全体のプログラムの正常な動作に影響を与えない、ことを行います。

 

オリジナルます。https://tech.meituan.com/2019/02/28/java-dynamic-trace.html

おすすめ

転載: www.cnblogs.com/yx88/p/11291655.html