2 ポイント 投稿者 GN⁺ 2024-09-15 | 1件のコメント | WhatsAppで共有

FlowTracker: Javaプログラムのデータフロー追跡

FlowTrackerはJavaエージェントで、プログラムがデータを読み取り、操作し、書き込む方法を追跡する。これにより、ファイルおよびネットワークI/Oを確認し、入力と出力を結び付けて、出力がどこから来たのかを示す。これによって、Javaプログラムの出力が何を意味するのかを理解できる。

デモ

Spring PetClinicはSpringフレームワークのデモアプリケーションである。FlowTrackerの機能を示すために、PetClinicがHTTPリクエストを処理し、テンプレートとデータベースからHTMLページを生成する過程を観察する。ブラウザでデモを実行することも、動画を視聴することもできる。

  • HTTP処理: FlowTrackerは、どのコードがどの出力を生成したのかを示す。たとえば、"HTTP/1.1" やHTTPヘッダーをクリックすると、その部分が org.apache.coyote パッケージのクラスによって生成されたことが分かる。
  • Thymeleafテンプレート: プログラムが読み取った入力(HTMLテンプレート)が出力とどのように結び付いているかを示す。HTMLタグ名をクリックすると、その部分が layout.html ファイルに由来することが分かる。
  • データベース: HTMLページのテーブル内の情報がデータベースから来ていることを示す。たとえば、テーブル内の George をクリックすると、その値がデータベースに由来することが分かる。

このデモはインメモリデータベースを使用しているため、SQLスクリプトまで追跡できる。MySQLデータベースを使用する場合は、データベース接続まで追跡できる。

使い方

FlowTrackerは現在、概念実証段階にあり、すべてのプログラムでうまく動作するとは限らない。また、多くのオーバーヘッドを追加するため、プログラムの実行速度が遅くなる。FlowTrackerエージェントのjarファイルをダウンロードし、Javaコマンドラインに追加して使用する。

内部の動作方式

簡単な説明

FlowTrackerはクラスファイル(バイトコード)にコードを注入し、メモリ内のデータとその由来を追跡する。主にテキストおよびバイナリデータ(String、char、byte配列)を追跡する。

  • JDKメソッド呼び出しをFlowTrackerのメソッド呼び出しに置き換える。
  • JDKの主要な箇所にコードを注入して入力と出力を追跡する。
  • メソッド内でローカル変数とスタック上の値を追跡するために、データフロー分析とより深い計測を行う。
  • メソッド呼び出しの前後、およびメソッドの開始時と終了時にコードを追加して、メソッド引数と戻り値を追跡する。

データモデル: Tracker

FlowTrackerのデータモデルの中核となるクラスと概念:

  • Tracker: 追跡対象オブジェクトの内容と由来に関する情報を保持する。
    • content: データが通過した内容。例: InputStream または OutputStream を通過したすべてのバイト。
    • source: 他のトラッカーのソース範囲に対する内容の範囲を関連付ける。
  • TrackerRepository: 関心のあるオブジェクトとそのトラッカーを関連付けるグローバルマップを保持する。
  • TrackerPoint: 単一のプリミティブ値を表すトラッカー内の位置を指す。

基本的な計測

Trackerを最新の状態に保つため、特定のJDKメソッド呼び出し時にFlowTrackerの hook メソッド呼び出しを挿入する。たとえば、System.arraycopy 呼び出しを com.coekie.flowtracker.hook.SystemHook.arraycopy 呼び出しに置き換える。

プリミティブ値、データフロー分析

プリミティブ値を追跡することは、より大きな課題である。たとえば、byte 値を追跡するために、メソッド内でローカル変数にトラッカーを保存する。

メソッド呼び出し

プリミティブ値がメソッド呼び出しの引数や戻り値として別のメソッドへ流れることをモデル化する。Invocation を用いて、引数と戻り値の PointTracker を保存する。

コード自体を由来として使う

コード自体に由来する値(例: プリミティブ定数やString定数)を追跡する。各クラスに対するトラッカーを生成し、定数が参照される際にそのトラッカーを参照する。

Stringリテラル

Stringリテラルを新たにコピーし、Stringの内容を ClassOriginTracker と関連付ける。たとえば、String s = "abc";String s = StringHook.constantString("abc", 1234, 81); に書き換えられる。

追跡されていない値に対する代替手法

プログラム内のすべての値を追跡するわけではない。追跡されていない値が追跡すべき場所に到達した場合、それを定数と同様に扱う。

GN⁺のまとめ

  • FlowTrackerはJavaプログラムのデータフローを追跡し、プログラムの出力を理解するのに役立つ。
  • Spring PetClinicデモを通じて、HTTPリクエスト処理、テンプレート使用、データベース連携を視覚的に確認できる。
  • 現在は概念実証段階であり、すべてのプログラムでうまく動作するとは限らず、性能オーバーヘッドも大きい。
  • データフロー分析とメソッド呼び出し追跡を通じて、プリミティブ値とオブジェクトの由来を追跡する。
  • 類似機能を持つツールとしては、Dynatrace、New Relicなどがある。

1件のコメント

 
GN⁺ 2024-09-15
Hacker News の意見
  • Clojure向けの FlowStorm というツールを紹介

    • 公式の Clojure コンパイラをフォークして追加のバイトコードを挿入
    • 値の大半が不変であるため、ポインタを保持してスナップショットを取れる
    • Web アプリのデバッグデモへのリンクを掲載: FlowStorm デモ
  • Java/JVM エコシステムのツールが非常に優れていると称賛

    • jitwatch と同じくらい感銘を受けた
    • FlowTracker が taint 解析を連想させる
    • 関連キーワード: "dynamic taint tracking/analysis"
    • 関連プロジェクトのリンク:
  • HTML 要素から SQL 文まで追跡するデモに感銘を受けた

    • この種のツールはバグ解決の第一防衛線になり得る
  • Smalltalk 環境を思い起こさせる

    • すべてのオブジェクトとメッセージを追跡し、相互作用できる
  • デモ動画が非常に有用であることを強調

    • 見慣れないコードベースを探索する際に役立ちそう
  • HTML ソースマップに似た概念を試した経験を共有

    • Web 開発ツールはこのようなフルスタックの性質から大きな恩恵を受けるはず
    • 既存フレームワークに統合することが大きな課題
    • 関連プロジェクトのリンク: HTML Source Maps
  • Eve-lang のデモに似ていると言及

  • SQL インジェクションを動的に見つけるツールに似た論文を思い出した

  • インターネット上のデータを追跡するというビジョンを持っていた経験を共有

    • 画像の出所や文字列の経路を追跡する方向へ進む一段階だと感じる
  • VSCode とプロジェクトでこのツールを試そうとしたことへの感謝

    • 現在は中断しているが、再挑戦するつもり