C/C++ WebAssembly をデバッグする

Sofia Emelianova
Sofia Emelianova

WebAssembly を使用すると、C/C++ コードをウェブ上でネイティブ スピードに近い速度で JavaScript とともに実行できます。このドキュメントでは、Chrome DevTools を設定して使用し、このようなアプリケーションをより適切にデバッグする方法について説明します。

DevTools を設定すると、次のことができます。

  • [ソース] > [エディタ] で元のコードを検査します。
  • コード行のブレークポイントで実行を一時停止し、コンパイルされた .wasm バイナリ ファイルではなく、元の C/C++ ソースコードをステップ実行します。

一時停止中は、次のことができます。

  • 元のソースファイルの変数にカーソルを合わせると、その値が表示されます。
  • [コールスタック] の関数名と [スコープ] の変数を理解する。
  • 深くネストされたプロパティと複雑なオブジェクトを コンソールに出力します。
  • Memory Inspector を使用してオブジェクトのメモリを調べます。

設定

DevTools で C/C++ WebAssembly デバッグを有効にするには:

  1. DWARF デバッグ情報を含めてアプリケーションをコンパイルします。最新の Emscripten コンパイラを実行し、-g フラグを渡します。次に例を示します。

    emcc -g source.cc -o app.html
    

    詳細については、デバッグ情報を使用してプロジェクトをビルドするをご覧ください。

  2. C/C++ DevTools サポート(DWARF)Chrome 拡張機能をインストールします。

デバッグ

DevTools をセットアップしたら、コードをデバッグします。

  1. DevTools を開くと、ウェブサイトが検証されます。このチュートリアルでは、必須の -g フラグを使用してコンパイルされたこちらのデモページで試すことができます。
  2. 必要に応じて、作成したファイルをグループ化して、移動を容易にします。[ソース] で、その他メニュー。 > [ページ] > チェックボックス。 > [作成者/デプロイ別にグループ化] 試験運用中。 をオンにします。
  3. ファイルツリーから元のソースファイルを選択します。この場合は mandelbrot.cc です。
  4. コード行ブレークポイントを設定するには、エディタの左側の列にある行番号をクリックします(例: 行 38)。

    38 行目に設定されたコード行ブレークポイント。

  5. コードをもう一度実行します。実行は、ブレークポイントのある行の前に停止します。

一時停止している間に、次の操作をお試しください。

  • [ソース] > [エディタ] で、変数にカーソルを合わせると、ツールチップに値が表示されます。

ツールチップ内の変数の値。

  • [ソース] > [コールスタック] で、ソースの関数名を表示します。

コールスタック内のメイン関数。

  • [ソース] > [スコープ] で、ローカル変数とグローバル変数、その型、値を表示します。

ローカル変数とその値が表示された [スコープ] ペイン。

  • コンソールで、スコープで移動しにくい変数とオブジェクトを出力します。

    • 深くネストされた変数(大きな配列のインデックス付きアイテムなど)。
    • ポインタ(->)でアクセスできるオブジェクトなど、複雑なオブジェクト。展開して検査します。

ネストされた変数と複雑なオブジェクトがコンソールで展開されています。

  • [ソース] > [スコープ] で メモリ。 アイコンをクリックして [メモリ インスペクタ] を開き、オブジェクト メモリの未加工バイトを検査します。詳細については、WebAssembly メモリ検査をご覧ください。

変数のメモリを検査する。

プロファイルのパフォーマンス

DevTools をセットアップして開いている場合、Chrome が実行するコードは最適化されません。デバッグ エクスペリエンスを向上させるため、階層化されています。

この場合、コード内の console.time()performance.now() を使用してパフォーマンスをプロファイリングすることはできません。代わりに、[パフォーマンス] パネルを使用してプロファイリングしてください。

また、DevTools を開かずにプロファイリング コードを実行し、その後に開いてコンソールでメッセージを検査することもできます。

デバッグ情報を分離する

読み込みを高速化しつつデバッグ機能を向上させるには、デバッグ情報を別の .wasm ファイルに分割します。詳細については、WebAssembly のデバッグを高速化するをご覧ください。

このファイルはローカルに保持することも、別のサーバーでホストすることもできます。Emscripten でこれを行うには、-gseparate-dwarf=<filename> フラグを渡して、ファイルのパスを指定します。

emcc -g source.cc -o app.html \
     -gseparate-dwarf=temp.debug.wasm \
     -s SEPARATE_DWARF_URL=[file://local/path/to/temp.debug.wasm] | [URL]

別のマシンでビルドとデバッグを行う

Chrome を実行するマシンとは異なるオペレーティング システム(コンテナ、VM、リモート サーバー)のマシンでビルドする場合は、デバッグ ファイルのパスを手動でマッピングする必要があります。

たとえば、ローカルでプロジェクトが C:\src\project にあり、パス /mnt/c/src/project の Docker コンテナでビルドされている場合は、次のようにします。

  1. chrome://extensions/ に移動し、[C/C++ DevTools Support (DWARF)] 拡張機能を見つけて、[詳細] > [拡張機能のオプション] をクリックします。
  2. 古いファイルパスと新しいファイルパスを指定します。

指定された古いファイルパスと新しいファイルパス。

その他の情報

WebAssembly のデバッグについて詳しくは、Chrome DevTools エンジニアリング ブログをご覧ください。