From: KUBO T. <ku...@ji...> - 2004-11-21 10:29:16
|
久保です。 Masao Mutoh <mu...@hi...> writes: >> GnomeCanvas が削除された後に GnomeCanvasItem が削除されて、 >> >> - gnome_canvas_item_dispose() >> - redraw_if_visible() >> - gnome_canvas_request_redraw() >> --> GnomeCanvas は削除されているのでwarning >> >> となっているところまではつきとめました。 >> とりあえずは rbgnome-canvas-item.c の citem_intialize() で >> g_object_ref(group); >> の代りに >> g_object_ref(_SELF(self)); >> とするとwarningは消えるのですが、これは明らかに間違った対処方法(二重ref) >> なのでCVSに入れるわけにはいかない。 > > 他のやつもこの辺が問題だったんですよね。 > > この現象ってrequest_redrawする前段階に二重にunrefされてるから > GnomeCanvasが削除されてるんですよね。 いいえ。GnomeCanvas が削除されること自体は問題ないのですが、その時点で GnomeCanvasItem が ruby 側から ref されているのが問題なのではないかと 思います。おそらく GnomeCanvasItem は GnomeCanvas のみから参照されてい るという前提ではないかと。 試しに ruby 側からの ref をなくすために gnomecanvas/sample/canvas.rb に以下のパッチを当てて実行したところ、終了時のエラーが出なくなりました。 # signal_connect を無効化させているのは、signal_connect は ruby オブジェ # クトへの参照を保持している場合があるためです。 citem_intialize() の g_object_ref(group) を消した状態でも同じです。 ---------------------- ここから ---------------------- --- canvas.rb.~1.5.~ 2002-11-05 20:26:21.000000000 +0900 +++ canvas.rb 2004-11-21 17:36:23.000000000 +0900 @@ -40,6 +40,14 @@ require 'canvas-rich-text' require 'canvas-curve' +module Gnome + class CanvasItem + def signal_connect(*dummy) + # do nothing + end + end +end + class CanvasSample < Gtk::Window def initialize super(Gtk::Window::TOPLEVEL) @@ -64,5 +72,6 @@ Gtk.init canvas = CanvasSample.new() +GC.start Gtk::main() ---------------------- ここまで ---------------------- > だとすれば、二重refであっても、それが適正な回数であれば問題ないと思います。 > 問題は適正かどうかなのですが、これはこれで難しそうですね。 > この場合のメモリリークは許容範囲内かもしれないですし(^^;)。 glib のソースの g_object_last_unref() に手を加えて個々のオブジェクトが 削除されるタイミングを見たところ、citem_intialize() に g_object_ref(group) がついている状態だと GnomeCanvasGroup は最後まで削 除されませんでした。おそらくむとうさんのところでエラーが消えたのは libgnomecanvas 側、ruby 側両方の終了処理が終わっても GnomeCanvasGroup の ref が残っていて最後まで gnome_canvas_item_dispose() が呼ばれなかっ たためではないかと思います。 > もしかしたら他のメソッドでg_object_refをしないといけない場所があるのかも > しれませんね。 Ruby/GLib2 に手をいれないといけないような予感が....。 今の Ruby/GLib2 だと、GObject に対応する ruby object を生成すると GObject の refcount が 1 上がるのですが、refcount を上げずに weakref のみで参照する ruby object が必要かも。 > ちなみに、これって、久保さんの環境だとサンプルでも再現しますか? > というのは私の環境ではもうこの現象出ていないんですよね。 再現しています。 あと、むとうさんの今日の commit で、エラー時の core dump がまた起きる ようになりました。finalizer が走っている最中に例外が上がると core を吐 くようです。 では、再見 -- 久保 健洋 email: ku...@ji... web: http://www.jiubao.org GnuPG fingerprint = 5F7B C8EF CA16 57D0 FDE1 9F47 C001 1F93 AC08 2262 |