Random segfaults in GSlist via PyGObject
I've been banging my head against this for months with very little progress. Here's a fairly typical stack trace with some additional data:
Process 3294 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x11e06364000)
frame #0: 0x0000000109aabb77 libgtk-3.0.dylib`_gtk_style_animation_is_static(animation=0x0000011e06364000) at gtkstyleanimation.c:120:3 [opt]
117 {
118 GtkStyleAnimationClass *klass;
119
-> 120 g_return_val_if_fail (GTK_IS_STYLE_ANIMATION (animation), TRUE);
121
122 klass = GTK_STYLE_ANIMATION_GET_CLASS (animation);
123
Target 0: (python3) stopped.
(lldb) bt 12
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x11e06364000)
* frame #0: 0x0000000109aabb77 libgtk-3.0.dylib`_gtk_style_animation_is_static(animation=0x0000011e06364000) at gtkstyleanimation.c:120:3 [opt]
frame #1: 0x00000001098ee4d1 libgtk-3.0.dylib`gtk_css_animated_style_is_static(style=<unavailable>) at gtkcssanimatedstyle.c:74:12 [opt]
frame #2: 0x00000001099075f8 libgtk-3.0.dylib`gtk_css_node_invalidate_timestamp(cssnode=0x000000011bf34330) at gtkcssnode.c:1333:8 [opt]
frame #3: 0x0000000109907638 libgtk-3.0.dylib`gtk_css_node_invalidate_timestamp(cssnode=<unavailable>) at gtkcssnode.c:1338:7 [opt]
frame #4: 0x0000000109907638 libgtk-3.0.dylib`gtk_css_node_invalidate_timestamp(cssnode=<unavailable>) at gtkcssnode.c:1338:7 [opt]
frame #5: 0x0000000109907638 libgtk-3.0.dylib`gtk_css_node_invalidate_timestamp(cssnode=<unavailable>) at gtkcssnode.c:1338:7 [opt]
frame #6: 0x0000000109907638 libgtk-3.0.dylib`gtk_css_node_invalidate_timestamp(cssnode=<unavailable>) at gtkcssnode.c:1338:7 [opt]
frame #7: 0x0000000109907638 libgtk-3.0.dylib`gtk_css_node_invalidate_timestamp(cssnode=<unavailable>) at gtkcssnode.c:1338:7 [opt]
frame #8: 0x0000000109907638 libgtk-3.0.dylib`gtk_css_node_invalidate_timestamp(cssnode=<unavailable>) at gtkcssnode.c:1338:7 [opt]
frame #9: 0x0000000109907638 libgtk-3.0.dylib`gtk_css_node_invalidate_timestamp(cssnode=<unavailable>) at gtkcssnode.c:1338:7 [opt]
frame #10: 0x00000001099075a9 libgtk-3.0.dylib`gtk_css_node_invalidate_frame_clock(cssnode=0x000000011d9871a0, just_timestamp=1) at gtkcssnode.c:1350:3 [opt]
frame #11: 0x0000000109925eb6 libgtk-3.0.dylib`gtk_css_widget_node_queue_callback(widget=0x0000000102def150, frame_clock=<unavailable>, user_data=<unavailable>) at gtkcsswidgetnode.c:64:3 [opt]
(lldb) f 2
frame #2: 0x00000001099075f8 libgtk-3.0.dylib`gtk_css_node_invalidate_timestamp(cssnode=0x000000011bf34330) at gtkcssnode.c:1333:8 [opt]
1330 if (!cssnode->invalid)
1331 return;
1332
-> 1333 if (!gtk_css_style_is_static (cssnode->style))
1334 gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_TIMESTAMP);
1335
1336 for (child = cssnode->first_child; child; child = child->next_sibling)
(lldb) up
error: unable to find CIE at 0x00000018 for cie_id = 0x00000004 for entry at 0x00000018.
error: unable to find CIE at 0x00000050 for cie_id = 0x00000004 for entry at 0x00000050.
frame #3: 0x0000000109907638 libgtk-3.0.dylib`gtk_css_node_invalidate_timestamp(cssnode=<unavailable>) at gtkcssnode.c:1338:7 [opt]
1335
1336 for (child = cssnode->first_child; child; child = child->next_sibling)
1337 {
-> 1338 gtk_css_node_invalidate_timestamp (child);
1339 }
1340 }
1341
(lldb) p child
(GtkCssNode *) $0 = 0x000000011bf19ac0
(lldb) p *child
(GtkCssNode) $1 = {
object = {
g_type_instance = {
g_class = 0x00000001007db020
}
ref_count = 4
qdata = 0x0000000000000000
}
parent = 0x000000011baea4a0
previous_sibling = 0x000000011bf34330
next_sibling = 0x000000011bf19e40
first_child = 0x000000011baea020
last_child = 0x000000011baea020
decl = 0x0000000112df5450
style = 0x000000011bc7d240
cache = 0x0000000000000000
pending_changes = 10745839744
visible = 1
invalid = 1
needs_propagation = 1
style_is_invalid = 1
}
(lldb) dow
frame #2: 0x00000001099075f8 libgtk-3.0.dylib`gtk_css_node_invalidate_timestamp(cssnode=0x000000011bf34330) at gtkcssnode.c:1333:8 [opt]
1330 if (!cssnode->invalid)
1331 return;
1332
-> 1333 if (!gtk_css_style_is_static (cssnode->style))
1334 gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_TIMESTAMP);
1335
1336 for (child = cssnode->first_child; child; child = child->next_sibling)
(lldb) p *cssnode
(GtkCssNode) $2 = {
object = {
g_type_instance = {
g_class = 0x00000001007db020
}
ref_count = 4
qdata = 0x0000000000000000
}
parent = 0x000000011baea4a0
previous_sibling = 0x0000000000000000
next_sibling = 0x000000011bf19ac0
first_child = 0x000000011bf198c0
last_child = 0x000000011bf198c0
decl = 0x000000011b6d0960
style = 0x000000011daa7b40
cache = 0x0000000000000000
pending_changes = 10745806976
visible = 1
invalid = 1
needs_propagation = 1
style_is_invalid = 1
}
(lldb) dow
frame #1: 0x00000001098ee4d1 libgtk-3.0.dylib`gtk_css_animated_style_is_static(style=<unavailable>) at gtkcssanimatedstyle.c:74:12 [opt]
71
72 for (list = animated->animations; list; list = list->next)
73 {
-> 74 if (!_gtk_style_animation_is_static (list->data))
75 return FALSE;
76 }
77
(lldb) p list
(GSList *) $3 = 0x0000000118bd953f
(lldb) p *list
(GSList) $4 = {
data = 0x0000011e06364000
next = 0x00000118c5f28000
}
In this case the run is with GSLICE=debug_blocks
, which unfortunately doesn't provide any additional information. I've also done runs with MALLOC_SCRIBBLE=1
(a MacOS feature that writes 0xaaaaaaaa
to freed memory) and GSLICE=always-malloc
and in that case the memory location has been scribbled, indicating a double-free. MacOS's malloc also provides a nice memory-location history feature and I've examined a couple of dozen history logs for the segfaulted locations and not been able to identify the prior free.
A pure-C program (GnuCash) hasn't exhibited any instability at all using recent releases of Gtk or GLib, leading me to think that this has something to do with Python's garbage collector. The problem with that line of reasoning is that these gslists
are all private, buried fairly deeply in the Gtk implementation and shouldn't be exposed to introspection at all.
Anyone have an idea of where to look next?