Open4
WasmLinux: 2回目以降のprintfが出力されない問題
... そんな細かい問題あるか。。? printf
を2回以上実施すると、どうも最初の1回しか出ないようだ。
とりあえず色々試してみたところ、 puts
でも問題が再現し、 write
は常に正常に動作することが確認できた:
const char* msg = "Hello, world\n";
write(1, msg, 13); // ★ 出る
write(1, msg, 13); // ★ 出る
puts("Hello, world!\n"); // ★ 出る
puts("Hello, world!\n"); // ★ 出ない
ということで、write(2)が正常な以上はlibc側の内部状態が狂っている可能性が高い。
__stdout_write
が呼ばれない
printf
にせよ puts
にせよ、実際の出力は __fwritex
から行われる。
このwriteの先は __stdout_write
で、これが2回目以降に呼ばれないのが問題のようだ。 __fwritex
は常に呼ばれる。
よって、 __fwritex
にブレークポイントを仕掛けて挙動差を確認するのが良いな。
長時間放置していたら大量に出てきた
... どうなってんだコレ。。 1026
はほぼ BUFSIZ
だから、 fflush
が必要って事。。?
Rearm: 6124971
(user) syscall = 66
TLS[61]: 1 -> 38880800
(user) syscall = 407
Override syscall args (407: 6 => 4)
res = 1026 (from: 56, 38880000)
[stdout]:
[stdout]: Hello, world!
[stdout]:
[stdout]: Sleep...0
[stdout]: Sleep...1
[stdout]: Sleep...2
[stdout]: Sleep...3
[stdout]: Sleep...4
[stdout]: Sleep...5
[stdout]: Sleep...6
[stdout]: Sleep...7
[stdout]: Sleep...8
[stdout]: Sleep...9
[stdout]: Sleep...10
[stdout]: Sleep...11
[stdout]: Sleep...12
[stdout]: Sleep...13
[stdout]: Sleep...14
[stdout]: Sleep...15
[stdout]: Sleep...16
TLS[61]: 1 -> 38880800
[stdout]: Sleep...17
[stdout]: Sleep...18
[stdout]: Sleep...19
[stdout]: Sleep...20
[stdout]: Sleep...21
[stdout]: Sleep...22
[stdout]: Sleep...23
[stdout]: Sleep...24
[stdout]: Sleep...25
[stdout]: Sleep...26
[stdout]: Sleep...27
[stdout]: Sleep...28
[stdout]: Sleep...29
良く見たらターミナル判別してるじゃねぇか。。
TIOCGWINSZ
はターミナルの巾を取るioctl。というわけでfdがリダイレクトされている場合はバッファリングを強制しているようだ。伝統的なlibcは \n
で自動的にflushする挙動になっているが、まぁ無くても機能する。
( F_SVB
は setvbuf
したかどうかフラグ。)
これはどうしようも無くない。。? とりあえず(このような処理が入っていない) stderr
で逃げてみる。