GNOME Bugzilla – Bug 652420
GogThemes leaked
Last modified: 2011-06-25 14:34:06 UTC
Created attachment 189793 [details] sample file go_font_free: assertion `font->ref_count == 1' failed
Open the attached file Select the graph Open its properties window add a linear trendline to Series1 okay quit Three occurrences of: ** (gnumeric:15859): CRITICAL **: go_font_free: assertion `font->ref_count == 1' failed
I'm unable to replicate with latest git.
Unable to reproduce with git as-of Friday.
Strange, it is 100% consistent for me with current git.
Breakpoint 1, go_font_free (font=0x8181ea0) at go-font.c:41 41 g_return_if_fail (font->ref_count == 1); (gdb) p font->ref_count $2 = 2 (gdb) p font $3 = (GOFont *) 0x8181ea0 (gdb) p *font $4 = {ref_count = 2, font_index = 2, desc = 0x817f980, underline = 0, strikethrough = 0, color = 0} (gdb) p font->desc $5 = (PangoFontDescription *) 0x817f980 (gdb) p *font->desc $6 = <incomplete type> (gdb) c Continuing. ** (/home/aguelzow/gnumeric/bin/gnumeric:7366): CRITICAL **: go_font_free: assertion `font->ref_count == 1' failed Breakpoint 1, go_font_free (font=0x817ec30) at go-font.c:41 41 g_return_if_fail (font->ref_count == 1); (gdb) p font->ref_count $7 = 24 (gdb) c Continuing. ** (/home/aguelzow/gnumeric/bin/gnumeric:7366): CRITICAL **: go_font_free: assertion `font->ref_count == 1' failed Breakpoint 1, go_font_free (font=0x8181e58) at go-font.c:41 41 g_return_if_fail (font->ref_count == 1); (gdb) p font->ref_count $8 = 2
I can even get those messages in a simpler way: Open the attached file Select the graph Open its properties window cancel quit
I see three occurrences of: ** (gnumeric:15859): CRITICAL **: go_font_free: assertion `font->ref_count == 1' failed also when using ./samples/excel12/chart-tests-excel.xlsx instead of the attached file.
The refcount error means we leaked something. It is likely a ref held by another object that is leaked in your configuration, but not in mine.
2 of the three GOFonts that have problems with my setup are created through a call to go_style_set_font_desc by gog-theme. The third one is apparently the main font (created initially and reffed and unreffed a very large number of times), it seems to like to end with 24 refs.
The two gog-theme related fonts have a very short gog-theme history: when they are created we have: ** (gnumeric:30520): WARNING **: created 0x9208fb8 = 1 (for the hash) ** (gnumeric:30520): WARNING **: ref added 0x9208fb8 = 2 (for the style used by the theme) ** (gnumeric:30520): CRITICAL **: go_font_free: assertion `font->ref_count == 1' failed where it still has the 2 refs. So clearly the style used by the theme is leaking.
so in the theme initialization there are 25 new styles created. for two of them special fonts are used the remaining 23 have the default font associated wit them when the style is initially created. This matches the extra references: 23 + 1 + 1 since at freeing time the fonts have 24 + 2 + 2 rather than the expected 1 + 1 + 1. I would say that this would be a very unlikely coincidence.
The leak requires a graph properties dialog to be opened so the question is what happens with themes at that time?
Well the themes are loaded into the model for the combobox. That references the themes. Are we sure that the model gets deleted when we are done?
If I try to break in gog_theme_finalize then in the described actions,I never break. If I skip the opening of the property dialog then we break when exiting.
When closing the graph guru, gtk_combo_box_dispose is called which should unref its model. Nevertheless, gtk_list_store_finalize is never called. as a consequence the themes are not unreffed and so hold onto the GOFonts. This should be a gtk+ problem unless we are holding onto a reference to the list store (directly or indirectly).
Created attachment 190146 [details] gnumeric file showing the differences in gobjects This gnumeric file shows the differences in column B are objects left alive with the properties dialog that are new or have changed references. Column E are teh reference counts without the properties dialog. Note that there are 3 GtkListStores, one of them will hold the references to the themes.
Created attachment 190148 [details] object logs
I see GOMarker leaks if I displays something that has a marker selector on it. I believe go_marker_palette_render_func leaks these.
GOMarker and GtkBuilder leaks fixed.
Created attachment 190175 [details] new object logs What I see after these fixes. The GOFont warnings are still there too.
We leak the styles in the theme because we leak the theme: - 0x9f9a200, GogTheme: refs=1 - 0x9f9a120, GogTheme: refs=1
And I would think we are leaking the GogThemes because we are leaking the GtkListStore containing those GogThemes (and holding a reference to them): one of: - 0xa64ad50, GtkListStore: refs=3 - 0xb5605e88, GtkListStore: refs=3 - 0xa51cf98, GtkListStore: refs=3 And they are probably leaked because the corresponding GtkComboBox is leaked: - 0xa52fb08, GtkComboBox: refs=3 name="GtkComboBox" - 0xa52fa20, GtkComboBox: refs=5 name="GtkComboBox" - 0xa52f938, GtkComboBox: refs=2 name="GtkComboBox"
although as mentioned earlier, gtk_combo_box_dispose is called which should unref its model. It isn't clear why there are 3 refs to the ListStore where it shouldn't really ever have more than 2.
- 0xa51cf98, GtkListStore: refs=3 ++ Created object 0xa62b990, GtkBuilder ++ Created object 0xa51ce98, GtkAdjustment ++ Created object 0xa51ced8, GtkAdjustment ++ Created object 0xa51cf18, GtkAdjustment ++ Created object 0xa51cf58, GtkAdjustment ++ Created object 0xa51cf98, GtkListStore <--- That one ++ Created object 0xa64ad50, GtkListStore ++ Created object 0xa61b968, GtkHBox ++ Created object 0xa61b9c0, GtkVBox ++ Created object 0xa595428, GtkLabel ++ Created object 0x9fc6cf0, GtkAlignment ++ Created object 0xa553d30, GtkTable ++ Created object 0xa5954a8, GtkLabel ++ Created object 0xa595528, GtkLabel ++ Created object 0xa5955a8, GtkLabel ++ Created object 0xa518030, PangoContext ++ Created object 0xa595628, PangoLayout That would appear to be created from a ui file with four adjustments and two GtkListStore. That is surely go-style-prefs.ui The leaking item looks like it's model1 which is attached to widget fill_type_menu.
- 0xa64ad50, GtkListStore: refs=3 That's the other one from the list above. A wild guess is that the leak is related to the size group and that it's unrelated to the theme leak.
- 0xb5605e88, GtkListStore: refs=3 Note, that the address doesn't look like the other addresses. Normally that would mean it's allocated from a different thread. ++ Created object 0xa4075b0, GtkArrow ++ Created object 0xa180f08, GtkWindow ++ Created object 0xa10c220, GtkMenu ++ Created object 0xa595328, GtkTreeViewColumn ++ Created object 0xa52f938, GtkComboBox ++ Created object 0xa152b98, GtkCellRendererText ++ Created object 0xa592570, GtkButton ++ Created object 0x9fc6dc0, GtkAlignment ++ Created object 0xa61b910, GtkHBox ++ Created object 0xa61c6f8, GtkImage ++ Created object 0xa5953a8, GtkLabel ++ Created object 0xb5605e88, GtkListStore <--- That one ++ Created object 0xa5fed60, GOMarker ++ Created object 0xa63fe90, GogStyle -- Finalized object 0xa5fed60, GOMarker ++ Created object 0xa5fed80, GOMarker This is likely the one we're interested in.
New and improved http://people.gnome.org/~mortenw/gobject-list.c should show column types for GtkTreeModel leaks. That should tell us which list store it is. After that, try GOBJECT_LIST_FILTER=GTK_LIST_STORE GOBJECT_LIST_DISPLAY=all and you just might be told of all refs and unrefs. If you compile with libunwind you might even get stack traces. In principle, that is -- I haven't actually tested any of this.
Created attachment 190229 [details] even newer object logs object logs with the new and improved gobject-list
After that, try GOBJECT_LIST_FILTER=GTK_LIST_STORE GOBJECT_LIST_DISPLAY=all and you just might be told of all refs and unrefs. Hmm, I translated that for me into the command: GOBJECT_LIST_FILTER=GTK_LIST_STORE GOBJECT_LIST_DISPLAY=all LD_PRELOAD=~/git/gobject-list/libgobject-list.so GNM_DEBUG=close-displays jhbuild run gnumeric which shortens the "Still Alive" section to exactly 0 entries. And the entries prior are all "-- Finalized object (...)"
Okay, if I change this to: GOBJECT_LIST_FILTER=GtkListStore GOBJECT_LIST_DISPLAY=all LD_PRELOAD=~/git/gobject-list/libgobject-list.so GNM_DEBUG=close-displays jhbuild run gnumeric then I get a long list of Finalized interspersed with: ++ Created object 0x88c7cc8, GtkListStore ++ Created object 0x88c7d08, GtkListStore + Reffed object 0x88c7d08, GtkListStore; ref_count: 1 -> 2 + Reffed object 0x88c7cc8, GtkListStore; ref_count: 1 -> 2 ++ Created object 0x89c1098, GtkListStore + Reffed object 0x89c1098, GtkListStore; ref_count: 1 -> 2 - Unreffed object 0x89c1098, GtkListStore; ref_count: 2 -> 1 ++ Created object 0x88c7f08, GtkListStore + Reffed object 0x88c7f08, GtkListStore; ref_count: 1 -> 2 - Unreffed object 0x88c7f08, GtkListStore; ref_count: 2 -> 1 ++ Created object 0x89c0e90, GtkListStore + Reffed object 0x89c0e90, GtkListStore; ref_count: 1 -> 2 - Unreffed object 0x89c0e90, GtkListStore; ref_count: 2 -> 1 ++ Created object 0x89faa58, GtkListStore + Reffed object 0x89faa58, GtkListStore; ref_count: 1 -> 2 - Unreffed object 0x89faa58, GtkListStore; ref_count: 2 -> 1 ++ Created object 0x89fa918, GtkListStore + Reffed object 0x89fa918, GtkListStore; ref_count: 1 -> 2 - Unreffed object 0x89fa918, GtkListStore; ref_count: 2 -> 1 + Reffed object 0x89c1098, GtkListStore; ref_count: 1 -> 2 + Reffed object 0x89c1098, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0x89c1098, GtkListStore; ref_count: 3 -> 2 + Reffed object 0x89c1098, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0x89c1098, GtkListStore; ref_count: 3 -> 2 + Reffed object 0x89c1098, GtkListStore; ref_count: 2 -> 3 + Reffed object 0x89fa918, GtkListStore; ref_count: 1 -> 2 + Reffed object 0x89fa918, GtkListStore; ref_count: 2 -> 3 + Reffed object 0x89c0e90, GtkListStore; ref_count: 1 -> 2 + Reffed object 0x89c0e90, GtkListStore; ref_count: 2 -> 3 + Reffed object 0x89faa58, GtkListStore; ref_count: 1 -> 2 + Reffed object 0x89faa58, GtkListStore; ref_count: 2 -> 3 + Reffed object 0x88c7f08, GtkListStore; ref_count: 1 -> 2 + Reffed object 0x88c7f08, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0x89c1098, GtkListStore; ref_count: 3 -> 2 + Reffed object 0x89c1098, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0x89c1098, GtkListStore; ref_count: 3 -> 2 + Reffed object 0x89c1098, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0x89fa918, GtkListStore; ref_count: 3 -> 2 + Reffed object 0x89fa918, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0x89fa918, GtkListStore; ref_count: 3 -> 2 + Reffed object 0x89fa918, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0x89c0e90, GtkListStore; ref_count: 3 -> 2 + Reffed object 0x89c0e90, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0x89c0e90, GtkListStore; ref_count: 3 -> 2 + Reffed object 0x89c0e90, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0x89faa58, GtkListStore; ref_count: 3 -> 2 + Reffed object 0x89faa58, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0x89faa58, GtkListStore; ref_count: 3 -> 2 + Reffed object 0x89faa58, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0x88c7f08, GtkListStore; ref_count: 3 -> 2 + Reffed object 0x88c7f08, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0x88c7f08, GtkListStore; ref_count: 3 -> 2 + Reffed object 0x88c7f08, GtkListStore; ref_count: 2 -> 3 ++ Created object 0x8e265c8, GtkListStore + Reffed object 0x8e265c8, GtkListStore; ref_count: 3 -> 4 + Reffed object 0x8e265c8, GtkListStore; ref_count: 4 -> 5 ++ Created object 0x8e26688, GtkListStore ++ Created object 0x8836418, GtkListStore + Reffed object 0x8e26688, GtkListStore; ref_count: 3 -> 4 + Reffed object 0x8e26688, GtkListStore; ref_count: 4 -> 5 + Reffed object 0x8e26688, GtkListStore; ref_count: 5 -> 6 + Reffed object 0x8e26688, GtkListStore; ref_count: 6 -> 7 + Reffed object 0x8e26688, GtkListStore; ref_count: 7 -> 8 + Reffed object 0x8e26688, GtkListStore; ref_count: 8 -> 9 + Reffed object 0x8e26688, GtkListStore; ref_count: 9 -> 10 + Reffed object 0x8e26688, GtkListStore; ref_count: 10 -> 11 + Reffed object 0x8e26688, GtkListStore; ref_count: 11 -> 12 + Reffed object 0x8e26688, GtkListStore; ref_count: 12 -> 13 + Reffed object 0x8e26688, GtkListStore; ref_count: 13 -> 14 + Reffed object 0x8e26688, GtkListStore; ref_count: 14 -> 15 + Reffed object 0x8e26688, GtkListStore; ref_count: 15 -> 16 + Reffed object 0x8e26688, GtkListStore; ref_count: 16 -> 17 + Reffed object 0x8e26688, GtkListStore; ref_count: 17 -> 18 + Reffed object 0x8e26688, GtkListStore; ref_count: 18 -> 19 + Reffed object 0x8e26688, GtkListStore; ref_count: 19 -> 20 + Reffed object 0x8836418, GtkListStore; ref_count: 3 -> 4 + Reffed object 0x8836418, GtkListStore; ref_count: 4 -> 5 + Reffed object 0x8836418, GtkListStore; ref_count: 5 -> 6 + Reffed object 0x8836418, GtkListStore; ref_count: 6 -> 7 + Reffed object 0x8836418, GtkListStore; ref_count: 7 -> 8 + Reffed object 0x8836418, GtkListStore; ref_count: 8 -> 9 + Reffed object 0x8836418, GtkListStore; ref_count: 9 -> 10 + Reffed object 0x8836418, GtkListStore; ref_count: 10 -> 11 + Reffed object 0x8836418, GtkListStore; ref_count: 11 -> 12 + Reffed object 0x8836418, GtkListStore; ref_count: 12 -> 13 + Reffed object 0x8836418, GtkListStore; ref_count: 13 -> 14 + Reffed object 0x8836418, GtkListStore; ref_count: 12 -> 13 + Reffed object 0x8836418, GtkListStore; ref_count: 13 -> 14 + Reffed object 0x8836418, GtkListStore; ref_count: 14 -> 15 + Reffed object 0x8836418, GtkListStore; ref_count: 15 -> 16 + Reffed object 0x8e26688, GtkListStore; ref_count: 18 -> 19 + Reffed object 0x8e26688, GtkListStore; ref_count: 19 -> 20 + Reffed object 0x8e26688, GtkListStore; ref_count: 20 -> 21 + Reffed object 0x8e26688, GtkListStore; ref_count: 21 -> 22 + Reffed object 0x8e265c8, GtkListStore; ref_count: 4 -> 5 + Reffed object 0x8e265c8, GtkListStore; ref_count: 5 -> 6 + Reffed object 0x8e265c8, GtkListStore; ref_count: 6 -> 7 + Reffed object 0x8e265c8, GtkListStore; ref_count: 7 -> 8 + Reffed object 0x8e265c8, GtkListStore; ref_count: 8 -> 9 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 9 -> 8 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 8 -> 7 + Reffed object 0x8e265c8, GtkListStore; ref_count: 7 -> 8 + Reffed object 0x8e265c8, GtkListStore; ref_count: 8 -> 9 + Reffed object 0x8e265c8, GtkListStore; ref_count: 9 -> 10 + Reffed object 0x8e265c8, GtkListStore; ref_count: 10 -> 11 + Reffed object 0x8e265c8, GtkListStore; ref_count: 11 -> 12 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 12 -> 11 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 11 -> 10 + Reffed object 0x8e265c8, GtkListStore; ref_count: 9 -> 10 + Reffed object 0x8e265c8, GtkListStore; ref_count: 10 -> 11 + Reffed object 0x8e265c8, GtkListStore; ref_count: 11 -> 12 + Reffed object 0x8e265c8, GtkListStore; ref_count: 12 -> 13 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 13 -> 12 + Reffed object 0x8e26688, GtkListStore; ref_count: 22 -> 23 + Reffed object 0x8e26688, GtkListStore; ref_count: 23 -> 24 - Unreffed object 0x8e26688, GtkListStore; ref_count: 24 -> 23 - Unreffed object 0x8e26688, GtkListStore; ref_count: 23 -> 22 + Reffed object 0x8e26688, GtkListStore; ref_count: 22 -> 23 + Reffed object 0x8e26688, GtkListStore; ref_count: 23 -> 24 - Unreffed object 0x8e26688, GtkListStore; ref_count: 24 -> 23 - Unreffed object 0x8e26688, GtkListStore; ref_count: 23 -> 22 + Reffed object 0x8e26688, GtkListStore; ref_count: 22 -> 23 + Reffed object 0x8e26688, GtkListStore; ref_count: 23 -> 24 - Unreffed object 0x8e26688, GtkListStore; ref_count: 24 -> 23 - Unreffed object 0x8e26688, GtkListStore; ref_count: 23 -> 22 + Reffed object 0x8e26688, GtkListStore; ref_count: 22 -> 23 + Reffed object 0x8e26688, GtkListStore; ref_count: 23 -> 24 - Unreffed object 0x8e26688, GtkListStore; ref_count: 24 -> 23 - Unreffed object 0x8e26688, GtkListStore; ref_count: 23 -> 22 + Reffed object 0x8e26688, GtkListStore; ref_count: 22 -> 23 + Reffed object 0x8e26688, GtkListStore; ref_count: 23 -> 24 - Unreffed object 0x8e26688, GtkListStore; ref_count: 24 -> 23 - Unreffed object 0x8e26688, GtkListStore; ref_count: 23 -> 22 + Reffed object 0x8836418, GtkListStore; ref_count: 16 -> 17 + Reffed object 0x8836418, GtkListStore; ref_count: 17 -> 18 - Unreffed object 0x8836418, GtkListStore; ref_count: 18 -> 17 - Unreffed object 0x8836418, GtkListStore; ref_count: 17 -> 16 + Reffed object 0x8836418, GtkListStore; ref_count: 16 -> 17 + Reffed object 0x8836418, GtkListStore; ref_count: 17 -> 18 - Unreffed object 0x8836418, GtkListStore; ref_count: 18 -> 17 - Unreffed object 0x8836418, GtkListStore; ref_count: 17 -> 16 + Reffed object 0x8836418, GtkListStore; ref_count: 16 -> 17 + Reffed object 0x8836418, GtkListStore; ref_count: 17 -> 18 - Unreffed object 0x8836418, GtkListStore; ref_count: 18 -> 17 - Unreffed object 0x8836418, GtkListStore; ref_count: 17 -> 16 + Reffed object 0x8e265c8, GtkListStore; ref_count: 12 -> 13 + Reffed object 0x8e265c8, GtkListStore; ref_count: 13 -> 14 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 14 -> 13 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 13 -> 12 + Reffed object 0x8e265c8, GtkListStore; ref_count: 12 -> 13 + Reffed object 0x8e265c8, GtkListStore; ref_count: 13 -> 14 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 14 -> 13 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 13 -> 12 + Reffed object 0x8e26688, GtkListStore; ref_count: 22 -> 23 + Reffed object 0x8e26688, GtkListStore; ref_count: 23 -> 24 - Unreffed object 0x8e26688, GtkListStore; ref_count: 24 -> 23 - Unreffed object 0x8e26688, GtkListStore; ref_count: 23 -> 22 + Reffed object 0x8e26688, GtkListStore; ref_count: 22 -> 23 + Reffed object 0x8e26688, GtkListStore; ref_count: 23 -> 24 - Unreffed object 0x8e26688, GtkListStore; ref_count: 24 -> 23 - Unreffed object 0x8e26688, GtkListStore; ref_count: 23 -> 22 + Reffed object 0x8e26688, GtkListStore; ref_count: 22 -> 23 + Reffed object 0x8e26688, GtkListStore; ref_count: 23 -> 24 - Unreffed object 0x8e26688, GtkListStore; ref_count: 24 -> 23 - Unreffed object 0x8e26688, GtkListStore; ref_count: 23 -> 22 + Reffed object 0x8e26688, GtkListStore; ref_count: 22 -> 23 + Reffed object 0x8e26688, GtkListStore; ref_count: 23 -> 24 - Unreffed object 0x8e26688, GtkListStore; ref_count: 24 -> 23 - Unreffed object 0x8e26688, GtkListStore; ref_count: 23 -> 22 + Reffed object 0x8e26688, GtkListStore; ref_count: 22 -> 23 + Reffed object 0x8e26688, GtkListStore; ref_count: 23 -> 24 - Unreffed object 0x8e26688, GtkListStore; ref_count: 24 -> 23 - Unreffed object 0x8e26688, GtkListStore; ref_count: 23 -> 22 + Reffed object 0x8836418, GtkListStore; ref_count: 16 -> 17 + Reffed object 0x8836418, GtkListStore; ref_count: 17 -> 18 - Unreffed object 0x8836418, GtkListStore; ref_count: 18 -> 17 - Unreffed object 0x8836418, GtkListStore; ref_count: 17 -> 16 + Reffed object 0x8836418, GtkListStore; ref_count: 16 -> 17 + Reffed object 0x8836418, GtkListStore; ref_count: 17 -> 18 - Unreffed object 0x8836418, GtkListStore; ref_count: 18 -> 17 - Unreffed object 0x8836418, GtkListStore; ref_count: 17 -> 16 + Reffed object 0x8836418, GtkListStore; ref_count: 16 -> 17 + Reffed object 0x8836418, GtkListStore; ref_count: 17 -> 18 - Unreffed object 0x8836418, GtkListStore; ref_count: 18 -> 17 - Unreffed object 0x8836418, GtkListStore; ref_count: 17 -> 16 + Reffed object 0x8e265c8, GtkListStore; ref_count: 12 -> 13 + Reffed object 0x8e265c8, GtkListStore; ref_count: 13 -> 14 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 14 -> 13 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 13 -> 12 + Reffed object 0x8e265c8, GtkListStore; ref_count: 12 -> 13 + Reffed object 0x8e265c8, GtkListStore; ref_count: 13 -> 14 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 14 -> 13 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 13 -> 12 - Unreffed object 0x8836418, GtkListStore; ref_count: 16 -> 15 - Unreffed object 0x8e26688, GtkListStore; ref_count: 22 -> 21 - Unreffed object 0x8e26688, GtkListStore; ref_count: 21 -> 20 - Unreffed object 0x8e26688, GtkListStore; ref_count: 20 -> 19 - Unreffed object 0x8e26688, GtkListStore; ref_count: 19 -> 18 - Unreffed object 0x8e26688, GtkListStore; ref_count: 18 -> 17 - Unreffed object 0x8e26688, GtkListStore; ref_count: 17 -> 16 - Unreffed object 0x8e26688, GtkListStore; ref_count: 16 -> 15 - Unreffed object 0x8e26688, GtkListStore; ref_count: 15 -> 14 - Unreffed object 0x8e26688, GtkListStore; ref_count: 14 -> 13 - Unreffed object 0x8e26688, GtkListStore; ref_count: 13 -> 12 - Unreffed object 0x8e26688, GtkListStore; ref_count: 12 -> 11 - Unreffed object 0x8e26688, GtkListStore; ref_count: 11 -> 10 - Unreffed object 0x8e26688, GtkListStore; ref_count: 10 -> 9 - Unreffed object 0x8e26688, GtkListStore; ref_count: 9 -> 8 - Unreffed object 0x8e26688, GtkListStore; ref_count: 8 -> 7 - Unreffed object 0x8e26688, GtkListStore; ref_count: 7 -> 6 - Unreffed object 0x8e26688, GtkListStore; ref_count: 6 -> 5 - Unreffed object 0x8e26688, GtkListStore; ref_count: 5 -> 4 - Unreffed object 0x8e26688, GtkListStore; ref_count: 4 -> 3 - Unreffed object 0x8836418, GtkListStore; ref_count: 15 -> 14 - Unreffed object 0x8836418, GtkListStore; ref_count: 14 -> 13 - Unreffed object 0x8836418, GtkListStore; ref_count: 13 -> 12 - Unreffed object 0x8836418, GtkListStore; ref_count: 12 -> 11 - Unreffed object 0x8836418, GtkListStore; ref_count: 11 -> 10 - Unreffed object 0x8836418, GtkListStore; ref_count: 10 -> 9 - Unreffed object 0x8836418, GtkListStore; ref_count: 9 -> 8 - Unreffed object 0x8836418, GtkListStore; ref_count: 8 -> 7 - Unreffed object 0x8836418, GtkListStore; ref_count: 7 -> 6 - Unreffed object 0x8836418, GtkListStore; ref_count: 6 -> 5 - Unreffed object 0x8836418, GtkListStore; ref_count: 5 -> 4 - Unreffed object 0x8836418, GtkListStore; ref_count: 4 -> 3 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 12 -> 11 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 11 -> 10 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 10 -> 9 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 9 -> 8 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 8 -> 7 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 7 -> 6 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 6 -> 5 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 5 -> 4 - Unreffed object 0x8e265c8, GtkListStore; ref_count: 4 -> 3 - Unreffed object 0x88c7d08, GtkListStore; ref_count: 2 -> 1 - Unreffed object 0x88c7d08, GtkListStore; ref_count: 1 -> 0 -- Finalized object 0x88c7d08, GtkListStore - Unreffed object 0x88c7cc8, GtkListStore; ref_count: 2 -> 1 - Unreffed object 0x88c7cc8, GtkListStore; ref_count: 1 -> 0 -- Finalized object 0x88c7cc8, GtkListStore - Unreffed object 0x89c1098, GtkListStore; ref_count: 3 -> 2 - Unreffed object 0x89c1098, GtkListStore; ref_count: 2 -> 1 - Unreffed object 0x89c1098, GtkListStore; ref_count: 1 -> 0 -- Finalized object 0x89c1098, GtkListStore - Unreffed object 0x88c7f08, GtkListStore; ref_count: 3 -> 2 - Unreffed object 0x88c7f08, GtkListStore; ref_count: 2 -> 1 - Unreffed object 0x88c7f08, GtkListStore; ref_count: 1 -> 0 -- Finalized object 0x88c7f08, GtkListStore - Unreffed object 0x89c0e90, GtkListStore; ref_count: 3 -> 2 - Unreffed object 0x89c0e90, GtkListStore; ref_count: 2 -> 1 - Unreffed object 0x89c0e90, GtkListStore; ref_count: 1 -> 0 -- Finalized object 0x89c0e90, GtkListStore - Unreffed object 0x89faa58, GtkListStore; ref_count: 3 -> 2 - Unreffed object 0x89faa58, GtkListStore; ref_count: 2 -> 1 - Unreffed object 0x89faa58, GtkListStore; ref_count: 1 -> 0 -- Finalized object 0x89faa58, GtkListStore - Unreffed object 0x89fa918, GtkListStore; ref_count: 3 -> 2 - Unreffed object 0x89fa918, GtkListStore; ref_count: 2 -> 1 - Unreffed object 0x89fa918, GtkListStore; ref_count: 1 -> 0 -- Finalized object 0x89fa918, GtkListStore Still Alive: - 0x8e26688, GtkListStore: refs=3 cols=[gchararray] - 0x8836418, GtkListStore: refs=3 cols=[gchararray] - 0x8e265c8, GtkListStore: refs=3 cols=[gchararray,GObject] Considering that I am only opening a file, selecting the graph, open the properties dialog , cancel, close window, I am not sure what this liststore tango is about.
Hmm, just opening Gnuemric, bringing up then file open dialog, cancelling and then closing Gnumeric yields: Still Alive: - 0x9519708, GtkListStore: refs=3 cols=[gchararray] - 0x93f3610, GtkListStore: refs=3 cols=[gchararray]
With static void hook_g_object_finalize (GObject *obj) { char *typ = g_strdup (G_OBJECT_TYPE_NAME (obj)); G_LOCK (objects_lock); g_hash_table_remove (objects, obj); G_UNLOCK (objects_lock); real_g_object_finalize (obj); if (object_filter (typ)) { g_printerr (" -- Finalized object %p, %s\n", obj, typ); print_trace (); } g_free (typ); } one gets rid of the finalize stuff.
Created attachment 190230 [details] liststore logs with and without... Hiding all toolbars seems to reduce clutter too.
This just doesn't look right: ++ Created object 0x9fabcd0, GtkListStore + Reffed object 0x9fabcd0, GtkListStore; ref_count: 3 -> 4 + Reffed object 0x9fabcd0, GtkListStore; ref_count: 4 -> 5 How does the GtkListStore ref get to 3? Note that the same happens also for the other two GtkListStores that leak!
> How does the GtkListStore ref get to 3? We only catch calls to ref and unref that the linker can see. It is possible that some calls within libgobject are not intercepted.
I just find is suspicious that of all the GtkListStores created the 3 that appear to start off with 3 visible refs are the once that are leaked.
We might need to hook into g_object_ref_sink.
New and improved http://people.gnome.org/~mortenw/gobject-list.c also hooks into g_object_ref_sink and, more importantly, the GValue operations that involve GObjects.
Created attachment 190281 [details] liststore logs with and without These are the logs with respect to GtkListStore again with or without. We now don't have an initial skip to 3 at the beginning. Nevertheless, considering that when I open the property dialog, the theme page is hidden, I find it very surprising that the GtkListStore in question shows so much ref/unref activity.
The gui uses list-stores too, so you get a lot of noise. However, if you grep for 0x960e2a0 you get only 60 hits. Any luck with libunwind?
For a list store that is just created, stuffed with 2 items and then never used 60 hits seem to be excessive for me. How do I link with libunwind?
Created attachment 190304 [details] liststore "with" log using libunwind
If in gog_graph_populate_editor I comment out: ---------------------------------------------------------------------------- for (ptr = theme_names; ptr != NULL; ptr = ptr->next) { theme = gog_theme_registry_lookup (ptr->data); gtk_list_store_append (model, &iter); /* gtk_list_store_set (model, &iter, */ /* 0, gog_theme_get_local_name (theme), */ /* 1, theme, */ /* -1); */ /* if (strcmp (ptr->data, graph_theme_name) == 0) */ /* index = count; */ count++; } /* gtk_combo_box_set_active (GTK_COMBO_BOX (combo), index); */ g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (cb_theme_changed), graph); ---------------------------------------------------------------------------- the gtkliststore still leaks. If I also comment out the gtk_list_store_append the leak disappears. So the leak appears to be directly or indirectly caused by the gtk_list_store_append
We probably should be using gtk_list_store_insert_with_values instead of gtk_list_store_append followed by gtk_list_store_set since this will save a bunch of signals. It doesn't seem to affect the leak though!
What is the precise gtk+ version here? This has all the marks of a gtk+ issue.
2.24.4-0ubuntu2
I have 2.22.1. The diffs from that to yours is mostly docs and renames. I went through the whole thing and nothing stands out. On a crazy hunch, please try building the model while not connected anything. The upcoming patch should do. With this, I see... ... Howdy 0xc393a0: 3 + Reffed object 0xc393a0, GtkListStore; ref_count: 3 -> 4 - Unreffed object 0xc393a0, GtkListStore; ref_count: 4 -> 3 - Unreffed object 0xc393a0, GtkListStore; ref_count: 3 -> 2 A 0xc393a0: 0 2 B 0xc393a0: 0 2 + Reffed object 0xc393a0, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0xc393a0, GtkListStore; ref_count: 3 -> 2 C 0xc393a0: 0 2 + Reffed object 0xc393a0, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0xc393a0, GtkListStore; ref_count: 3 -> 2 D 0xc393a0: 0 2 A 0xc393a0: 1 2 B 0xc393a0: 1 2 + Reffed object 0xc393a0, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0xc393a0, GtkListStore; ref_count: 3 -> 2 C 0xc393a0: 1 2 + Reffed object 0xc393a0, GtkListStore; ref_count: 2 -> 3 - Unreffed object 0xc393a0, GtkListStore; ref_count: 3 -> 2 D 0xc393a0: 1 2 Howdy 0xc393a0: 2 + Reffed object 0xc393a0, GtkListStore; ref_count: 2 -> 3 + Reffed object 0xc393a0, GtkListStore; ref_count: 3 -> 4 + Reffed object 0xc393a0, GtkListStore; ref_count: 4 -> 5 + Reffed object 0xc393a0, GtkListStore; ref_count: 5 -> 6 + Reffed object 0xc393a0, GtkListStore; ref_count: 6 -> 7 + Reffed object 0xc393a0, GtkListStore; ref_count: 7 -> 8 + Reffed object 0xc393a0, GtkListStore; ref_count: 8 -> 9 + Reffed object 0xc393a0, GtkListStore; ref_count: 9 -> 10 + Reffed object 0xc393a0, GtkListStore; ref_count: 10 -> 11 + Reffed object 0xc393a0, GtkListStore; ref_count: 11 -> 12 + Reffed object 0xc393a0, GtkListStore; ref_count: 12 -> 13 + Reffed object 0xc393a0, GtkListStore; ref_count: 13 -> 14 - Unreffed object 0xc393a0, GtkListStore; ref_count: 14 -> 13 - Unreffed object 0xc393a0, GtkListStore; ref_count: 13 -> 12 ...
Created attachment 190363 [details] [review] Isolate model while constructing it Crazy patch.
Created attachment 190364 [details] liststore "with" log using libunwind with crazy patch with the crazy patch
May be ubuntu patched gtk+?
@jean, ubuntu uses the following list of patches: -rw-r--r-- 1 aguelzow aguelzow 1931 2011-04-13 16:36 001_static-linking-dont-query-immodules.patch -rw-r--r-- 1 aguelzow aguelzow 738 2011-04-13 16:36 002_static-linking-dont-build-perf.patch -rw-r--r-- 1 aguelzow aguelzow 2143 2011-04-13 16:36 003_gdk.pc_privates.patch -rw-r--r-- 1 aguelzow aguelzow 72279 2011-04-13 16:36 004_gtk+-ximian-gtk2-filesel-navbutton-5.patch -rw-r--r-- 1 aguelzow aguelzow 2563 2011-04-13 16:36 005_support_disabling_x11_extensions.patch -rw-r--r-- 1 aguelzow aguelzow 6562 2011-04-13 16:36 009_gtk-export-filechooser.patch -rw-r--r-- 1 aguelzow aguelzow 541 2011-04-13 16:36 011_immodule-cache-dir.patch -rw-r--r-- 1 aguelzow aguelzow 1519 2011-04-13 16:36 012_ubuntu-set-grab-add.patch -rw-r--r-- 1 aguelzow aguelzow 644 2011-04-13 16:36 015_default-fallback-icon-theme.patch -rw-r--r-- 1 aguelzow aguelzow 664 2011-04-13 16:36 022_disable-viqr-im-for-vi-locale.patch -rw-r--r-- 1 aguelzow aguelzow 2802 2011-04-13 16:36 041_ia32-libs.patch -rw-r--r-- 1 aguelzow aguelzow 666 2011-04-13 16:36 042_treeview_single-focus.patch -rw-r--r-- 1 aguelzow aguelzow 41902 2011-04-13 16:36 043_ubuntu_menu_proxy.patch -rw-r--r-- 1 aguelzow aguelzow 51132 2011-04-13 16:36 044_grips.patch -rw-r--r-- 1 aguelzow aguelzow 469 2011-04-13 16:36 060_ignore-random-icons.patch -rw-r--r-- 1 aguelzow aguelzow 3086 2011-04-13 16:36 062_dnd_menubar.patch -rw-r--r-- 1 aguelzow aguelzow 3505 2011-04-13 16:36 063_treeview_almost_fixed.patch -rw-r--r-- 1 aguelzow aguelzow 1061 2011-04-13 16:36 064_gir_build_workaround.patch -rw-r--r-- 1 aguelzow aguelzow 2861 2011-04-13 16:36 065_gir_set_packages.patch -rw-r--r-- 1 aguelzow aguelzow 842 2011-04-13 16:36 071_no_offscreen_widgets_grabbing.patch -rw-r--r-- 1 aguelzow aguelzow 3351 2011-04-13 16:36 072_indicator_menu_update.patch -rw-r--r-- 1 aguelzow aguelzow 10628 2011-04-13 16:36 091_bugzilla_tooltip_refresh.patch -rw-r--r-- 1 aguelzow aguelzow 1146 2011-04-13 16:36 092_default_to_xdg_document_dir.patch -rw-r--r-- 1 aguelzow aguelzow 3792 2011-04-13 16:36 093_gtk3_gtkimage_fallbacks_use.patch -rw-r--r-- 1 aguelzow aguelzow 5408 2011-04-13 16:36 094_git_fileselector_error.patch -rw-r--r-- 1 aguelzow aguelzow 2545 2011-04-13 16:36 095_git_menus_scrolling.patch -rw-r--r-- 1 aguelzow aguelzow 2549 2011-04-13 16:36 096_git_gtkprintsettings.patch -rw-r--r-- 1 aguelzow aguelzow 927 2011-04-13 16:36 097_statusicon_image_fallback.patch -rw-r--r-- 1 aguelzow aguelzow 9229 2011-04-13 16:36 100_overlay_scrollbar_loading.patch How does this list compare with debian?
Debian has: 001_static-linking-dont-query-immodules.patch 002_static-linking-dont-build-perf.patch 003_gdk.pc_privates.patch 004_gtk+-ximian-gtk2-filesel-navbutton-5.patch 005_support_disabling_x11_extensions.patch 009_gtk-export-filechooser.patch 011_immodule-cache-dir.patch 015_default-fallback-icon-theme.patch 022_disable-viqr-im-for-vi-locale.patch 041_ia32-libs.patch 042_treeview_single-focus.patch 060_ignore-random-icons.patch 061_use_pdf_as_default_printing_standard.patch 064_gir_build_workaround.patch 070_mandatory-relibtoolize.patch
As an experiment, I took the log from comment 49 and did: zgrep 0xa016a80 ~/Download/logfile.gz >~/aaa together with my similar log: grep 0xc393a0 ~/eee2 | sed -e 's/0xc393a0/0xa016a80/' >~/bbb (mapping my address for that GtkListStore into the Andreas' address.) The interesting part is that the diffs are small: $ diff -u ~/aaa ~/bbb --- /home/welinder/aaa 2011-06-21 12:47:53.644223000 -0400 +++ /home/welinder/bbb 2011-06-21 12:48:36.423398000 -0400 @@ -65,4 +65,7 @@ - Unreffed object 0xa016a80, GtkListStore; ref_count: 6 -> 5 - Unreffed object 0xa016a80, GtkListStore; ref_count: 5 -> 4 - Unreffed object 0xa016a80, GtkListStore; ref_count: 4 -> 3 - - 0xa016a80, GtkListStore: refs=3 cols=[gchararray,GObject] + - Unreffed object 0xa016a80, GtkListStore; ref_count: 3 -> 2 + - Unreffed object 0xa016a80, GtkListStore; ref_count: 2 -> 1 + - Unreffed object 0xa016a80, GtkListStore; ref_count: 1 -> 0 + -- Finalized object 0xa016a80, GtkListStore So the ref and unref sequences follow each other nicely. I am going to try to create a little more textual context than this so I can see which triple-unref is missing.
Interesting: gunzip < ~/Download/logfile.gz | perl -ne 'if (/^#(\d+)/) { next if $1>1; s/ \+ \[.*\]//; }if (/0xa016a80/) { print "\n\n\n$_"; $p=1; next;} $p=0 if (/^ /); print if $p;' >~/lll cat ~/eee2 | perl -ne 'if (/^#(\d+)/) { next if $1>1; s/ \+ \[.*\]//; } s/0xc39d30/0xa016a80/; if (/0xa016a80/) { print "\n\n\n$_"; $p=1; next;} $p=0 if (/^ /) ; print if $p;' >~/mmm diff -u ~/lll ~/mmm --- /home/welinder/lll 2011-06-21 13:37:46.970340000 -0400 +++ /home/welinder/mmm 2011-06-21 13:38:02.951343000 -0400 @@ -27,7 +27,7 @@ + Reffed object 0xa016a80, GtkListStore; ref_count: 4 -> 5 #0 g_object_ref -#1 gtk_cell_view_set_model +#1 gtk_combo_box_set_model @@ -157,7 +157,7 @@ + Reffed object 0xa016a80, GtkListStore; ref_count: 3 -> 4 #0 g_object_ref -#1 gtk_cell_view_set_model +#1 gtk_color_selection_dialog_get_color_selection @@ -175,7 +175,7 @@ + Reffed object 0xa016a80, GtkListStore; ref_count: 6 -> 7 #0 g_object_ref -#1 gtk_cell_view_set_model +#1 gtk_color_selection_dialog_get_color_selection @@ -193,7 +193,7 @@ + Reffed object 0xa016a80, GtkListStore; ref_count: 9 -> 10 #0 g_object_ref -#1 gtk_cell_view_set_model +#1 gtk_combo_box_set_model @@ -383,4 +383,24 @@ - - 0xa016a80, GtkListStore: refs=3 cols=[gchararray,GObject] + - Unreffed object 0xa016a80, GtkListStore; ref_count: 3 -> 2 +#0 g_object_unref +#1 gtk_color_selection_dialog_get_color_selection + + + + - Unreffed object 0xa016a80, GtkListStore; ref_count: 2 -> 1 +#0 g_object_unref +#1 gtk_tree_row_reference_free + + + + - Unreffed object 0xa016a80, GtkListStore; ref_count: 1 -> 0 +#0 g_object_unref +#1 gtk_tree_row_reference_free + + + + -- Finalized object 0xa016a80, GtkListStore +#0 hook_g_object_finalize +#1 g_object_unref The first few differences in who-called-ref/unref are probably just due to static functions and lack of debug information around. The three extra unrefs are the ones that make sure I do not have a leak. Here are the stack traces for these: - Unreffed object 0xc39d30, GtkListStore; ref_count: 3 -> 2 #0 g_object_unref + [0x0000008b] #1 gtk_color_selection_dialog_get_color_selection + [0x000025a6] #2 gtk_color_selection_dialog_get_color_selection + [0x00003fda] #3 g_object_unref + [0x00000174] - Unreffed object 0xc39d30, GtkListStore; ref_count: 2 -> 1 #0 g_object_unref + [0x0000008b] #1 gtk_tree_row_reference_free + [0x0000005e] #2 gtk_color_selection_dialog_get_color_selection + [0x000025bb] #3 gtk_color_selection_dialog_get_color_selection + [0x00003fda] #4 g_object_unref + [0x00000174] - Unreffed object 0xc39d30, GtkListStore; ref_count: 1 -> 0 #0 g_object_unref + [0x0000008b] #1 gtk_tree_row_reference_free + [0x00000067] #2 gtk_color_selection_dialog_get_color_selection + [0x000025bb] #3 gtk_color_selection_dialog_get_color_selection + [0x00003fda] #4 g_object_unref + [0x00000174] Note: I only trust the items with a low offset in brackets, so the latter two come from gtk_tree_row_reference_free. Other than that I don't trust it.
Updated stack traces:
+ Trace 227549
Hmm... bugzilla butchered that one. https://bugzilla.gnome.org/page.cgi?id=trace.html&trace_id=227549 From your log it appears that the GtkComboBox is being leaked. Hence it's not that strange that it doens't free its refs. Agree?
Created attachment 190388 [details] [review] Potential workaround
You are right. The GtkComboBox leaks and so of course its model. Your potential workaround appears to work fine (of course the GtkComboBox still leaks afterwards). I think we should apply your workaround and probably also to the other two GtkComboBoxes whose models leak in this situation (and any other GtkComboBox that we are using).
Workaround committed. I don't see a reason to add workarounds for the other combos unless they cause visible trouble. Newer gtk+ unsets the model itself in the dispose handler.
I guess then this can be considered fixed?
I'd love to know why we leak the combo box. Could you create a log with filter GtkComboBox, please?
Created attachment 190449 [details] gtkcombobox trace
Created attachment 190456 [details] ubuntu gtk patches
Nothing stand out. For now assume Ubuntu takes care of their bugs eventually. (And pigs fly.)