GDB JIT コンパイルインターフェースの統合
GDB JIT コンパイルインターフェースの統合により、V8 は V8 ランタイムから生成されるネイティブコードに対するシンボルとデバッグ情報を GDB に提供することができます。
GDB JIT コンパイルインターフェースが無効化された状態では、GDB の典型的なバックトレースには ??
でマークされたフレームが含まれます。これらのフレームは動的に生成されたコードに対応します:
#8 0x08281674 in v8::internal::Runtime_SetProperty (args=...) at src/runtime.cc:3758
#9 0xf5cae28e in ?? ()
#10 0xf5cc3a0a in ?? ()
#11 0xf5cc38f4 in ?? ()
#12 0xf5cbef19 in ?? ()
#13 0xf5cb09a2 in ?? ()
#14 0x0809e0a5 in v8::internal::Invoke (construct=false, func=..., receiver=..., argc=0, args=0x0,
has_pending_exception=0xffffd46f) at src/execution.cc:97
しかし、GDB JIT コンパイルインターフェースを有効にすると、GDB はより多くの情報を含むスタックトレースを生成できます:
#6 0x082857fc in v8::internal::Runtime_SetProperty (args=...) at src/runtime.cc:3758
#7 0xf5cae28e in ?? ()
#8 0xf5cc3a0a in loop () at test.js:6
#9 0xf5cc38f4 in test.js () at test.js:13
#10 0xf5cbef19 in ?? ()
#11 0xf5cb09a2 in ?? ()
#12 0x0809e1f9 in v8::internal::Invoke (construct=false, func=..., receiver=..., argc=0, args=0x0,
has_pending_exception=0xffffd44f) at src/execution.cc:97
まだ GDB に認識されていないフレームはソース情報が無いネイティブコードに対応します。詳細については 既知の制限事項 を参照してください。
GDB JIT コンパイルインターフェースの仕様は GDB ドキュメントに記載されています: https://sourceware.org/gdb/current/onlinedocs/gdb/JIT-Interface.html
必須要件
- V8 v3.0.9 またはそれ以降のバージョン
- GDB 7.0 またはそれ以降のバージョン
- Linux OS
- Intel 互換アーキテクチャ (ia32 または x64) の CPU
GDB JIT コンパイルインターフェースの有効化
GDB JIT コンパイルインターフェースは現在、デフォルトではコンパイルから除外され、ランタイムでは無効化されています。有効化するには以下を実行してください:
ENABLE_GDB_JIT_INTERFACE
を定義して V8 ライブラリをビルドします。scons を使用して V8 をビルドする場合は、gdbjit=on
を付けて実行してください。- V8 を起動するときに
--gdbjit
フラグを渡します。
GDB JIT 統合が正しく有効になっていることを確認するために、__jit_debug_register_code
にブレークポイントを設定してみてください。この関数は新しいコードオブジェクトについて GDB に通知するために呼び出されます。
既知の制限事項
-
現在のところ (GDB 7.2 時点)、GDB 側の JIT インターフェースはコードオブジェクトの登録を非常に効率的に処理していません。次の登録ごとに処理時間が増加します: 500 個の登録済みオブジェクトの場合、次の登録には 50ms を超える時間がかかり、1000 個の登録済みコードオブジェクトでは 300ms を超える時間がかかります。この問題は GDB 開発者に報告されています が、現在のところ解決策はありません。GDB にかかる負担を軽減するために、現在の GDB JIT 統合の実装は 2 つのモード (default および full) で動作します (full モードは
--gdbjit-full
フラグで有効化)。default モードでは、V8 は GDB に対しソース情報が付随するコードオブジェクト (通常はすべてのユーザースクリプトを含む) についてのみ通知します。full モードでは、すべての生成されたコードオブジェクト (スタブ、IC、トランポリンなど) について通知します。 -
x64 環境では、GDB は
.eh_frame
セクションなしではスタックの巻き戻しが適切に行えません (Issue 1053) -
GDB はスナップショットからデシリアライズされたコードについて通知を受けません (Issue 1054)
-
Intel 互換 CPU 上の Linux OS のみサポートされています。別の OS の場合、異なる ELF ヘッダーが生成されるか、完全に異なるオブジェクト形式が使用される必要があります。
-
GDB JIT インターフェースを有効化すると、コンパクト GC が無効化されます。これは、GDB への負荷を軽減するためで、移動された各コードオブジェクトの登録解除と再登録が大きなオーバーヘッドを引き起こすためです。
-
GDB JIT 統合はあくまで おおよその ソース情報のみを提供します。ローカル変数、関数の引数、スタックレイアウトなどについての情報は提供されません。また、JavaScript コードのステップ実行や特定行でのブレークポイント設定もサポートされません。ただし、関数名を指定してブレークポイントを設定することは可能です。