and crashes the entire application. What causes it is toggling many ToggleButtons on and off, i.e. 10-12 buttons within the span of a second, and doing that repeatedly, and eventually slowing down. Unlike the previous time this one is not strictly deterministic - but eventually enough button toggling (and thus css class adding and removing) in rapid succession will crash the application.
I will see if I can prepare a minimal reproducible example tomorrow.
Alright I have been unable to make a minimally reproducible example (short of sending my exact project over), but the error persists - eventually, after a rapid amount of button changes (with their requisite css class changes on and on) , which are toggled with a piston press, this Counting Bloom Filter error occurs.
For now I have added a delaying usleep(500) call between piston press handling, maybe this might work. Disappointing to have such an unstable GUI framework for anything custom built, however.
You can alleviate your disappointment by helping to resolve the issue, either by working on a merge request or at the very least logging it on GitLab. Just complaining about it here does nothing to help anyone.
Thanks for the tips on how to debug. The result of bt full:
**
Gtk:ERROR:../../../gtk/gtkcountingbloomfilterprivate.h:123:gtk_counting_bloom_filter_remove: assertion failed: (self->buckets[bucket] > 0)
Bail out! Gtk:ERROR:../../../gtk/gtkcountingbloomfilterprivate.h:123:gtk_counting_bloom_filter_remove: assertion failed: (self->buckets[bucket] > 0)
Thread 1 "GTKConsole" received signal SIGABRT, Aborted.
__pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
44 ./nptl/pthread_kill.c: No such file or directory.
(gdb) bt full
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
tid = <optimized out>
ret = 0
pd = <optimized out>
old_mask = {__val = {11}}
ret = <optimized out>
#1 0x00007f9728c49d2f in __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2 0x00007f9728bfaef2 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
ret = <optimized out>
#3 0x00007f9728be5472 in __GI_abort () at ./stdlib/abort.c:79
save_stage = 1
act = {__sigaction_handler = {sa_handler = 0x20, sa_sigaction = 0x20}, sa_mask = {__val = {140287192973762, 93892158672512, 162, 93892159466640, 140287192988261, 140720308486144, 0, 140720436526784, 11764671505127832320, 140287193264558, 18446744073709551488, 11, 140287193775520, 140287208077720, 140720436526752, 140287202264256}}, sa_flags = 684031279, sa_restorer = 0x7f97292f1409}
#4 0x00007f972847cebe in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5 0x00007f97284e2b3a in g_assertion_message_expr () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#6 0x00007f97290ef5f5 in () at /lib/x86_64-linux-gnu/libgtk-4.so.1
#7 0x00007f97290ed963 in () at /lib/x86_64-linux-gnu/libgtk-4.so.1
#8 0x00007f97290ed963 in () at /lib/x86_64-linux-gnu/libgtk-4.so.1
#9 0x00007f97290ed963 in () at /lib/x86_64-linux-gnu/libgtk-4.so.1
#10 0x00007f97290ee7b9 in () at /lib/x86_64-linux-gnu/libgtk-4.so.1
#11 0x00007f9728db6450 in g_closure_invoke () at /lib/x86_64-linux-gnu/libgobject-2.0.so.0
#12 0x00007f9728dc94e4 in () at /lib/x86_64-linux-gnu/libgobject-2.0.so.0
#13 0x00007f9728dcfd95 in g_signal_emit_valist () at /lib/x86_64-linux-gnu/libgobject-2.0.so.0
#14 0x00007f9728dcff5f in g_signal_emit () at /lib/x86_64-linux-gnu/libgobject-2.0.so.0
#15 0x00007f9729290705 in () at /lib/x86_64-linux-gnu/libgtk-4.so.1
#16 0x00007f9729291367 in () at /lib/x86_64-linux-gnu/libgtk-4.so.1
#17 0x00007f97284b88fa in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#18 0x00007f97284b7dbf in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#19 0x00007f97284b8198 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#20 0x00007f97284b822c in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#21 0x00007f972976dd0d in g_application_run () at /lib/x86_64-linux-gnu/libgio-2.0.so.0
#22 0x00005564f5fc6b52 in main (argc=1, argv=0x7ffc07a1d778) at test.c:570
app = 0x5564f6407f70
status = 0
The backtrace appears to only show that a pthread was killed, if I am reading it correctly. I only have one additional pthread and it does minimal work → msgrcv() in a loop from another process, and the function that toggles ToggleButtons and adds and removes a CSS class for them.
Thanks, that’s very helpful! Which distro are you using?
I only have one additional pthread and it does minimal work → msgrcv() in a loop from another process, and the function that toggles ToggleButtons and adds and removes a CSS class for them
Is the toggling of buttons / CSS manipulation done from the worker thread? That may cause issues because GTK is meant to be used only from the UI thread. If so, consider using g_idle_add_once to schedule functions on the main thread
I am using Debian Linux bookworm. I just realized that my LD_PRELOAD had the wrong path and didn’t work, so that backtrace is with the native debian gtk4-10 package.
With the successful LD_PRELOAD using those self-compiled packages I have not yet managed to get it to crash while in the gdb interface, so perhaps I can use those packages as a precaution.
static void update_toggles() {
short i;
lstarea = OFFSET_PTR ((data_t *), shared.data, shared.config->lstoffset);
for (i = 0; i < lnum; i++) {
char css_class[21];
sprintf(css_class, "stop_pressed_r%d", lstops[i].grid_y);
if (lstarea[lstops[i].index]) {
if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lstop_btns[i])))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lstop_btns[i]), TRUE);
gtk_widget_add_css_class(lstop_btns[i], (char *) &css_class);
}
else {
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lstop_btns[i])))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lstop_btns[i]), FALSE);
//gtk_widget_remove_css_class(lstop_btns[i], "stop_button_pressed");
gtk_widget_remove_css_class(lstop_btns[i], (char *) &css_class);
}
}
// update rstops
for (i = 0; i < rnum; i++) {
char css_class[21];
sprintf(css_class, "stop_pressed_r%d", rstops[i].grid_y);
if (lstarea[rstops[i].index]) {
if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rstop_btns[i])))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rstop_btns[i]), TRUE);
gtk_widget_add_css_class(rstop_btns[i], (char *) &css_class);
}
else {
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rstop_btns[i])))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rstop_btns[i]), FALSE);
gtk_widget_remove_css_class(rstop_btns[i], (char *) &css_class);
}
}
if (!cleared)
cleared = 1;
}
As suggested I implemented g_idle_add_once in the worker thread in order to schedule update_toggles() to be called in the main thread. So far it seems to work well.