2019-10-31 (Th) [長年日記]
_ wayfire 更にデバッグ
wayfire を使い始めたころからの症状だけど、 wireshark を X11 で動かすと、
- capture 開始
- パケットが表示されたら
ctrl+q
- ポップアップが出るので、保存せずに終了
これだけで wayfire が落ちる。
以前デバッグしてみたところ、解放済みメモリを使ってるらしいことは判った。
で、今日もっとデバッグしてみた。
- unique_ptr が nullptr である。
- しかし nullptr にしている箇所はない。
- その unique_ptr はメンバなので、インスタンスが破棄された際に unique_ptr も破棄されて、結果 nullptr でクリアされたのかもしれない。
- だとすれば、そのインスタンスは既に破棄されているはず。
で、
- そのインスタンスを更に使おうとするのは、
last_focus
にセットされているせい。 last_focus
は view になったり nullptr がセットされたりするようだ。- destroy されてるはずなのに
last_focus
が nullptr になってないのが問題なのだろう。
んで、destroy 時に set_last_focus()
漏れがある? と思ったけど、
そういう作りではない。
view が destroy されたら signal が emit されて、その signal handler で
set_last_focus(nullptr)
する感じ。
漏れようがない。
…と思ったんだけど、set_last_focus(nullptr)
してるのは、
disappeared
の時なんだよね。destroy 時ではなく、unmap の時。
これ… unmap 処理が呼ばれずに destroy してとか、ない?? と思った。
wlroots の xwayland 対応の仕様として、 map されてる view は、いきなり destroy されても必ず unmap は呼ぶ、 とか書いてあった。怪しい。そこがうまくいってないとか?
wayfire 側 unmap, destroy のところに fprintf を突っ込んでみたら、 確かに unmap が来て destroy が来てる。wlroots は正しそう。 そういう問題ではないのか?
でも set_last_focus()
の引数を見ると、map してないのに set_last_focus()
が
呼ばれてるんだよね。これ、まずくない?
constructor → set_last_focus → destroy って流れだと、
unmap が呼ばれないので last_focus
がクリアされずに destroy が走ってしまって、
ポインタが残ってしまう。
んー、しかし、set_last_focus()
の前に is_mapped()
はチェックしてる。
……ように見えて、その後、view の親を一番上まで辿って、set_last_focus()
してる。
その際に is_mapped()
はチェックしてない。
これ? と思ったらビンゴ。
ただ、子が map されてるのに親が map されてない、という奇妙な状況になるのが、
理由がわからない。とりあえず、一番上の親が map されてなかったら set_last_focus()
しない、って処理を入れると回避はできた。
https://github.com/masm11/wayfire/commit/718c363b333f7ea5b69eda531ded84cce5005e44
……思えば遠くへ来たもんだw
ともかく、これで安心して使えるかな。使えるといいな。
_ リステップ 更新
お知らせを見て歓喜した!
ステージ中とそれ以外とで、別々にボリュームを設定できるようになった。
よし、これで、ステージ中以外は SE を鳴らしつつ、 ステージ中だけしゃんしゃん音を消すことができる!
このゲーム、私が始めたのは最近だけど、リリースから何年経ってるのかな。3年くらい? 今頃こんな小さな機能追加があるとは思ってなかった。 要望があるならとっくに追加されてるだろうし、追加されてないってことは要望は多くない んだろう、くらいに思ってた。
「神アプリ」の称号が相応しい。