WebGL-Native: Raspberry Piで起動しない問題
prev: https://zenn.dev/okuoku/scraps/d4419915c37216
next:
よもやこんな苦労するとは。。
起動時に刺さる
ひとまず現状見えている問題は:
- Raspbian OSに収録されているOpenGLが正常に起動しない 。 これは手でビルドしたら治った ので、たぶんSDL2が自分でロードするOpenGLと、実行ファイルがリンクしているOpenGLが一致していないのが問題だろう。
-
Emscriptenの
stdout
が何故かソケットに繋がっている 。意味わかんねぇ! ただ、これはNode.jsやUbuntu amd64上のduktapeでも同様になっていることを確認したのでたぶん問題ではない。 - 2 のソケットを経由して
stdout
に書こうとしてEDESTADDRREQ
を返却すると先に進まなくなる 。これはRaspberry Pi上のduktapeでしか起こらない。 WebGLコンテキストの生成中に進まなくなったように見えていた のはこれが原因だった。
とりあえず 3 を解く必要がある。
Raspberry Pi 3 に挿しかえる
Raspberry Pi 1とRaspberry Pi 3はソフトウェア的には互換なので、RPi1で使っていたSDカードをRPi3に挿しても普通に起動する。というわけでRPi1ではメモリ不足で使えなかった gdb
が使えるようになった。
まぁゲーム機でも開発機は実機の倍のメモリを搭載したりしてるんで、こういうインチキは許して。。
符号付き数のオーバーラップが問題だった
diff --git a/duk-nccc/duk-nccc.c b/duk-nccc/duk-nccc.c
index 0021715..9fe2f6f 100644
--- a/duk-nccc/duk-nccc.c
+++ b/duk-nccc/duk-nccc.c
@@ -82,7 +82,7 @@ value_out(duk_context* ctx, uint64_t* out, char type, duk_idx_t vin){
}else if(get_pointer(ctx, vin, &v)){
*out = v;
}else{
- *out = duk_require_number(ctx, vin);
+ *out = (int64_t)duk_require_number(ctx, vin);
}
break;
case 'f':
gdb
でステップ実行してみると、(エラーにより) -89
を返却すべきところで 0
を返却していることがわかった。で、これは double
の -89.0
を uint64_t
にキャストしているのが原因のようなので、上記のように修正することで期待通りに動作するようになった。
... x86と挙動が違うのかコレ。。
画面が壊れる問題
というわけで無事OpenGLで描画する所までは進行したものの、画面にゴミを表示して止まってしまった
こんなもんどうやってデバッグすればいいんだ。。
前回OpenGLスタックを手でリビルドしている ので、それをRaspberryPi OS本来のものに戻してみるのかな。。
止まり方はかなり深刻な感じで、おそらくGPU側をハングさせてしまっている。この状況になると、SSHやコンソールも一切操作できなくなる。(非特権ユーザがシステム全体を止められてしまうことになる)
クラッシュ箇所は判明したが。。
とりあえずテクスチャのアップロードが原因であることは分かった。
この行を実行するとカーネルパニックする。
ちょっと芸術的な壊れ方だな。
#0 droppoint () at /home/pi/repos/cwgl/yfrm/src-sdl2/yfrm-ctx-sdl2.c:115
#1 cwgl_priv_check_current (ctx=0x411e20)
at /home/pi/repos/cwgl/yfrm/src-sdl2/yfrm-ctx-sdl2.c:115
#2 0x76b9db20 in cwgl_texImage2D (ctx=<optimized out>,
target=(CWGL_ENUM_DUMMY), level=2, internalformat=(CWGL_ENUM_DUMMY),
width=512, height=512, border=0, format=(CWGL_ENUM_DUMMY),
type=(CWGL_ENUM_DUMMY), buf=0x5d824af0, buflen=1048576)
at /home/pi/repos/cwgl/src-gles2/cwgl-gles2-s3.c:58
#3 0x7690ad90 in stub_cwgl_texImage2D (in=<optimized out>,
out=<optimized out>) at /home/pi/repos/cwgl/ncccstubs/stubcode.inc.c:61
#4 0x00015494 in nccc_call_trampoline (ctx=0x68918)
at /home/pi/repos/cwgl/duk-nccc/duk-nccc.c:235
#5 0x00019c18 in duk__handle_call_raw (thr=thr@entry=0x68918,
idx_func=idx_func@entry=10, call_flags=call_flags@entry=8)
at /home/pi/repos/cwgl/duktape260/duk_js_call.c:2268
level=2
の指定から、MIPMAPが怪しいか。。?確かに level == 0
のものだけ通すようにしたらクラッシュはしなくなった。
しかし、このまま実行を続けても、
-------- GLSL link error: ERROR:CUSTOM-6 (fragment shader, line -1) Out of memory
のように出てシェーダのコンパイルに失敗してしまった。
Full KMS + SDL2 KMSDRM で試す
BroadcomのGLESを使うのは諦めてMesaを使うことにした。現実的なワークロードを動かすのはもう無理だな。。(Broadcomのスタックと違い、MesaはOpenGL実装をCPU側で行っていて、3D描画のみをGPUにオフロードするのでちょっと重い。)
結果 amd64 Linuxと同じくDevelopment buildと黒画面に出る ところまでは動作した。
ただamd64では正常に描画される状態まで持っていけたものの、Raspberry Piの方ではDRI内部でクラッシュしてしまう。
CNT: 2218
Thread 1 "yuniduk" received signal SIGSEGV, Segmentation fault.
0x596426b4 in ?? () from /usr/lib/arm-linux-gnueabihf/dri/vc4_dri.so
(gdb) bt
#0 0x596426b4 in ?? () from /usr/lib/arm-linux-gnueabihf/dri/vc4_dri.so
#1 0x00000028 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
とりあえず 2218 回目のOpenGL callでbreakしてみる:
Thread 1 "yuniduk" hit Breakpoint 1, droppoint ()
at /home/pi/repos/cwgl/yfrm/src-sdl2/yfrm-ctx-sdl2.c:108
108 printf("Reached droppoint.\n");
(gdb) bt
#0 droppoint () at /home/pi/repos/cwgl/yfrm/src-sdl2/yfrm-ctx-sdl2.c:108
#1 0x76b80f34 in cwgl_priv_check_current (ctx=0x568468)
at /home/pi/repos/cwgl/yfrm/src-sdl2/yfrm-ctx-sdl2.c:115
#2 0x76b82a28 in cwgl_drawElements (ctx=0x568468, mode=(CWGL_ENUM_DUMMY),
count=5190, type=(CWGL_ENUM_DUMMY), offset=0)
at /home/pi/repos/cwgl/src-gles2/cwgl-gles2-s2.c:81
#3 0x7682ed78 in stub_cwgl_drawElements (in=0x7effe060, out=0x7effe060)
at /home/pi/repos/cwgl/ncccstubs/stubcode.inc.c:61
... ただの描画。。つまりメモリ不足だな。。 MESA_DEBUG=1
して実行すると、
CNT: 788
Mesa: User error: GL_OUT_OF_MEMORY in glTexImage
Mesa: User error: GL_OUT_OF_MEMORY in glTexImage2D
CNT: 789
動いた
しかし遅い。。