gz-sim icon indicating copy to clipboard operation
gz-sim copied to clipboard

Destruction of GuiRunner's EventManager causes a segfault at exit

Open azeey opened this issue 2 years ago • 1 comments

Environment

  • OS Version: Ubuntu 20.04
  • Source or binary build? main, b2549dd04078a3f31d43215b8a858d05a2de9565

Description

  • Expected behavior: No segfault at exit
  • Actual behavior: A segfault occurs when the GUI terminates due to what appears to be the destruction of GuiRunner's EventManager object. I believe the cause for this is as follows:
    • GuiRunner's EventManager object contains ignition::common::EventT objects created by GUI plugins. Since these are templates, the vtable for the objects is stored in the shared library of the GUI plugin that creates the EventT objects.
    • event::SceneUpdate is emitted in RenderUtil.cc which is part of libignition-gazebo7-rendering.so. And libGzSceneManager.so depends on libignition-gazebo7-rendering.so. Emitting that event creates the EventT object which is stored in GuiRunner's EventManager object, but the vtable is stored in libignition-gazebo7-rendering.so.
    • When the GUI terminates, libGzSceneManager.so is unloaded, which in turn unloades libignition-gazebo7-rendering.so. This invalidates the vtable for the event::SceneUpdate object contained in GuiRunner's EventManager object.
    • When it's time for GuiRunner's EventManager object to be destroyed, the virtual destructor for the event::SceneUpdate object is called, but since the pointer to the destructor points to an address that is no longer accessible, a segfault occurs.

Other notes:

  • This is a similar issue to #1158, but this time it involves EventT.
  • This segfault does not occur in ign-gazebo6. I'm not sure what changed between ign-gazebo6 and main, but the only difference I can tell so far is in main, libGzSceneManager.so is unloaded in when you exit before GuiRunner is destroyed. In ign-gazebo6, it never gets unloaded.

Steps to reproduce

  1. Run ign gazebo empty.sdf
  2. Type ctrl-c on the terminal

Output

Stack trace
#31   Object "/home/addisu/.rbenv/versions/2.5.1/lib/libruby.so.2.5", at 0x7f192f6eec78, in
#30   Object "/home/addisu/.rbenv/versions/2.5.1/lib/ruby/2.5.0/x86_64-linux/fiddle.so", at 0x7f192e01d8b4, in
#29   Object "/home/addisu/.rbenv/versions/2.5.1/lib/libruby.so.2.5", at 0x7f192f6c3ee7, in rb_thread_call_without_gvl
#28   Object "/home/addisu/.rbenv/versions/2.5.1/lib/ruby/2.5.0/x86_64-linux/fiddle.so", at 0x7f192e01da77, in
#27   Object "/usr/lib/x86_64-linux-gnu/libffi.so.6", at 0x7f192ddd171e, in ffi_call
#26   Object "/usr/lib/x86_64-linux-gnu/libffi.so.6", at 0x7f192ddd1dad, in ffi_call_unix64
#25   Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-ign.so.7.0.0~pre1", at 0x7f192d0ff9d0, in runGui
#24   Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd2eb39, in ignition::gazebo::v7::gui::runGui(int&, char**, char const*, char const*)
#23   Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd30677, in std::unique_ptr<ignition::gui::Application, std::default_delete<ignition::gui::Application> >::~unique_ptr()
#22   Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd31403, in std::default_delete<ignition::gui::Application>::operator()(ignition::gui::Application*) const
#21   Object "/home/addisu/ws/garden/install/lib/libignition-gui7.so.7", at 0x7f192ac365cc, in ignition::gui::Application::~Application()
#20   Object "/home/addisu/ws/garden/install/lib/libignition-gui7.so.7", at 0x7f192ac36326, in ignition::gui::Application::~Application()
#19   Object "/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5", at 0x7f192a6c949d, in QApplication::~QApplication()
#18   Object "/usr/lib/x86_64-linux-gnu/libQt5Core.so.5", at 0x7f192af2a97d, in QCoreApplication::~QCoreApplication()
#17   Object "/usr/lib/x86_64-linux-gnu/libQt5Core.so.5", at 0x7f192af5c4be, in QObject::~QObject()
#16   Object "/usr/lib/x86_64-linux-gnu/libQt5Core.so.5", at 0x7f192af51eed, in QObjectPrivate::deleteChildren()
#15   Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd425d9, in ignition::gazebo::v7::GuiRunner::~GuiRunner()
#14   Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd425ad, in ignition::gazebo::v7::GuiRunner::~GuiRunner()
#13   Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd7354f, in std::unique_ptr<ignition::gazebo::v7::GuiRunner::Implementation, void (*)(ignition::gazebo::v7::GuiRunner::Implementation*)>::~unique_ptr()
#12   Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd7a403, in void ignition::utils::detail::DefaultDelete<ignition::gazebo::v7::GuiRunner::Implementation>(ignition::gazebo::v7::GuiRunner::Implementation*)
#11   Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd7a31d, in ignition::gazebo::v7::GuiRunner::Implementation::~Implementation()
#10   Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd732ab, in ignition::gazebo::v7::EventManager::~EventManager()
#9    Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd7326b, in std::unordered_map<std::reference_wrapper<std::type_info const>, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> >, ignition::gazebo::v7::EventManager::Hasher, ignition::gazebo::v7::EventManager::EqualTo, std::allocator<std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > > > >::~unordered_map()
#8    Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd7a2df, in std::_Hashtable<std::reference_wrapper<std::type_info const>, std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > >, std::allocator<std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > > >, std::__detail::_Select1st, ignition::gazebo::v7::EventManager::EqualTo, ignition::gazebo::v7::EventManager::Hasher, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::~_Hashtable()
#7    Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd7fe8b, in std::_Hashtable<std::reference_wrapper<std::type_info const>, std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > >, std::allocator<std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > > >, std::__detail::_Select1st, ignition::gazebo::v7::EventManager::EqualTo, ignition::gazebo::v7::EventManager::Hasher, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::clear()
#6    Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd851ab, in std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > >, true> > >::_M_deallocate_nodes(std::__detail::_Hash_node<std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > >, true>*)
#5    Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd88fbc, in std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > >, true> > >::_M_deallocate_node(std::__detail::_Hash_node<std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > >, true>*)
#4    Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd8c3e8, in void std::allocator_traits<std::allocator<std::__detail::_Hash_node<std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > >, true> > >::destroy<std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > > >(std::allocator<std::__detail::_Hash_node<std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > >, true> >&, std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > >*)
#3    Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd92ef9, in void __gnu_cxx::new_allocator<std::__detail::_Hash_node<std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > >, true> >::destroy<std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > > >(std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > >*)
#2    Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd92ed5, in std::pair<std::reference_wrapper<std::type_info const> const, std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> > >::~pair()
#1    Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd95c5d, in std::unique_ptr<ignition::common::Event, std::default_delete<ignition::common::Event> >::~unique_ptr()
#0    Object "/home/addisu/ws/garden/install/lib/libignition-gazebo7-gui.so.7", at 0x7f192cd9731e, in std::default_delete<ignition::common::Event>::operator()(ignition::common::Event*) const
Segmentation fault (Address not mapped to object [0x7f18eece5cb8])

azeey avatar Apr 12 '22 23:04 azeey

This segfault does not occur in ign-gazebo6. I'm not sure what changed between ign-gazebo6 and main, but the only difference I can tell so far is in main, libGzSceneManager.so is unloaded in when you exit before GuiRunner is destroyed. In ign-gazebo6, it never gets unloaded.

Is there any reason why libGzSceneManager.so is unloaded in main, but not on ign-gazebo6? I guess one patch for this issue is to never unload libGzSceneManager.so in main, but I'm guessing we don't want to do that since that could technically result in memory leaks.

adlarkin avatar Apr 14 '22 18:04 adlarkin

Fixed by https://github.com/gazebosim/gz-gui/pull/469

azeey avatar Sep 26 '22 16:09 azeey