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 に通知するために呼び出されます。
既知の制限事項 #
JIT インターフェイスの GDB 側 (GDB 7.2 現在) は、現在コードオブジェクトの登録を非常に効率的に処理しません。登録するごとに時間がかかります。500 個のオブジェクトが登録されると、次の登録に 50 ミリ秒以上かかり、1,000 個のコードオブジェクトが登録されると、300 ミリ秒以上かかります。この問題は GDB 開発者に報告されました が、現時点では利用可能なソリューションはありません。GDB に加わる負担を軽減するために、GDB JIT 統合の現在のインプリメンテーションでは 2 つのモードが動作しています: default と full (
--gdbjit-full
フラグで有効化)。default モードでは、V8 はソース情報が付加されたコードオブジェクトについてのみ GDB に通知します (通常、すべてのユーザーのスクリプトを含みます)。full モードでは、生成されたすべてのコードオブジェクト (スタブ、IC、トランポリン) について通知します。GDB は、
.eh_frame
セクションなしではスタックを適切にアンワインドできません (x64 上) (Issue 1053)GDB は、スナップショットからデシリアライズされたコードについては通知されません (Issue 1054)
Intel 互換 CPU 上の Linux OS のみサポートされます。異なる OS の場合は、異なる ELF ヘッダーを生成するか、全く異なるオブジェクト形式を使用する必要があります。
GDB JIT インターフェイスを有効にすると、コンパクト化 GC が無効になります。これは、移動された各コードオブジェクトを登録解除して登録し直すことでかなりのオーバーヘッドが発生するため、GDB に加わる負担を軽減するために行われます。
GDB JIT 統合は、近似的な ソース情報のみを提供します。ローカル変数、関数の引数、スタックのレイアウトなどの情報は提供しません。JavaScript コードをステップ実行したり、特定の行にブレークポイントを設定することはできません。ただし、関数の名前でブレークポイントを設定することはできます。