これまでの道のり
1 年前、Chrome は初期サポートを発表 を使用します。
基本的なステップ実行のサポートを紹介し、機会について説明しました。 代わりに DWARF 情報を使用する ソースマップは将来的に利用可能になります。
- 変数名の解決
- プリティ プリントのタイプ
- ソース言語の式を評価する
- ほか多数
本日は、期待していた機能が実現した様子をご紹介します Emscripten と Chrome DevTools のチームは 特に C および C++ アプリの場合は特にそうです。
なお、これはまだベータ版であることにご留意ください 更新するには、すべてのツールの最新バージョンを使用する必要があります。 ご自身の責任においてご利用ください。問題が発生した場合は、 https://bugs.chromium.org/p/chromium/issues/entry?template=DevTools+issue.
前回と同じ単純な C の例から始めましょう。
#include <stdlib.h>
void assert_less(int x, int y) {
if (x >= y) {
abort();
}
}
int main() {
assert_less(10, 20);
assert_less(30, 20);
}
コンパイルには、最新の Emscripten を使用します。
元の投稿と同様に -g
フラグを渡して、デバッグ
含まれます
emcc -g temp.c -o temp.html
これで、生成されたページを localhost HTTP サーバー( (serve を使用した場合の例)、および 最新版の Chrome Canary で開いてください。
今度は、Chrome と統合するヘルパー拡張機能も必要です。 DevTools ですべてのデバッグ情報を WebAssembly ファイルにエンコードされますこちらの リンク: goo.gle/wasm-debugging-extension
また、DevTools で WebAssembly デバッグを有効にします。 テスト。Chrome DevTools を開いて、歯車アイコン(⚙)アイコンをクリックします。 [DevTools] ペインの右上で、[Experiments] パネルに移動します。 [WebAssembly Debugging: Enable DWARF support] チェックボックスをオンにします。
[Settings] を閉じると、DevTools によって再読み込みが提案されます。 設定を適用するだけです1 回限りは以上です できます。
[ソース] パネルに戻り、[一時停止 例外(⏸ アイコン)を選択してから、[Pause on キャッチされた例外] をオンにします。 ページを再読み込みしてください。例外により DevTools が一時停止したことがわかります。
デフォルトでは、Emscripten で生成されたグルーコードで停止しますが、
[Call Stack] ビューが表示されます。これは、
呼び出された元の C 行に移動できます。
abort
:
これで、[スコープ] ビューを見ると、元の名前を確認できます。
C/C++ コードで変数と値を宣言することで、インフラストラクチャを
$localN
のようなマングリングされた名前の意味と、それらが
ソースコードが表示されます。
これは整数などのプリミティブ値だけでなく、 構造体、クラス、配列などの型も含まれます。
リッチ型のサポート
これらを示す、より複雑な例を見てみましょう。この マンデルブロ フラクタルを 次の C++ コードは次のようになります。
#include <SDL2/SDL.h>
#include <complex>
int main() {
// Init SDL.
int width = 600, height = 600;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window;
SDL_Renderer* renderer;
SDL_CreateWindowAndRenderer(width, height, SDL_WINDOW_OPENGL, &window,
&renderer);
// Generate a palette with random colors.
enum { MAX_ITER_COUNT = 256 };
SDL_Color palette[MAX_ITER_COUNT];
srand(time(0));
for (int i = 0; i < MAX_ITER_COUNT; ++i) {
palette[i] = {
.r = (uint8_t)rand(),
.g = (uint8_t)rand(),
.b = (uint8_t)rand(),
.a = 255,
};
}
// Calculate and draw the Mandelbrot set.
std::complex<double> center(0.5, 0.5);
double scale = 4.0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
std::complex<double> point((double)x / width, (double)y / height);
std::complex<double> c = (point - center) * scale;
std::complex<double> z(0, 0);
int i = 0;
for (; i < MAX_ITER_COUNT - 1; i++) {
z = z * z + c;
if (abs(z) > 2.0)
break;
}
SDL_Color color = palette[i];
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
SDL_RenderDrawPoint(renderer, x, y);
}
}
// Render everything we've drawn to the canvas.
SDL_RenderPresent(renderer);
// SDL_Quit();
}
ご覧のとおり、このアプリケーションはまだかなり小さく、1 つの ファイルには 50 行のコードが含まれていますが、今回は の SDL ライブラリなどの 画像や、画像から得られる複素数を C++ 標準ライブラリ。
上記と同じ -g
フラグを使用してコンパイルし、
デバッグ情報を提供します。また、Emscripten に SDL2 の提供を依頼します。
任意のサイズのメモリを使用できます。
emcc -g mandelbrot.cc -o mandelbrot.html \ -s USE_SDL=2 \ -s ALLOW_MEMORY_GROWTH=1
生成されたページをブラウザでアクセスすると、 ランダムな色のフラクタル図形:
DevTools を開くと、再び元の C++ ファイルが表示されます。この ただし、コードにエラーはないため、次のように設定します。 ブレークポイントを追加します。
再度ページを再読み込みすると、デバッガが C++ ソース:
右側にはすでにすべての変数が表示されていますが、width
のみです。
height
は現在初期化されているため、何も実行することは
検査します。
メインのマンデルブロ ループ内に別のブレークポイントを設定して、 少し前にスキップします。
この時点で、palette
はランダムな色で塗りつぶされています。
配列自体も個々の配列自体も展開できます
SDL_Color
構造を検証し、そのコンポーネントを検査して、
すべて正常です(たとえば、「アルファ」チャンネルは常に
にします)。同様に、実際の値と元の値の状態を
center
変数に格納された複素数の虚数部。
他の方法では見つけにくい、深くネストされたプロパティにアクセスする場合は、 [スコープ] ビューに移動するには、コンソール 評価も行われています。ただし、より複雑な C++ 式は サポートされていません。
実行を数回再開して、内部 x
の状態を確認してみましょう。
再度 [スコープ] ビューを表示して、
変数名をウォッチリストに追加するか、コンソールで評価するか、
ソースコード内の変数にカーソルを合わせます。
ここから、C++ ステートメントをステップインまたはステップ オーバーして、 他の変数も変化しています。
デバッグ情報があればうまくいきますが、 デバッグでビルドされていないコードをデバッグする場合、 選択肢はあるか?
未加工の WebAssembly デバッグ
たとえば、Emscripten に事前構築済みの SDL ライブラリを
ソースから直接コンパイルするのではなく
現時点では、関連するソースをデバッガが見つける方法はありません。
もう一度 SDL_RenderDrawColor
に移動しましょう。
WebAssembly デバッグの生の体験に戻りました。
少し恐ろしく見えますが、ほとんどのウェブ デベロッパーはあまりそう思わないでしょう。 デコーダをデバッグする必要はあるか ビルドされたライブラリがデバッグ情報なしで サードパーティ ライブラリをご自身で管理できない場合、または 本番環境でのみ発生するバグの いずれかに遭遇した場合です
そのような場合に備えて、基本的な デバッグ経験も豊富です。
まず、WebAssembly デバッグを未加工の使用したことがある場合は、
逆アセンブル全体が 1 つのファイル内に表示され、
Sources エントリ wasm-53834e3e/
wasm-53834e3e-7
がどの関数に対応しているかを推測する回数が増える。
新しい名前生成スキーム
逆アセンブル ビューの名前も改善しました。これまでは 数値インデックスだけを使う 関数の場合は名前をまったく持たないこともあります
他の逆アセンブル ツールと同様の名前を生成します。名前には、
WebAssembly 名セクションのヒントを使用する
インポート/エクスポートのパスができ
最後にすべて失敗した場合
$func123
など、アイテムの型とインデックスに基づいてオブジェクトが作成されます。Google Chat では
上のスクリーンショットでは、これはすでにわずかに
スタックトレースと逆アセンブルが
わかりやすくなっています
利用可能な型情報がない場合、検査が難しい可能性がある プリミティブ以外のすべての値(たとえば、ポインタは 通常の整数として格納され、その背後に何が保存されているかは できます。
メモリ検査
以前は、[Scope] ビューで env.memory
で表される WebAssembly メモリ オブジェクトを展開して検索するだけでした。
表示されます。いくつかの簡単なシナリオでうまくいったが、
拡張が特に便利でデータの再解釈ができず
データをバイト値以外の形式で指定します。そこで、便利な機能を
線形メモリ インスペクタも役立ちます。
env.memory
を右クリックすると、新しい
[メモリを検査] というオプションを使用します。
クリックすると、Memory Inspector が表示されます。 16 進数と ASCII ビューで WebAssembly メモリを検査できます。 特定の住所への移動、 保存できます。
高度なシナリオと注意点
WebAssembly コードのプロファイリング
DevTools を開くと、WebAssembly コードが階層化される宛先
デバッグを有効にしますこのバージョンは動作が遅く、
つまり、console.time
、performance.now
は
などの方法でコードの速度を測定する方法を
表示される数字は実際のパフォーマンスを表すとは限らないため、
ありません。
代わりに、DevTools の [Performance] パネルを使用する必要があります。 これによりコードが最大速度で実行され さまざまな部門に費やされた時間の詳細な内訳:
または、DevTools を閉じてアプリケーションを実行することもできます。 完了したら、それらを開いてコンソールを調べます。
プロファイリングのシナリオは今後改善する予定ですが、現時点では 注意すべき点がありますWebAssembly についてさらに詳しく WebAssembly コンパイル パイプラインに関するドキュメントをご覧ください。
異なるマシン(Docker / ホストなど)でのビルドとデバッグ
Docker、仮想マシン、リモートビルド サーバーでビルドする場合、 多くの場合、ソースファイルへのパスがファイル パスに 自分のファイル システムのパスと一致しない場合に、 確認できます。この場合、ファイルは Sources パネルの読み込みに失敗します。
この問題を修正するため、 C/C++ 拡張オプションを使用します。任意のパスを再マッピングしたり、 DevTools でソースの検索に役立ちます。
たとえば、ホストマシン上のプロジェクトが
C:\src\my_project
ですが、次の Docker コンテナ内でビルドされています。
そのパスが /mnt/c/src/my_project
として表されていた場合、
これらのパスを接頭辞として指定することで、デバッグ中に元に戻すことができます。
最初に一致した接頭辞が優先されます。他の C++ 言語に習熟している場合、
デバッガ。このオプションは set substitute-path
コマンドに似ています。
target.source-map
設定を使用します。
最適化されたビルドのデバッグ
他の言語と同様に、デバッグが最適に機能するのは、 無効です。最適化では、関数同士のインライン化、並べ替えや コードの一部を完全に削除したり デバッガを混乱させ、ユーザーをユーザーとして操作してしまう可能性があります。
デバッグ エクスペリエンスは限定的であってもかまわないが、
最適化されたビルドをデバッグすると、最適化のほとんどが
関数のインライン化を除きます。残りの
ただし、当面は -fno-inline
を使用して
-O
レベルの最適化でコンパイルするときに無効にします。次に例を示します。
emcc -g temp.c -o temp.html \ -O3 -fno-inline
デバッグ情報の分離
デバッグ情報では、コードに関する多くの詳細が保持されます。 型、変数、関数、スコープ、ロケーションなど、 デバッガにとって便利です。そのため、多くの場合、ファイアウォール ルールの 構築できます。
WebAssembly モジュールの読み込みとコンパイルを高速化するには、
このデバッグ情報を
表示されます。そのためには、Emscripten で -gseparate-dwarf=…
フラグを次のように渡します。
ファイル名を指定します。
emcc -g temp.c -o temp.html \ -gseparate-dwarf=temp.debug.wasm
この場合、メイン アプリケーションはファイル名のみを保存します。
temp.debug.wasm
。ヘルパー拡張機能が特定して、
読み込む必要があるかもしれません。
この機能を上記のような最適化と組み合わせると、 ほぼ最適化された製品版ビルドを リリースするために使用できます ローカルのサイドファイルを使用してデバッグできます。この例では 保存された URL をオーバーライドして、拡張機能が サイドファイルを見つけます。次に例を示します。
emcc -g temp.c -o temp.html \ -O3 -fno-inline \ -gseparate-dwarf=temp.debug.wasm \ -s SEPARATE_DWARF_URL=file://[local path to temp.debug.wasm]
続く
新機能がたくさんありました。
こうした新しい統合により、Chrome DevTools は実用的で JavaScript だけでなく、C / C++ アプリにも使用できる強力なデバッガです。 これまで以上に簡単にアプリを使用できます。 共有のクロス プラットフォーム ウェブに提供します。
しかし、私たちの取り組みはまだ終わっていません。このコースでは 次の段階として進めていきます
- デバッグ時の粗いエッジのクリーンアップ。
- カスタム型フォーマッタのサポートを追加しました。
- 現在、 プロファイリング(WebAssembly アプリの場合)
- 見つけやすくするためにコード カバレッジのサポートを追加しました。 ありません。
- コンソール評価での式のサポートを改善しました。
- 対応言語の追加。
- …など
当面は、ご自身のコードで現在のベータ版をお試しいただき、見つかったものについてお知らせください。 問題の https://bugs.chromium.org/p/chromium/issues/entry?template=DevTools+issue.
プレビュー チャンネルをダウンロードする
デフォルトの開発ブラウザとして Chrome の Canary、Dev、または Beta を使用することを検討してください。これらのプレビュー チャンネルを使用すると、DevTools の最新機能にアクセスしたり、最先端のウェブ プラットフォーム API をテストしたり、ユーザーに先駆けてサイトの問題を検出したりできます。
Chrome DevTools チームへのお問い合わせ
以下のオプションを使用して、投稿の新機能や変更点、または DevTools に関連するその他のことについて話し合います。
- ご提案やフィードバックは、crbug.com からお送りください。
- DevTools の問題を報告するには、その他のオプション() >ヘルプ >DevTools で DevTools の問題を報告します。
- @ChromeDevTools でツイートしてください。
- DevTools の新機能に関する YouTube 動画または DevTools のヒントの YouTube 動画にコメントを残してください。