vcl/unx/gtk3/a11y/atkwrapper.cxx | 5 +++++ 1 file changed, 5 insertions(+)
New commits: commit 957aea0cf9d21909a8488c80ebb272bd91fb30cd Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Tue Nov 19 17:27:20 2024 +0100 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Wed Nov 20 11:50:23 2024 +0100 tdf#155449 gtk3 a11y: Hold reference to the original AtkObject Let the AtkObjectWrapper hold a reference to the original AtkObject, and release it in `atk_object_wrapper_finalize`. Without this, the original AtkObject might get destroyed too early. Then trying to access it would result in a crash. While occasionally also seen elsewhere, this was somewhat more reliably reproducible when starting the Orca screen reader or a pyatspi event listener script while the spell check dialog in Writer was shown. Backtrace of how the AtkObject got destroyed (reverse-debugged with rr with a data breakpoint on the AtkObject's accessible description): 1 _int_free_create_chunk malloc.c 4738 0x7fe5766a858e 2 _int_free_merge_chunk malloc.c 4700 0x7fe5766a99b8 3 _int_free malloc.c 4646 0x7fe5766a9d31 4 __GI___libc_free malloc.c 3398 0x7fe5766ac4ff 5 atk_object_finalize atkobject.c 1399 0x7fe5626a7785 6 g_object_unref 0x7fe56e9b94ee 7 expiry_func accessible-leasing.c 122 0x7fe5624f32b1 8 ?? 0x7fe568f0f88e 9 ?? 0x7fe568f0c7df 10 ?? 0x7fe568f0ea17 11 g_main_context_iteration 0x7fe568f0f180 12 GtkSalData::Yield gtkdata.cxx 405 0x7fe5634766ec 13 GtkInstance::DoYield gtkinst.cxx 425 0x7fe56347b493 14 ImplYield svapp.cxx 385 0x7fe56db0e106 15 Application::Yield svapp.cxx 473 0x7fe56db0da9f 16 Application::Execute svapp.cxx 360 0x7fe56db0d880 17 desktop::Desktop::Main app.cxx 1679 0x7fe576926d8b 18 ImplSVMain svmain.cxx 228 0x7fe56db2e996 19 SVMain svmain.cxx 246 0x7fe56db30589 20 soffice_main sofficemain.cxx 121 0x7fe5769a08da 21 sal_main main.c 51 0x5644db935a6d 22 main main.c 49 0x5644db935a47 Backtrace of the crash when using the already deleted object later: 1 g_type_check_instance_cast 0x7fe56e9d9337 2 atk_object_get_index_in_parent atkobject.c 1007 0x7fe5626a5ae5 3 wrapper_get_index_in_parent atkwrapper.cxx 545 0x7fe56344a244 4 atk_object_get_index_in_parent atkobject.c 1011 0x7fe5626a5b3c 5 append_cache_item cache-adaptor.c 183 0x7fe562500591 6 append_accessible_hf cache-adaptor.c 246 0x7fe56250029b 7 g_hash_table_foreach 0x7fe568efacd3 8 spi_cache_foreach accessible-cache.c 423 0x7fe5624f33f9 9 impl_GetItems cache-adaptor.c 328 0x7fe562500174 10 handle_other droute.c 558 0x7fe56250f8a4 11 handle_message droute.c 605 0x7fe56250e7d6 12 ?? 0x7fe5764f5e64 13 dbus_connection_dispatch 0x7fe5764e58ab 14 message_queue_dispatch atspi-gmain.c 89 0x7fe5623abc52 15 ?? 0x7fe568f0c7df 16 ?? 0x7fe568f0ea17 17 g_main_context_iteration 0x7fe568f0f180 18 GtkSalData::Yield gtkdata.cxx 405 0x7fe5634766ec 19 GtkInstance::DoYield gtkinst.cxx 425 0x7fe56347b493 20 ImplYield svapp.cxx 385 0x7fe56db0e106 21 Application::Yield svapp.cxx 473 0x7fe56db0da9f 22 Application::Execute svapp.cxx 360 0x7fe56db0d880 23 desktop::Desktop::Main app.cxx 1679 0x7fe576926d8b 24 ImplSVMain svmain.cxx 228 0x7fe56db2e996 25 SVMain svmain.cxx 246 0x7fe56db30589 26 soffice_main sofficemain.cxx 121 0x7fe5769a08da 27 sal_main main.c 51 0x5644db935a6d 28 main main.c 49 0x5644db935a47 The deleted object is the `AtkObject *accessible` param passed to `atk_object_get_index_in_parent`. This is with at-spi2-core git main as of commit 422cac4bd657ce783164324e6ae4b3d54a8aa761. Change-Id: I23d8a3d55bd587aa99316d71524a18afcd6c0479 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176787 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> (cherry picked from commit 357f040d36c4bdebb59c9ada1a2ee20423ca2155) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176811 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/vcl/unx/gtk3/a11y/atkwrapper.cxx b/vcl/unx/gtk3/a11y/atkwrapper.cxx index b83cf04d48b5..3fe2d388891c 100644 --- a/vcl/unx/gtk3/a11y/atkwrapper.cxx +++ b/vcl/unx/gtk3/a11y/atkwrapper.cxx @@ -667,6 +667,9 @@ atk_object_wrapper_finalize (GObject *obj) atk_object_wrapper_dispose( pWrap ); + if (pWrap->mpOrig) + g_object_unref(pWrap->mpOrig); + parent_class->finalize( obj ); } @@ -962,6 +965,8 @@ atk_object_wrapper_new( const css::uno::Reference< css::accessibility::XAccessib pWrap->mpContext = xContext; pWrap->mpOrig = orig; + if (pWrap->mpOrig) + g_object_ref(pWrap->mpOrig); AtkObject* atk_obj = ATK_OBJECT(pWrap); atk_obj->role = mapToAtkRole(xContext->getAccessibleRole(), xContext->getAccessibleStateSet());