Emscripten
Runtimeと
デバッグ
junji hashimoto
目次
- はじめに
- 動機
- 長い闘い
- Runtimeの構造
- DLLの仕組み
-
デバッグ方法
- ソースとの対応
- printfデバッグ
- 終わりに
はじめに
- この発表を行うにあたり、某企業や団体とは無関係です。
- 実際の業務に使用しているわけではないので、内容についてはご了承ください。
- Emscriptenのランタイムに関する資料がありましたら共有お願いします。
Emscriptenを始めた動機
- 食指が動く
-
各種妄想
- AWSのLambdaでHaskellを動かしたい。
- ブラウザ上で自作のHaskell製プログラムを動かしたい
- HaskellのインタプリタhugsをEmscriptenでビルドし始める。
戦いの幕開け(よくある問題)
- Emscriptenは環境
- OSと独立したファイルシステムと環境変数
- JSのイベントモデルから来る問題
- CLIのプログラムをWebに移植するには、stdinのあたりの処理の書き直しが必要
- window.promptの置き換え
-
JSの闇
- promise、awaitに期待?
- 一旦できたかに思われたが。
長い闘い
- その後
- インタプリタとCとJSの連携(DLL関連)
- 未知の領域へ(問題だらけ)
- realpathでEINVAL(musl起因)
- LD_LIBRARY_PATHが動かない
- dlopenでセグフォ(RTLD_GLOBALのバグ)
- chdirで例外
たどり着いた結論
- ランタイムのアーキテクチャがわからないとデバッグできない。
- どこにprintfをおけばいいのか
- スタックトレースが意味不明
- ftCallとかでて落ちる。
- straceがない。(ブラウザなので)
ということで
- Emscriptenのランタイムの紹介をします。
x86とのアーキテクチャの違い
x86 | Emscripten | |
---|---|---|
レジスタ(PCも) | ある | ない |
スタックの向き | 上位アドレスから 下位アドレス |
下位アドレスから 上位アドレス |
ヒープの場所 | コードの後 | スタックの後 |
コードの場所 | メモリ上 | jsの関数 |
関数ポインタ | メモリ上のアドレス | 関数テーブルの インデックス |
Runtimeの構造
JSのオブジェクト全体
スタック
ヒープ
関数テーブル
FUNCTION_TABLE_<sig>
FS:File System
関数('_'で始まる)
関数ポインタ用:
<sig>は関数型情報
'_'で始まる関数への
参照が入っている
通常呼び出し用
DLL(SIDE_MODULE)の構造
MAIN_MODULE(本体)からevalで呼ばれる
スタック
ヒープ
関数テーブル
FUNCTION_TABLE_<sig>
関数('_'で始まる)
関数ポインタ用:
MAIN_MODULEの
ポインタと
SIDE_MODULE
両方がマージ
関数:
DLLの関数のみ
MAIN_MODULE
と共有
関数の呼ばれ方
-
モジュール内の場合
- '_'付きの関数が直接呼ばれる
-
モジュール外や関数ポインタの場合
- 関数テーブルのポインタをftCallに渡して実行
- ftCallには型がある。(signatureとよぶらしい)
- v:void
- i:int
- i:pointer
- d:double
ソースとの対応
-
ランタイム
- emscripten/src
-
ftCallなどの関数生成
- emscripten/emscripten.py
-
libc(musl)とかcのライブラリ
- emscripten/system
デバッグ方法
- printfデバッグ
- 自分のソースにprintf
- ランタイムのライブラリにconsole.log
- 最適化しないで動く場合は生成されたJSにconsole.log
- 最適化しないと動かない場合は生成されたJSをjs-beautifyで整形してconsole.log
- elseifや小数点で間違ったJSを吐くので手で直す。
他の方法はないのか
- デバッグオプションは?
- EMCC_DEBUGはコード生成のデバッグ用でランタイムのエラーには無力
- 代わりにLIBRARY_DEBUGというのがあるらしい
- デバッガは?
- node inspectとかコードが大きすぎて動かない
- 最適化を外すとブラウザで動かない。
- サイズが10Mbyteごえなので
終わりに
- ランタイムの構造の概要とデバッグ方法の紹介
- 当初の問題はEmscriptenでFixされています。
- Haskellも動くようになりました。
デバッグのためのEmscriptenの内部
By Junji Hashimoto
デバッグのためのEmscriptenの内部
- 2,773