バグ #1494
完了機能 #887: gtk3
gtk3: Mastodonアカウントのプロフィールを開くとランダムにSEGVする
説明
Mastodonアカウントのプロフィールタブを開くと、開いた直後や何か操作をしたランダムなタイミングでSEGVします。
[BUG] object allocation during garbage collection phase
とのことなので、gem側の問題がありそうな気がします。
ファイル
関連するチケット
Akira Ouchi さんが約3年前に更新
SEGVしない場合でも、forecast_font_sizeがcore/mui/gtk_extension.rbから削除されているためundefined methodでコケるようです。
/Users/akkie/mikutter-gtk3/core/mui/gtk_intelligent_textview.rb:119:in `block in gen_body': undefined method `forecast_font_size' for #<Pango::FontDescription:0x00007ffc9d52d068 ptr=0x00007ffca0e7cb90 own=true> (NoMethodError) from /Users/akkie/mikutter-gtk3/core/mui/gtk_intelligent_textview.rb:115:in `each' from /Users/akkie/mikutter-gtk3/core/mui/gtk_intelligent_textview.rb:115:in `each_with_index' from /Users/akkie/mikutter-gtk3/core/mui/gtk_intelligent_textview.rb:115:in `gen_body' from /Users/akkie/mikutter-gtk3/core/mui/gtk_intelligent_textview.rb:45:in `initialize' from /Users/akkie/mikutter-gtk3/plugin/mastodon_account_viewer/mastodon_account_viewer.rb:69:in `new' from /Users/akkie/mikutter-gtk3/plugin/mastodon_account_viewer/mastodon_account_viewer.rb:69:in `cell_widget' from /Users/akkie/mikutter-gtk3/plugin/mastodon_account_viewer/mastodon_account_viewer.rb:59:in `block (2 levels) in user_field_table' from /Users/akkie/mikutter-gtk3/plugin/mastodon_account_viewer/mastodon_account_viewer.rb:56:in `each' from /Users/akkie/mikutter-gtk3/plugin/mastodon_account_viewer/mastodon_account_viewer.rb:56:in `each_with_index' from /Users/akkie/mikutter-gtk3/plugin/mastodon_account_viewer/mastodon_account_viewer.rb:56:in `block in user_field_table' from <internal:kernel>:90:in `tap' from /Users/akkie/mikutter-gtk3/plugin/mastodon_account_viewer/mastodon_account_viewer.rb:55:in `user_field_table' from /Users/akkie/mikutter-gtk3/plugin/gui/widget.rb:100:in `method_missing' from /Users/akkie/mikutter-gtk3/plugin/mastodon_account_viewer/mastodon_account_viewer.rb:43:in `block (2 levels) in <top (required)>' from /Users/akkie/mikutter-gtk3/plugin/gui/widget.rb:71:in `instance_exec' from /Users/akkie/mikutter-gtk3/plugin/gui/widget.rb:71:in `instance_eval_with_delegate' from /Users/akkie/mikutter-gtk3/plugin/modelviewer/modelviewer.rb:46:in `block (3 levels) in <top (required)>' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/filter.rb:34:in `filtering' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:82:in `block (2 levels) in filtering' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:81:in `each' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:81:in `reduce' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:81:in `block in filtering' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:80:in `catch' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:80:in `filtering' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:212:in `block in collect' from /Users/akkie/mikutter-gtk3/plugin/modelviewer/modelviewer.rb:63:in `each' from /Users/akkie/mikutter-gtk3/plugin/modelviewer/modelviewer.rb:63:in `each' from /Users/akkie/mikutter-gtk3/plugin/modelviewer/modelviewer.rb:63:in `sort_by' from /Users/akkie/mikutter-gtk3/plugin/modelviewer/modelviewer.rb:63:in `cluster_initialize' from /Users/akkie/mikutter-gtk3/plugin/modelviewer/modelviewer.rb:31:in `block (4 levels) in <top (required)>' from /Users/akkie/mikutter-gtk3/plugin/gui/widget.rb:71:in `instance_exec' from /Users/akkie/mikutter-gtk3/plugin/gui/widget.rb:71:in `instance_eval_with_delegate' from /Users/akkie/mikutter-gtk3/plugin/gui/gui.rb:30:in `block (2 levels) in <top (required)>' from /Users/akkie/mikutter-gtk3/plugin/modelviewer/modelviewer.rb:24:in `block (3 levels) in <top (required)>' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/listener.rb:25:in `call' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:241:in `block (2 levels) in call_all_listeners' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:240:in `each' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:240:in `block in call_all_listeners' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:239:in `catch' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:239:in `call_all_listeners' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/pluggaloid-1.7.0/lib/pluggaloid/event.rb:62:in `block in call' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/delayer-1.2.1/lib/delayer/procedure.rb:26:in `run' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/delayer-1.2.1/lib/delayer/extend.rb:126:in `run_once_without_pop_reserve' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/delayer-1.2.1/lib/delayer/extend.rb:117:in `run_once' from /Users/akkie/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/delayer-1.2.1/lib/delayer.rb:38:in `method_missing' from /Users/akkie/mikutter-gtk3/plugin/gtk3/mainloop.rb:23:in `block (2 levels) in mainloop' from /Users/akkie/mikutter-gtk3/plugin/gtk3/mainloop.rb:12:in `loop' from /Users/akkie/mikutter-gtk3/plugin/gtk3/mainloop.rb:12:in `block in mainloop' from /Users/akkie/mikutter-gtk3/plugin/gtk3/mainloop.rb:10:in `catch' from /Users/akkie/mikutter-gtk3/plugin/gtk3/mainloop.rb:10:in `mainloop' from mikutter.rb:79:in `boot!' from mikutter.rb:115:in `<main>'
Shibafu Midorino さんが約3年前に更新
- ステータス を 分類待ち から 実装待ち に変更
IntelligentTextViewにて、"style-set" signalを購読していることが直接的な原因。
なんでこれが原因になるのかというと、GC中に次のような処理が発生するためである。
- マークフェーズで、GObjectのRubyバインディングクラスのC関数 gobj_mark() が呼ばれる
- gobj_mark() では、g_object_class_list_properties() と g_object_get_property() を使い、オブジェクトのプロパティを列挙してマークしていく
- IntelligentTextViewの親Widgetに対して gobj_mark() が呼ばれた際、列挙中に GtkWidget.style が参照される
- gtk_widget_get_style() では、構造体内のstyleに値がセットされていなかった場合はその場で新しいGtkStyleを生成しセットしてから返すようになっている
- _gtk_widget_set_style() が呼び出されると、"style-set" signalが放出される
- IntelligentTextView#set_events にて "style-set" にconnectしているため、CからRubyへのコールバックが発生する
- signalをトリガーとしたRubyへのコールバック処理ではRubyオブジェクトの割り当てがいくつか発生するため、禁忌を犯したこととなりクラッシュする
対策だが、GtkStyle関連は一律deprecatedなのでこれに関する処理は廃止して代替を模索するのが良いと思われる。
Shibafu Midorino さんが約3年前に更新
log.txtとは別タイミングのものですが、原因特定に用いたGDB バックトレースのコピーを添付しておきます。
Shibafu Midorino さんが約3年前に更新
IntelligentTextViewの "style-set" の購読およびbg_modifierに関する処理のモチベーションは親Widgetから指定された、または親と同じ色の背景色を適切にセットすることのはず。
現在であれば、親と同じ色の背景色は単にCSSで背景を透過させてしまえば十分な結果が得られる。
この方法なら、親のスタイルが変更されたことを検知して自力で更新する必要もなくなる。
"style-set" の購読は削除し、IntelligentTextViewには自身の背景色を透過させるCSSを割り当てるようにした。
Shibafu Midorino さんが約3年前に更新
Akira Ouchi さんは #note-2 で書きました:
SEGVしない場合でも、forecast_font_sizeがcore/mui/gtk_extension.rbから削除されているためundefined methodでコケるようです。
Akira Ouchi
再現する方法を確認したいのですが、これって実行環境に mikutter-twemoji が入っていますか?
Shibafu Midorino さんが約3年前に更新
Akira Ouchi さんは #note-8 で書きました:
実行環境に mikutter-twemoji が入っていますか
入ってました。
OKです。ありがとうございます。
EmojiNoteのようなinline_photo持ちのNoteが来た時に評価されるようなので、twemoji導入環境以外にも、Mastodonのカスタム絵文字を含むテキストが表示されるときにも再現できそうですね。
Shibafu Midorino さんが約3年前に更新
topic/1494-forecast-font-size
で forecast_font_size を応急処置的に復活させました。
#1498 が直れば根本対応できる可能性があります。
toshi_a 初音 さんが約3年前に更新
- 担当者 を toshi_a 初音 から Shibafu Midorino に変更
topic/1494-forecast-font-size
のforecast_font_sizeを修正しました。確認お願いします。
Shibafu Midorino さんが約3年前に更新
- ファイル Screenshot_20210925_180130.png Screenshot_20210925_180130.png を追加
- 担当者 を Shibafu Midorino から toshi_a 初音 に変更
大丈夫そうです!