Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Probably harmless GTK assertion failures in gtk_notebook_get_tab_label #22176

Closed
vadz opened this issue Mar 4, 2022 · 2 comments
Closed

Probably harmless GTK assertion failures in gtk_notebook_get_tab_label #22176

vadz opened this issue Mar 4, 2022 · 2 comments

Comments

@vadz
Copy link
Contributor

vadz commented Mar 4, 2022

When destroying wxNotebook we get warnings like this (for each notebook page):

(dataview:432590): Gtk-CRITICAL **: 04:49:28.565: gtk_notebook_get_tab_label: assertion 'list != NULL' failed

This happens in

#0  gtk_notebook_get_tab_label (notebook=notebook@entry=0x555555976270 [GtkNotebook], child=0x555555a38b30 [wxPizza]) at ../../../../gtk/gtknotebook.c:7362
#1  0x00007ffff67b88db in get_label_from_notebook_page (page=page@entry=0x555555cb7680 [GtkNotebookPageAccessible]) at ../../../../gtk/a11y/gtknotebookpageaccessible.c:79
#2  0x00007ffff67b8b14 in gtk_notebook_page_accessible_ref_state_set (accessible=0x555555cb7680 [GtkNotebookPageAccessible]) at ../../../../gtk/a11y/gtknotebookpageaccessible.c:163
#3  0x00007ffff564ac20 in signal_is_needed
    (properties=<synthetic pointer>, minor=0x55555561ec79 "accessible-parent", major=0x7ffff5661936 "PropertyChange", klass=0x7ffff56619b1 "org.a11y.atspi.Event.Object", obj=0x555555cb7680 [GtkNotebookPageAccessible])
    at ../atk-adaptor/event.c:467
#4  emit_event
    (obj=obj@entry=0x555555cb7680 [GtkNotebookPageAccessible], klass=klass@entry=0x7ffff56619b1 "org.a11y.atspi.Event.Object", major=major@entry=0x7ffff5661936 "PropertyChange", minor=minor@entry=0x55555561ec79 "accessible-parent", detail1=<optimized out>, detail1@entry=0, detail2=<optimized out>, detail2@entry=0, type=0x7ffff5660d5a "(so)", val=0x55555561d9e0, append_variant=0x7ffff5649ab0 <append_object>) at ../atk-adaptor/event.c:545
#5  0x00007ffff564bea1 in property_event_listener (signal_hint=signal_hint@entry=0x7fffffffcbe0, n_param_values=<optimized out>, param_values=param_values@entry=0x7fffffffcc60, data=<optimized out>) at ../atk-adaptor/event.c:719
#8  0x00007ffff62344ff in <emit signal property-change:accessible-parent on instance 0x555555cb7680 [GtkNotebookPageAccessible]> (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>)
    at ../../../gobject/gsignal.c:3553
    #6  0x00007ffff622d8cf in signal_emit_unlocked_R
    (node=node@entry=0x555555699be0, detail=detail@entry=614, instance=instance@entry=0x555555cb7680, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffcc60)
    at ../../../gobject/gsignal.c:3708
    #7  0x00007ffff6233f51 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffce00) at ../../../gobject/gsignal.c:3497
#9  0x00007ffff567d443 in  () at /usr/lib/x86_64-linux-gnu/libatk-1.0.so.0
#13 0x00007ffff62344ff in <emit signal notify:accessible-parent on instance 0x555555cb7680 [GtkNotebookPageAccessible]> (instance=instance@entry=0x555555cb7680, signal_id=<optimized out>, detail=<optimized out>)
    at ../../../gobject/gsignal.c:3553
    #10 0x00007ffff621b6df in g_closure_invoke
    (closure=closure@entry=0x55555560f280, return_value=return_value@entry=0x0, n_param_values=2, param_values=param_values@entry=0x7fffffffd0e0, invocation_hint=invocation_hint@entry=0x7fffffffd060) at ../../../gobject/gclosure.c:830
    #11 0x00007ffff622d795 in signal_emit_unlocked_R
    (node=node@entry=0x5555555e44d0, detail=detail@entry=614, instance=instance@entry=0x555555cb7680, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffd0e0)
    at ../../../gobject/gsignal.c:3672
    #12 0x00007ffff6233f51 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffd280) at ../../../gobject/gsignal.c:3497
#14 0x00007ffff621fed4 in g_object_dispatch_properties_changed (object=0x555555cb7680 [GtkNotebookPageAccessible], n_pspecs=<optimized out>, pspecs=<optimized out>) at ../../../gobject/gobject.c:1212
#15 0x00007ffff6221d1a in g_object_notify_by_spec_internal (pspec=<optimized out>, object=0x555555cb7680 [GtkNotebookPageAccessible]) at ../../../gobject/gobject.c:1305
#16 g_object_notify (object=0x555555cb7680 [GtkNotebookPageAccessible], property_name=<optimized out>) at ../../../gobject/gobject.c:1353
#17 0x00007ffff67b8ec3 in gtk_notebook_page_accessible_invalidate (page=page@entry=0x555555cb7680 [GtkNotebookPageAccessible]) at ../../../../gtk/a11y/gtknotebookpageaccessible.c:280
#18 0x00007ffff67b8491 in page_removed_cb (notebook=<optimized out>, widget=widget@entry=0x555555a38b30 [wxPizza], page_num=6, data=<optimized out>) at ../../../../gtk/a11y/gtknotebookaccessible.c:86
#19 0x00007ffff6b0b1c5 in _gtk_marshal_VOID__OBJECT_FLAGSv
    (closure=0x555555cb1c70, return_value=<optimized out>, instance=0x555555976270, args=<optimized out>, marshal_data=<optimized out>, n_params=<optimized out>, param_types=0x5555556956a0) at ./debian/build/deb/gtk/gtkmarshalers.c:5620
#20 0x00007ffff621b909 in _g_closure_invoke_va (closure=closure@entry=0x555555cb1c70, return_value=return_value@entry=0x0, instance=instance@entry=0x555555976270, args=args@entry=0x7fffffffd640, n_params=2, param_types=0x5555556956a0)
    at ../../../gobject/gclosure.c:893
#21 0x00007ffff62342d9 in g_signal_emit_valist (instance=0x555555976270, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffd640) at ../../../gobject/gsignal.c:3406
#22 0x00007ffff62344ff in g_signal_emit (instance=instance@entry=0x555555976270, signal_id=<optimized out>, detail=detail@entry=0) at ../../../gobject/gsignal.c:3553
#23 0x00007ffff698cb18 in gtk_notebook_remove (container=0x555555976270 [GtkNotebook], widget=0x555555a38b30 [wxPizza]) at ../../../../gtk/gtknotebook.c:4268
#24 0x00007ffff621ea21 in g_cclosure_marshal_VOID__OBJECTv
    (closure=0x55555568ae70, return_value=<optimized out>, instance=0x555555976270, args=<optimized out>, marshal_data=<optimized out>, n_params=<optimized out>, param_types=0x555555694c80) at ../../../gobject/gmarshal.c:1910
#25 0x00007ffff621b909 in _g_closure_invoke_va (closure=closure@entry=0x55555568ae70, return_value=return_value@entry=0x0, instance=instance@entry=0x555555976270, args=args@entry=0x7fffffffd9c0, n_params=1, param_types=0x555555694c80)
    at ../../../gobject/gclosure.c:893
#26 0x00007ffff62342d9 in g_signal_emit_valist (instance=0x555555976270, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffd9c0) at ../../../gobject/gsignal.c:3406
#27 0x00007ffff62344ff in g_signal_emit (instance=instance@entry=0x555555976270, signal_id=<optimized out>, detail=detail@entry=0) at ../../../gobject/gsignal.c:3553
#28 0x00007ffff688c865 in gtk_container_remove (container=0x555555976270 [GtkNotebook], widget=0x555555a38b30 [wxPizza]) at ../../../../gtk/gtkcontainer.c:1907
#29 0x00007ffff7acaa22 in wxNotebook::DoRemovePage(unsigned long) (this=0x555555943c80, page=6) at src/gtk/notebook.cpp:431
#30 0x00007ffff7b265c2 in wxBookCtrlBase::DeletePage(unsigned long) (this=0x555555943c80, nPage=6) at src/common/bookctrl.cpp:381
#31 0x00007ffff7aca989 in wxNotebook::DeleteAllPages() (this=0x555555943c80) at src/gtk/notebook.cpp:413
#32 0x00007ffff7ac9639 in wxNotebook::~wxNotebook() (this=0x555555943c80, __in_chrg=<optimized out>) at src/gtk/notebook.cpp:162
...

and probably just because the page actually isn't there any longer, so it's probably harmless, but the warnings are still annoying and I don't think we were getting them before, but not sure about what could have changed.

@vadz
Copy link
Contributor Author

vadz commented May 9, 2022

This is still very annoying, but I just don't seem to be able to do anything about this, the assertion fails inside a function called from page_removed_cb() in gtk/a11y/gtknotebookaccessible.c and we have no controls about what happens there. Disabling this callback, by defining our own page-removed handler and using g_signal_stop_emission_by_name() in it doesn't work neither as this skips updating the internal ATK state on page removal and results in worse problems later on. The really aggravating thing is that the code works perfectly fine, it already handles the case of "missing" child (of course it's missing because the page has just got removed!) correctly. Oh, and to add insult to injury, the entire ATK got removed in GTK 4 anyhow.

FWIW here is the simplest possible GTK program, based on their own hello world, sufficient to reproduce the problem: just closing the window results in

(a.out:1501458): Gtk-CRITICAL **: 17:47:59.775: gtk_notebook_get_tab_label: assertion 'list != NULL' failed

(only once because there is only one page, there is one of those per page).

#include <gtk/gtk.h>

static void
activate (GtkApplication* app,
          gpointer        user_data)
{
  GtkWidget *window;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Window");
  gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);

  GtkWidget* notebook = gtk_notebook_new();
  GtkWidget* button = gtk_button_new_with_label("First");

  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), button, NULL);
  gtk_container_add (GTK_CONTAINER (window), notebook);

  gtk_widget_show_all (window);
}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

@vadz
Copy link
Contributor Author

vadz commented May 10, 2022

OK, so I think the only way to do something about this is to ignore this specific GTK error while the pages are being removed. It looks like it's not that difficult to do, we can just set our own log writer function for the required scope and "handle" (i.e. filter) the messages of this form.

This could also be used for other unwanted GTK logs, of course, without suppressing all of them as wxApp::GTKSuppressDiagnostics() does, because some of them indicate real problems. So it seems to be worth doing.

vadz added a commit to vadz/wxWidgets that referenced this issue May 11, 2022
These messages are due to an assertion failure deep inside ATK which
doesn't indicate any real problem (as failure to get the label of an
already destroyed tab is normal and is already handled correctly in the
GTK code) and can't be avoided, so suppress them to avoid showing them
to the users who can't do anything at all about them anyhow, but can be
scared by the "CRITICAL" GTK messages.

Closes wxWidgets#22176.
@vadz vadz closed this as completed in 8f49ecc May 17, 2022
vadz added a commit to vadz/wxWidgets that referenced this issue Aug 29, 2022
Make GTK notebook log suppression opt-in to avoid a fatal error when the
application calls g_log_set_writer_func() itself, as doing it more than
once immediately kills the application with glib 2.73 and there is no
way to check if it had been already done or not (you have to admire the
purity of the API design here).

This is unfortunate as 99% of the wxWidgets applications that do _not_
call g_log_set_writer_func() would now show the spurious diagnostics by
default again, but preferable to making the remaining 1% crash, and
there doesn't seem to be any other solution.

Call the new GTKAllowDiagnosticsControl() function in the notebook
sample to at least still avoid getting the spurious diagnostic messages
described in wxWidgets#22176 there.

See wxWidgets#22717,.
vadz added a commit to vadz/wxWidgets that referenced this issue Aug 30, 2022
Make GTK notebook log suppression opt-in to avoid a fatal error when the
application calls g_log_set_writer_func() itself, as doing it more than
once immediately kills the application with glib 2.73 and there is no
way to check if it had been already done or not (you have to admire the
purity of the API design here).

This is unfortunate as 99% of the wxWidgets applications that do _not_
call g_log_set_writer_func() would now show the spurious diagnostics by
default again, but preferable to making the remaining 1% crash, and
there doesn't seem to be any other solution.

Call the new GTKAllowDiagnosticsControl() function in the notebook
sample to at least still avoid getting the spurious diagnostic messages
described in wxWidgets#22176 there.

See wxWidgets#22717,.
vadz added a commit to vadz/wxWidgets that referenced this issue Aug 30, 2022
Make GTK notebook log suppression opt-in to avoid a fatal error when the
application calls g_log_set_writer_func() itself, as doing it more than
once immediately kills the application with glib 2.73 and there is no
way to check if it had been already done or not (you have to admire the
purity of the API design here).

This is unfortunate as 99% of the wxWidgets applications that do _not_
call g_log_set_writer_func() would now show the spurious diagnostics by
default again, but preferable to making the remaining 1% crash, and
there doesn't seem to be any other solution.

Call the new GTKAllowDiagnosticsControl() function in the notebook
sample to at least still avoid getting the spurious diagnostic messages
described in wxWidgets#22176 there.

See wxWidgets#22717.

(cherry picked from commit 8af645e)
vadz added a commit to vadz/wxWidgets that referenced this issue Aug 30, 2022
Make GTK notebook log suppression opt-in to avoid a fatal error when the
application calls g_log_set_writer_func() itself, as doing it more than
once immediately kills the application with glib 2.73 and there is no
way to check if it had been already done or not (you have to admire the
purity of the API design here).

This is unfortunate as 99% of the wxWidgets applications that do _not_
call g_log_set_writer_func() would now show the spurious diagnostics by
default again, but preferable to making the remaining 1% crash, and
there doesn't seem to be any other solution.

Call the new GTKAllowDiagnosticsControl() function in the notebook
sample to at least still avoid getting the spurious diagnostic messages
described in wxWidgets#22176 there.

See wxWidgets#22717.

(cherry picked from commit 8af645e and
adapted to 3.2 stable ABI).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant